lazy_static::lazy_static! {
static ref file_data: String = fs::read_to_string("static/login.html").expect("unable to read from static/login.html");
}
#[tokio::main]
async fn main() {
// code omitted
let login = warp::path("login").map(move || warp::reply::html(file_data));
// code omitted
}
Compile error:
error[E0277]: the trait bound `hyper::body::body::Body: std::convert::From<file_data>` is not satisfied
--> src/main.rs:45:49
|
45 | let login = warp::path("login").map(move || warp::reply::html(file_data));
| ^^^^^^^^^^^^^^^^^ the trait `std::convert::From<file_data>` is not implemented for `hyper::body::body::Body`
|
::: /home/ichi/.cargo/registry/src/github.com-1ecc6299db9ec823/warp-0.2.3/src/reply.rs:170:11
|
170 | Body: From<T>,
| ------- required by this bound in `warp::reply::html`
|
= help: the following implementations were found:
<hyper::body::body::Body as std::convert::From<&'static [u8]>>
<hyper::body::body::Body as std::convert::From<&'static str>>
<hyper::body::body::Body as std::convert::From<bytes::bytes::Bytes>>
<hyper::body::body::Body as std::convert::From<std::borrow::Cow<'static, [u8]>>>
and 4 others
I am trying to pass a String to a closure. According to the documentation, From<String> is implemented for hyper::body::Body and file_data is of type String. So why am I getting this error?
From lazy_static
For a given static ref NAME: TYPE = EXPR;, the macro generates a unique type that implements Deref<TYPE> and stores it in a static with name NAME. (Attributes end up attaching to this type.)
That is, the type of the variable is not TYPE!
This is why you see the error
the trait `std::convert::From<file_data>` is not implemented for `hyper::body::body::Body`
^^^^^^^^^
You'd probably have better luck explicitly de-referencing or cloning the global variable: warp::reply::html(&*file_data) or warp::reply::html(file_data.clone()).
The issue here is that lazy_static creates a wrapper type that references your data, and hyper doesn't know how to handle it. You could use file_data.clone() to clone the referenced data and construct a body from that, but in this case there's actually a simpler method. Since your string has a fixed value and Body implements From<&'static str>, you don't actually need a heap-allocated String or lazy_static at all: You can use the following code which just uses a constant string slice that can be used directly.
const FILE_DATA: &str = "test";
#[tokio::main]
async fn main() {
// code omitted
let login = warp::path("login").map(move || warp::reply::html(FILE_DATA));
// code omitted
}
Related
so i have got two files main.rs and utils.rs
I implemented StringUtils method on utils.rs but when I try to use the method in main.rs
it gives me this error
error[E0599]: no method named `slice` found for reference `&str` in the current scope
--> src\main.rs:89:50
|
89 | let text: String = self.inner.clone().as_str().slice(self.start, self.current);
| ^^^^^ method not found in `&str`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `StringUtils` defines an item `slice`, perhaps you need to implement it
--> src\util.rs:25:1
|
25 | trait StringUtils {
| ^^^^^^^^^^^^^^^^^
// main.rs
mod utils;
use utils::*;
...
fn add_token0(&mut self, token_type: TokenType) {
let text: String = self.inner.clone().as_str().slice(self.start, self.current);
// error: no method named `slice` found for reference `&str` in the current scope
}
...
but I implemented it already on utils.rs
// utils.rs
...
trait StringUtils {
...
fn slice(&self, range: impl RangeBounds<usize>) -> &str;
...
}
impl StringUtils for str {
...
fn slice(&self, range: impl RangeBounds<usize>) -> &str {
...
}
...
}
...
why doesn't my implementation work, and is there any way to solve it or I can only implement StringUtils on main.rs?
A substantively equivalent example appears in the section Paths for Referring to an Item in the Module Tree in The Rust Programming Language (which if you haven't read, I would suggest).
The short version is that any item (e.g., trait, function definition) within a module that you would like to be visible to other modules should have some variant of a pub visibility modifier. In your instant example, this manifests as needing to make the StringUtils trait pub (or some other variant exposing it to the containing module).
In fact, if you attempt to import StringUtils directly, via use utils::StringUtils instead of a glob import, you'd get the following error message:
error[E0603]: trait `StringUtils` is private
--> src/lib.rs:7:12
|
7 | use utils::StringUtils;
| ^^^^^^^^^^^ private trait
|
note: the trait `StringUtils` is defined here
--> src/lib.rs:19:5
|
19 | trait StringUtils {
| ^^^^^^^^^^^^^^^^^
Which would link to this explanation of one way to fix it. So if we do pub trait StringUtils { ... } instead, there are no issues relating to using the trait.
You would still have the issue #trentcl mentions concerning the incorrect number of parameters to slice, and I presume self.start..self.current (or the inclusive version) should be the range passed instead.
Finally, there is an error relating to your type annotation of text as StringUtils::slice would return &str, not String. Depending on what you want, you should either change the trait and its implementations or take a look at ways to go between &str and String and the differences between them.
(playground).
You may want to have a more restrictive visibility modifier, like pub(crate) or pub(super) which restrict visibility to the containing crate or the containing module, respectively.
A more exhaustive explanation of this can be found in the relevant section in The Rust Reference.
This question already has an answer here:
Can I have a static borrowed reference to a trait object?
(1 answer)
Closed 3 years ago.
I want to be able to iterate over an array of parsers trying to find a delegate parser from a main parsing function. The list of parsers is known at compile-time, so I want this to be a constant.
I've tried some varieties of this but I can't get it to work:
const ALL_PARSERS: [&Parser; 1] = [&CommentParser {}];
How can I achieve this?
Notes:
Parser is a trait.
CommentParser is a struct implementing Parser.
there are other implementations of Parser but they are not shown for simplicity.
even though all parser implementations are known at compile-time, I just want to avoid explicitly trying one by one as that would make the code worse than I think it should be.
The error I get currently:
|
11 | const ALL_PARSERS: [&Parser; 1] = [&CommentParser {}];
| ^^^^^^^^^^^^ the trait `parsers::Parser` cannot be made into an object
|
= note: method `parse` has generic type parameters
I can't see any generics in the parse method:
pub trait Parser {
fn opening_char(self: &Self) -> char;
fn parse(&mut self, env: impl ParserEnv) -> ParseResult;
}
If I make the types values:
const ALL_PARSERS: [Parser; 1] = [CommentParser {}];
The error becomes:
11 | const ALL_PARSERS: [Parser; 1] = [CommentParser {}];
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `(dyn parsers::Parser + 'static)`
Trait references need to be marked as &dyn, e.g. &dyn Parser:
trait Parser { }
struct CommentParser { }
impl Parser for CommentParser { }
const ALL_PARSERS: [&dyn Parser; 1] = [&CommentParser {}];
fn main() {
for &parser in &ALL_PARSERS {
// do something with parser
}
}
Link to playground example
Also, as this answer to a related question states, you can't have a generic parameter in your trait if you want to make a trait reference, so you'll need to either add a generic type to the trait itself, or use a trait reference instead of impl in your parser type:
// original (with error)
trait Parser {
// impl ParserEnv is an implicit generic type
fn parse(&mut self, env: impl ParserEnv) -> ParseResult;
// same as:
// fn parser<E: ParserEnv>(&mut self, env: E) -> ParserResult;
}
// alternative 1, with trait generic type
trait Parser<E: ParserEnv> {
fn parse(&mut self, env: E) -> ParseResult;
}
// alternative 2, with trait reference
trait Parser {
fn parser(&mut self, env: &dyn ParserEnv) -> ParserResult;
// may need &dyn mut ParserEnv if you want to modify env as well
}
I think the second approach may be the best, since then you can store the parsers in the array without needing to assign a particular ParserEnv type to the parsers.
How would I decode the standard Substrate extrinsic format into a Transaction object in a way where it would be possible to get the Sender, preferably as a string?
I have started with this code with a hardcoded sample extrinsic data for testing in the extrinsic_hex variable:
use hex::decode;
use hex_literal::hex;
use parity_codec::{Decode, Encode, Input};
use primitives::generic::UncheckedMortalExtrinsic;
use std::fmt;
use std::fmt::Debug;
fn main() {
let extrinsic_hex: &'static str = "81ffd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d3c6b8941e2976034e67bdd1a999c3eff4403c8ceaf717f18d9760ab18573ab2ce870e9b751c2f14dd9883e54746e1eb6639978ceab49968c25176cc0d2507205040003000ca10f";
let result = hex::decode(extrinsic_hex);
match result {
Ok(v1) => {
let extr_option = UncheckedMortalExtrinsic::decode(&mut v1);
()
}
_ => {
println!("Error decoding");
()
}
}
}
The error I get is:
error: duplicate lang item in crate `sr_io`: `panic_impl`.
|
= note: first defined in crate `std`.
error: duplicate lang item in crate `sr_io`: `oom`.
|
= note: first defined in crate `std`.
error[E0277]: the trait bound `std::vec::Vec<u8>: parity_codec::codec::Input` is not satisfied
--> core/decaddr/src/main.rs:13:20
|
13 | let extr_option=UncheckedMortalExtrinsic::decode(&mut v1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `parity_codec::codec::Input` is not implemented for `std::vec::Vec<u8>`
|
= note: required by `parity_codec::codec::Decode::decode`
Let's pretend that the error error: duplicate lang item in cratesr_io:panic_impl. doesn't exist for now.
If I am understanding correctly, it doesn't work because Vec doesn't implement the parity_codec::Input trait, am I right? If so, how would one add this trait to Vec? Or better said, what are the functions from the Substrate framework I am missing so the Input trait is automatically provided?
If so, how would one add this trait to Vec ?
In your code, you can't. For coherence reasons, Rust says that an implementation of a trait X for a type Y must exist in the crate for X or the crate for Y.
Or better said, what are the functions from Susbtrate framework I am missing so the Input trait is automatically provided?
If you look at the "Implementors" part of the Input trait documentation - you can see that every type that implements std::io::Read will implement Input.
As the comments say, the implementation that is useful for you is the one on &[u8], which exists because it implements std::io::Read.
This question already has answers here:
How can I swap in a new value for a field in a mutable reference to a structure?
(2 answers)
How do I move out of a struct field that is an Option?
(1 answer)
Closed 4 years ago.
I'm experimenting with Rust's Arc<Mutex>, trying to use it with a struct that is not in the default examples, but rather a custom one that is lazily initialized:
use std::sync::{Arc, Mutex};
#[macro_use]
extern crate lazy_static; // lazy_static = "1.2.0"
pub struct FooBar {}
lazy_static! {
static ref FOO_BAR: Arc<Mutex<Option<FooBar>>> = Arc::new(Mutex::new(None));
}
pub fn unpack_foo_bar() {
let foo_bar_arc = Arc::clone(&FOO_BAR);
let foo_bar_mutex_result = foo_bar_arc.lock();
let foo_bar_mutex = foo_bar_mutex_result.unwrap();
let foo_bar = foo_bar_mutex.unwrap();
// do something
}
The static FOO_BAR variable is later initialized by replacing the content of the option.
The code above won't compile:
error[E0507]: cannot move out of borrowed content
--> src/lib.rs:15:19
|
15 | let foo_bar = foo_bar_mutex.unwrap();
| ^^^^^^^^^^^^^ cannot move out of borrowed content
It would if FooBar were replaced with e. g. u32. The code also doesn't compile with String, but that type has built-in methods for cloning, which my type may not necessarily have.
Short of using foo_bar_mutex.as_ref().unwrap(), what other options do I have, particularly if I'd like to abstract the extraction of the FooBar instance into a method, like this:
pub fn unpack_foo_bar() -> Option<FooBar> {
let foo_bar_arc = Arc::clone(&FOO_BAR);
let foo_bar_mutex_result = foo_bar_arc.lock();
let foo_bar_mutex = foo_bar_mutex_result.unwrap();
let foo_bar_option = *foo_bar_mutex;
foo_bar_option
}
In this case, the compiler throws almost the same error, which is
error[E0507]: cannot move out of borrowed content
--> src/main.rs:34:26
|
11 | let foo_bar_option = *foo_bar_mutex;
| ^^^^^^^^^^^^^^
| |
| cannot move out of borrowed content
| help: consider using a reference instead: `&*foo_bar_mutex`
I have a sense that this would be much simpler if FooBar were easily cloned, but in the real world scenario I'm basing this example on FooBar has a field that is an instance of a third party library object that does not derive the Clone trait.
Using Option::take would only make the contained variable usable once. I'm not trying to take ownership of the FooBar instance. I don't care if it's owned as long as I can call its methods. Returning a reference would be great, but when doing this, the compiler complains:
pub fn unpack_foo_bar() -> &Option<FooBar> {
let foo_bar_arc = Arc::clone(&FOO_BAR);
let foo_bar_mutex_result = foo_bar_arc.lock();
let foo_bar_mutex = foo_bar_mutex_result.unwrap();
let foo_bar_option = foo_bar_mutex.as_ref();
foo_bar_option
}
Compiler's response:
error[E0106]: missing lifetime specifier
--> src/main.rs:30:28
|
7 | pub fn unpack_foo_bar() -> &Option<FooBar> {
| ^ help: consider giving it a 'static lifetime: `&'static`
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
Experimenting with &*foo_bar_mutex and adding 'static to the return type each opens up subsequent cans of compiler errors.
I have also tried experimenting with to_owned() on the FooBar reference and stumbled upon the owning_ref crate, but alas, haven't figured out how to make returning a reference work.
Final Update
Given that it appears impossible to pass on the reference to the Option<FooBar> to an external function caller, I decided to avoid this problem altogether by allowing passing in the methods relying on the FooBar instance as a closure:
pub fn unpack_foo_bar(use_foo_bar: fn(&FooBar)) {
let foo_bar_arc = Arc::clone(&FOO_BAR);
let foo_bar_mutex_result = foo_bar_arc.lock();
let foo_bar_mutex = foo_bar_mutex_result.unwrap();
let foo_bar_reference = foo_bar_mutex.as_ref().unwrap();
// pass in the closure that needs the foo bar instance
use_foo_bar(foo_bar_reference);
}
With the following code (an attempt to make an HTTP request using the reqwest crate), the compiler says that my value SID_URI does not implement the trait PolyfillTryInto. What's going on here? reqwest::Url clearly implements the private trait reqwest::into_url::PolyfillTryInto.
#[macro_use]
extern crate lazy_static;
extern crate reqwest;
static R_EMAIL: &str = "example#example.com";
static R_PASS: &str = "password";
static API_PUBKEY: &str = "99754106633f94d350db34d548d6091a";
static API_URI: &str = "https://example.com";
static AUTH_PATH: &str = "/api/v1";
lazy_static! {
static ref SID_URI: reqwest::Url = reqwest::Url::parse(&(API_URI.to_owned() + AUTH_PATH)).unwrap();
}
fn get_sid() -> Result<reqwest::Response, reqwest::Error> {
let client = reqwest::Client::new();
let params = [("ID", R_EMAIL), ("PW", R_PASS), ("KY", API_PUBKEY)];
let q = client.post(SID_URI).form(¶ms).send()?;
Ok(q)
}
fn main() {
assert!(get_sid().is_ok());
}
error[E0277]: the trait bound `SID_URI: reqwest::into_url::PolyfillTryInto` is not satisfied
--> src/main.rs:19:20
|
19 | let q = client.post(SID_URI).form(¶ms).send()?;
| ^^^^ the trait `reqwest::into_url::PolyfillTryInto` is not implemented for `SID_URI`
|
= note: required because of the requirements on the impl of `reqwest::IntoUrl` for `SID_URI`
The compiler isn't lying to you, you are just skipping over a relevant detail of the error message. Here's a self-contained example:
#[macro_use]
extern crate lazy_static;
struct Example;
trait ExampleTrait {}
impl ExampleTrait for Example {}
lazy_static! {
static ref EXAMPLE: Example = Example;
}
fn must_have_trait<T>(_: T)
where
T: ExampleTrait,
{
}
fn main() {
must_have_trait(EXAMPLE);
must_have_trait(42i32);
}
error[E0277]: the trait bound `EXAMPLE: ExampleTrait` is not satisfied
--> src/main.rs:19:5
|
19 | must_have_trait(EXAMPLE);
| ^^^^^^^^^^^^^^^ the trait `ExampleTrait` is not implemented for `EXAMPLE`
|
= note: required by `must_have_trait`
error[E0277]: the trait bound `i32: ExampleTrait` is not satisfied
--> src/main.rs:20:9
|
20 | must_have_trait(42i32);
| ^^^^^^^^^^^^^^^ the trait `ExampleTrait` is not implemented for `i32`
|
= note: required by `must_have_trait`
Compare the two error messages:
the trait bound `EXAMPLE: ExampleTrait` is not satisfied
the trait bound `i32: ExampleTrait` is not satisfied
The second error message doesn't say that 42 does not implement ExampleTrait, it says that i32 lacks the implementation. This error message shows the type that fails, not the name of the value! That means that EXAMPLE in the same context is referring to a type.
Lazy-static works by creating one-off types that wrap your value and provide thread-safe single initialization guarantees:
For a given static ref NAME: TYPE = EXPR;, the macro generates a unique type that implements Deref<TYPE> and stores it in a static with name NAME.
This wrapper type does not implement your trait, only the wrapped type does. You will need to invoke Deref and then probably re-reference it to get to a &Url, assuming that a reference to a Url implements your trait:
must_have_trait(&*EXAMPLE);
Additionally, using the bare static variable would attempt to move it out of the static location (which would be a Very Bad Thing), so you always need to use it by reference.