I'm trying to implement the trait diesel::Insertable<table in Rust.
In mail.rs
diesel::insert_into(mailing_list).values(
email // This is a String
).execute(connection);
This is because the following code results in this error:
error[E0277]: the trait bound `std::string::String: diesel::Insertable<table>` is not satisfied
--> src/mail.rs:18:10
|
17 | diesel::insert_into(mailing_list).values(
| ------ required by a bound introduced by this call
18 | email
| ^^^^^ the trait `diesel::Insertable<table>` is not implemented for `std::string::String`
Looking a bit more at the documentation from Diesel, I believe that I should make myself a struct that derives Insertable
In models.rs
#[derive(Insertable)]
pub struct NewSubscriber {
pub email: String
}
But then I get
but im getting this error
error[E0433]: failed to resolve: use of undeclared crate or module `new_subscribers`
--> src/models.rs:13:12
|
13 | pub struct NewSubscriber {
| ^^^^^^^^^^^^^ use of undeclared crate or module `new_subscribers`
I'm so confused why the compiler says it can't find a crate or module with a struct that I'm trying to define.
From the documentation on the Insertable derive macro:
To implement Insertable this derive needs to know the corresponding table type. By default it uses the snake_case type name with an added s from the current scope. It is possible to change this default by using #[diesel(table_name = something)].
So you need to define a "new_subscribers" table using table!. If you've already done so make sure you import it into scope, or if you already have a table and its in scope but with a different name, add the above attribute.
Judging by your insert statement, it looks like the table you're inserting into is mailing_list so use the last option:
#[derive(Insertable)]
#[diesel(table_name = mailing_list)]
pub struct NewSubscriber {
pub email: String
}
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.
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.
I'm trying to serialize the following Result object, however I'm getting an error because while it workings for some of the properties, it doesn't seem to work on path, even though all of the elements involved have implementations provided by Serde.
#[macro_use]
extern crate serde;
extern crate rocket;
use rocket_contrib::json::Json;
use std::rc::Rc;
#[derive(Serialize)]
struct Result {
success: bool,
path: Vec<Rc<GraphNode>>,
visited_count: u32,
}
struct GraphNode {
value: u32,
parent: Option<Rc<GraphNode>>,
}
fn main(){}
fn index() -> Json<Result> {
Json(Result {
success: true,
path: vec![],
visited_count: 1,
})
}
Playground, although I can't get it to pull in the Rocket crate, it must not be one of the 100 most popular.
error[E0277]: the trait bound `std::rc::Rc<GraphNode>: serde::Serialize` is not satisfied
--> src/main.rs:11:5
|
11 | path: Vec<Rc<GraphNode>>,
| ^^^^ the trait `serde::Serialize` is not implemented for `std::rc::Rc<GraphNode>`
|
= note: required because of the requirements on the impl of `serde::Serialize` for `std::vec::Vec<std::rc::Rc<GraphNode>>`
= note: required by `serde::ser::SerializeStruct::serialize_field`
From my understanding, #[derive(Serialize)] should automatically create a serialize method which serde can then use. However I would expect it to work for the properties too. Do I need to create structs for all the types and then derive Serialize for all of those structs?
Do I need to do something to enable it?
The following crates are in use:
rocket = "*"
serde = { version = "1.0", features = ["derive"] }
rocket_contrib = "*"
the trait bound `std::rc::Rc<GraphNode>: serde::Serialize` is not satisfied
This means that Rc does not implement Serialize. See How do I serialize or deserialize an Arc<T> in Serde?. TL;DR:
serde = { version = "1.0", features = ["derive", "rc"] }
Once adding that, the error message changes to:
error[E0277]: the trait bound `GraphNode: serde::Serialize` is not satisfied
--> src/main.rs:11:5
|
11 | path: Vec<Rc<GraphNode>>,
| ^^^^ the trait `serde::Serialize` is not implemented for `GraphNode`
|
= note: required because of the requirements on the impl of `serde::Serialize` for `std::rc::Rc<GraphNode>`
= note: required because of the requirements on the impl of `serde::Serialize` for `std::vec::Vec<std::rc::Rc<GraphNode>>`
= note: required by `serde::ser::SerializeStruct::serialize_field`
That's because every type that needs to be serialized must implement Serialize:
#[derive(Serialize)]
struct GraphNode {
I am curious to see how much boilerplate one can save through built-in reflection.
A little background
My idea behind structured logging is to use various small tailored types to separate content from representation. Instead of unstructured logger.info("Found a bar with {} foos", bar.foo) one uses something like logger.info(FoundBar{ _bar: bar })
My Rust-ish approach
define a Log trait
provide a default implementation that calls the Serde machinery to serialize the type (to JSON in this example)
define loggable types easily by letting them "inherit" the default implementation
profit
Define the trait, providing a default impl:
trait Log {
fn to_log(&self) -> String {
serde_json::to_string(&self).unwrap()
}
}
(RLS is already drawing angry red squiggles, but bear with me)
Define a simple type to be logged:
#[derive(Serialize)]
struct Message {
msg: String,
}
and let it use the default implementation:
impl Log for Message {}
and finally the polymorphic logging function defined in terms of the trait:
fn log(log: &Log) {
println!("serialized = {}", log.to_log());
}
The compiler complains:
error[E0277]: the trait bound `Self: _IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` is not satisfied
--> src\main.rs:8:9
|
8 | serde_json::to_string(&self).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^ the trait `_IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` is not implemented for `Self`
|
= help: consider adding a `where Self: _IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` bound
= note: required because of the requirements on the impl of `_IMPL_DESERIALIZE_FOR_Message::_serde::Serialize` for `&Self`
= note: required by `serde_json::ser::to_string`
Adding the where Self suggestion to my trait function only produces different errors (error[E0433]: failed to resolve. Use of undeclared type or module _IMPL_DESERIALIZE_FOR_Message), but apart from that it seems like a Bad Idea(TM) to have this implementation detail of Serde leak into my code.
How do I portably constrain my trait (using where?) to only apply to types that have the correct derive? Even better, can I "inject" the derive functionality into types using the trait?
If you create a MCVE of your problem on the playground, you get a more accurate error:
error[E0277]: the trait bound `Self: serde::Serialize` is not satisfied
--> src/lib.rs:6:9
|
6 | serde_json::to_string(&self).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^ the trait `serde::Serialize` is not implemented for `Self`
|
= help: consider adding a `where Self: serde::Serialize` bound
= note: required because of the requirements on the impl of `serde::Serialize` for `&Self`
= note: required by `serde_json::ser::to_string`
Following the suggestion, but using the idiomatic supertrait syntax, answers your question:
trait Log: serde::Serialize {
fn to_log(&self) -> String {
serde_json::to_string(&self).unwrap()
}
}
You'll need to change your log function for object-safety reasons:
fn log(log: &impl Log) {
println!("serialized = {}", log.to_log());
}
See also:
The trait cannot be made into an object
Unable to create a polymorphic type because the trait cannot be made into an object
How to implement `serde::Serialize` for a boxed trait object?
How can deserialization of polymorphic trait objects be added in Rust if at all?
Using trait inheritance works, but using the right Serde trait, not the compiler-suggested one:
trait Log: serde::Serialize {
fn to_log(&self) -> String {
serde_json::to_string(&self).unwrap()
}
}
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.