Rust trait not satisfied - rust

I'm new to rust and tried searching in stackoverflow as well as reading the serde documentation
https://docs.serde.rs/serde/trait.Serialize.html and https://serde.rs/impl-serialize.html, but I was a bit lost.
I would like to use Tera to generate html and the struct I'm passing it does not have the trait serde::ser::Serialize implemented and I tried to implement it but it doesn't appear quite right.
Cargo.toml dependencies
serde = "1.0.115"
serde_derive = "1.0.115"
serde-xml-rs = "0.4.0"
tera = "0.7.2"
main.rs
extern crate tera;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use tera::Context;
use serde::ser::{Serialize, SerializeStruct, Serializer};
#[derive(Serialize, Debug)]
struct Person {
firstname: String,
lastname: String,
age: i32,
}
#[derive(Debug)]
struct Attendees {
people: Vec<Person>,
updatedOn: String,
updatedBy: String,
}
impl Serialize for Attendees {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("Person", 3)?;
s.serialize_field("people", &self.people)?;
s.serialize_field("updatedOn", &self.updatedOn)?;
s.serialize_field("updatedBy", &self.updatedBy)?;
s.end()
}
}
fn main() {
let mut context = Context::new();
let mut peeps: Vec<Person> = Vec::new();
let mut attendees = Attendees {
people: peeps,
updatedOn: String::from("today"),
updatedBy: String::from("someone"),
};
context.add("attendees", &attendees);
}
compiler says:
mytest % cargo run
Compiling mytest v0.1.0 (/home/mike/mytest)
error[E0277]: the trait bound `Attendees: serde::ser::Serialize` is not satisfied
--> src/main.rs:44:29
|
44 | context.add("attendees", &attendees);
| ^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `Attendees`
error: aborting due to previous error
I am clearly missing something... Can anyone please help?

The trait you implemented and the trait that the error is referring are not the same, because they refer to two different versions of serde.
[[package]]
name = "tera"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c37e2aaa53871f9c3722a20f8951fea0afd366955e11542a58feb71997c6d769"
dependencies = [
"chrono",
"error-chain",
"glob",
"humansize",
"lazy_static 0.2.11",
"pest",
"regex",
"serde 0.9.15",
"serde_json",
"slug",
"url",
]
tera 0.7.2 is not using the version 1.0.* of serde, but 0.9.*.
You may use a more recent of tera, or use a compatible serde version in your Cargo.toml:
[dependencies]
serde = "0.9.15"
serde_derive = "0.9.15"

Related

Error on Post Method query_builder::QueryFragment / query_builder::QueryFragment

I am relatively new to rust and have really enjoyed playing around with it. However I am stuck on an error for my CRUD application using Diesel and Rocket. I have a main.rs, model.rs and schema.rs.
I get an error with my POST method that uses the User struct i created.
I am using a postgres DB i have running in the background on docker, Diesel and rocket for routing.
My models.rs
use super::schema::users;
use diesel::{prelude::*, table, Queryable, Insertable, RunQueryDsl};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Queryable, Debug, Insertable)]
#[table_name= "users"]
pub struct User {
pub id: i32,
pub first_name: String,
pub last_name: String,
pub user_name: String,
pub email_address: String,
}
My main.rs (included everything for detail but really question is about the Post method - create_user
#[macro_use] extern crate rocket;
mod models;
mod schema;
use rocket_sync_db_pools::{database};
use models::{User};
use rocket::{serde::json::Json};
use diesel::{RunQueryDsl};
use schema::users;
#[database("my_db")]
pub struct Db(rocket_sync_db_pools::diesel::PgConnection);
#[get("/")]
fn index() -> &'static str {
"Hello World"
}
#[get("/<id>")]
fn get_user(id: i32) -> Json<User> {
Json(User {
id: id,
first_name: "A Fist Name".to_string(),
last_name: "A Last Name".to_string(),
user_name: "A User Name".to_string(),
email_address: "AnEmail#email.com".to_string(),
})
}
#[post("/", data = "<user>")]
async fn create_user(connection: Db, user: Json<User>) -> Json<User> {
connection.run(move |c| {
diesel::insert_into(users::table)
.values(&user.into_inner())
.get_result(c)
})
.await
.map(Json)
.expect("There was an error saving the user")
}
#[launch]
fn rocket() -> _ {
let rocket = rocket::build();
rocket
.attach(Db::fairing())
.mount("/", routes![index])
.mount("/users", routes![get_user, create_user])
}
Dependencies from Cargo.toml
[dependencies]
diesel = "2.0.2"
diesel_cli = { version = "1.4.1", default-features = false, features = ["postgres"] }
rocket = { version = "0.5.0-rc.2", features = ["json"] }
rocket_sync_db_pools = { version = "0.1.0-rc.2", features = ["diesel_postgres_pool"] }
serde = "1.0.140"
The error message
--> src/main.rs:66:6
|
66 | .get_result(c)
| ^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`with_auth_rust_rocket_diesel_binary`)
= note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, &i32>>>`
= note: 123 redundant requirements hidden
= note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, &i32>>>`
= note: required because of the requirements on the impl of `diesel::insertable::InsertValues<table, _>` for `DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, &i32>>>`
= note: 3 redundant requirements hidden
= note: required because of the requirements on the impl of `diesel::query_builder::QueryFragment<_>` for `diesel::query_builder::InsertStatement<table, diesel::query_builder::insert_statement::ValuesClause<(DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, &i32>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::first_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::last_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::user_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::email_address, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>), table>, diesel::query_builder::insert_statement::private::Insert, diesel::query_builder::returning_clause::ReturningClause<(columns::id, columns::first_name, columns::last_name, columns::user_name, columns::email_address)>>`
= note: required because of the requirements on the impl of `diesel::query_dsl::LoadQuery<'_, _, _>` for `diesel::query_builder::InsertStatement<table, diesel::query_builder::insert_statement::ValuesClause<(DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::id, diesel::expression::bound::Bound<diesel::sql_types::Integer, &i32>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::first_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::last_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::user_name, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>, DefaultableColumnInsertValue<diesel::insertable::ColumnInsertValue<columns::email_address, diesel::expression::bound::Bound<diesel::sql_types::Text, &std::string::String>>>), table>>`
note: required by a bound in `diesel::RunQueryDsl::get_result`
--> /Users/me/.cargo/registry/src/github.com-1ecc6299db9ec823/diesel-2.0.2/src/query_dsl/mod.rs:1679:15
|
1679 | Self: LoadQuery<'query, Conn, U>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `diesel::RunQueryDsl::get_result`
I have reviewed both Diesel, Rocket and Rust documentation and worked worked through other examples for what I can find online however still do not quite get what i am doing incorrectly. Thanks in advance for any help.
I tried to create a post method that uses Diesel to take a Json version of my User object and insert it into my database.
This is a mismatch between the diesel version used by your project (2.0.2) and the diesel version provided by rocket_sync_db_pools (1.4.8). This means the c in connection.run(move |c| { is just a completely different type than expected by get_result, even if the types share the same name.

Error while rocket implementation for creating a basic API

I have been programming in Rust for a month or so and now I wanted to try out API's using Rocket in rust. I tried to implement the below code but I got the error the trait bound \Json<Test>: Responder<'_, '_> is not satisfied . Not quite sure what I did wrong I tried to find out a reason for it but couldn't get any. I am referring to this video and this guide, according to which I did everything correct.
Also side note: I use extern crate rocket but it still does not recognize Build, routes, etc. Any solution to this as well?
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
use rocket::*;
use rocket_contrib::json::Json;
use serde_json::json;
struct Test{
name: String,
}
#[get("/")]
fn hello_world() -> Json<Test> {
let test: Test = Test { name: String::from("Test54") };
Json(test)
}
#[launch]
fn rocket() -> Rocket<Build> {
rocket::build()
.mount(
"/",
routes![hello_world]
)
}
cargo.toml
[package]
name = "backend"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "lib"
path = "src/lib.rs"
[[bin]]
name = "backend"
path = "src/bin.rs"
[dependencies]
rocket = "0.5.0-rc.1"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
[dependencies.rocket_contrib]
version = "0.4"
default-features = false
features = ["json"]
error log
error[E0277]: the trait bound `Json<Test>: Responder<'_, '_>` is not satisfied
--> src/bin.rs:19:21
|
19 | fn hello_world() -> Json<Test> {
| ^^^^^^^^^^ the trait `Responder<'_, '_>` is not implemented for `Json<Test>`
|
= help: the following other types implement trait `Responder<'r, 'o>`:
<&'o [u8] as Responder<'r, 'o>>
<&'o str as Responder<'r, 'o>>
<() as Responder<'r, 'static>>
<(ContentType, R) as Responder<'r, 'o>>
<(Status, R) as Responder<'r, 'o>>
188 | pub fn from<R: Responder<'r, 'o>>(req: &'r Request<'_>, responder: R) -> Outcome<'r> {
| ^^^^^^^^^^^^^^^^^ required by this bound in `route::handler::<impl Outcome<rocket::Response<'o>, Status, rocket::Data<'o>>>::fr
om`
For more information about this error, try `rustc --explain E0277`.
rocket_contrib::json::Json only implements rocket::response::Responder if the T it contains implements serde::ser::Serialize (due to this). Currently, your Teststruct does not implement Serialize, so Json<Test> does not implement Responder; this is what the compiler is complaining about.
You can easily implement Serialize for Test by deriving it:
use serde::Serialize;
#[derive(Serialize)]
struct Test {
name: String,
}

cannot infer type for type parameter `T` declared on the associated function `matches`

I am trying to using rust diesel full text search, first I added the dependencies:
diesel_full_text_search = "1.0.1"
then tweak my search code like this:
#[macro_use]
extern crate diesel;
use diesel::{QueryDsl, RunQueryDsl};
use diesel_full_text_search::{ to_tsvector};
use rust_wheel::config::db::config;
use diesel_full_text_search::TsVectorExtensions;
use crate::model::diesel::dict::dict_models::Article;
mod model;
fn main() {
use model::diesel::dict::dict_schema::article as article_table;
let connection = config::establish_connection();
let mut query = article_table::table.into_boxed::<diesel::pg::Pg>();
let tsvector = to_tsvector("'dolphinzhcfg', title");
query = query.filter(&tsvector.matches("经济".parse().unwrap()));
let query_result = query.load::<Article>(&connection);
}
when I compile this code, shows error like this:
error[E0284]: type annotations needed
--> src/main.rs:17:36
|
17 | query = query.filter(&tsvector.matches("经济".parse().unwrap()));
| ^^^^^^^ cannot infer type for type parameter `T` declared on the associated function `matches`
|
= note: cannot satisfy `<_ as AsExpression<TsQuery>>::Expression == _`
help: consider specifying the type argument in the method call
|
17 | query = query.filter(&tsvector.matches("经济".parse::<F>().unwrap()));
| +++++
For more information about this error, try `rustc --explain E0284`.
error: could not compile `rust-learn` due to previous error
what should I do to avoid this problem? BTW, this is the dict_schema.rs:
table! {
article (id) {
id -> Int8,
user_id -> Int8,
title -> Varchar,
author -> Varchar,
guid -> Varchar,
created_time -> Int8,
updated_time -> Int8,
link -> Nullable<Varchar>,
sub_source_id -> Int8,
cover_image -> Nullable<Varchar>,
channel_reputation -> Int4,
editor_pick -> Nullable<Int4>,
}
}
and this is the dict_models.rs:
// Generated by diesel_ext
#![allow(unused)]
#![allow(clippy::all)]
use std::io::Write;
use diesel::deserialize::FromSql;
use diesel::pg::Pg;
use diesel::serialize::{Output, ToSql};
use diesel::sql_types::Jsonb;
use rocket::serde::Serialize;
use serde::Deserialize;
use chrono::DateTime;
use chrono::Utc;
use crate::model::diesel::dict::dict_schema::*;
#[derive(Queryable,QueryableByName,Debug,Serialize,Deserialize,Default,Clone)]
#[table_name = "article"]
pub struct Article {
pub id: i64,
pub user_id: i64,
pub title: String,
pub author: String,
pub guid: String,
pub created_time: i64,
pub updated_time: i64,
pub link: Option<String>,
pub sub_source_id: i64,
pub cover_image: Option<String>,
pub channel_reputation: i32,
pub editor_pick: Option<i32>,
}
this is the dependencies of the demo:
[package]
name = "rust-learn"
version = "0.1.0"
edition = "2018"
[dependencies]
rocket = { version = "=0.5.0-rc.2", features = ["json"] }
serde = { version = "1.0.64", features = ["derive"] }
serde_json = "1.0.64"
serde_derive = "1.0"
# database
diesel = { version = "1.4.7", features = ["postgres","serde_json"] }
dotenv = "0.15.0"
jsonwebtoken = "7"
chrono = "0.4"
config = "0.11"
ring = "0.16.20"
md5 = "0.7.0"
data-encoding = "2.3.2"
bigdecimal = "0.3.0"
# reddwarf public component
rust_wheel = { git = "https://github.com/jiangxiaoqiang/rust_wheel.git" }
diesel_full_text_search = "1.0.1"
The error message already contains all information required to fix this problem:
= note: cannot satisfy `<_ as AsExpression<TsQuery>>::Expression == _`
help: consider specifying the type argument in the method call
|
17 | query = query.filter(&tsvector.matches("经济".parse::<F>().unwrap()));
| +++++
which means you need to specify whatever type .parse() should parse into, as rustc cannot infer a type there. The concrete type depends on whatever type is expected by matches (checkout the documentation for that).

Unable to use parity_codec's Encode even though I have derived it for a struct

I am trying to use Encode::encode on structs with a derived implementation, but I am getting this error:
error[E0599]: no method named `encode` found for type `AnimalCollection<Animal>` in the current scope
--> src/main.rs:42:57
|
13 | struct AnimalCollection<A: AnimalTrait> {
| --------------------------------------- method `encode` not found for this
...
42 | println!("animal collection encoded = {:?}",animals.encode());
| ^^^^^^
|
= note: the method `encode` exists but the following trait bounds were not satisfied:
`AnimalCollection<Animal> : _IMPL_DECODE_FOR_Animal::_parity_codec::Encode`
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `encode`, perhaps you need to implement it:
candidate #1: `_IMPL_DECODE_FOR_Animal::_parity_codec::Encode`
This is the code:
use indexmap::map::IndexMap;
use parity_codec;
use parity_codec::{Decode, Encode};
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
struct Animal {
name: String,
cell: u32,
}
trait AnimalTrait: Encode + Decode {}
impl AnimalTrait for Animal {}
#[derive(Clone, PartialEq, Eq, Encode, Decode, Debug)]
struct AnimalCollection<A: AnimalTrait> {
animals: IndexMap<String, A>,
}
impl<A: AnimalTrait> AnimalCollection<A> {
fn new() -> AnimalCollection<A> {
AnimalCollection {
animals: IndexMap::new(),
}
}
fn add(&mut self, name: String, a: A) {
self.animals.insert(name, a);
}
}
fn main() {
let a = Animal {
name: String::from("Tiger"),
cell: 10,
};
println!("animal struct encoded = {:?}", a.encode());
let mut animals = AnimalCollection::<Animal>::new();
animals.add(
String::from("Dog"),
Animal {
name: String::from("Dog"),
cell: 1,
},
);
animals.add(
String::from("Cat"),
Animal {
name: String::from("Cat"),
cell: 2,
},
);
println!("animal collection encoded = {:?}", animals.encode());
}
Why isn't it working despite that I have #[derive]d all the traits automatically? How do I fix it?
Since I am deriving the Encode and Decode traits, I shouldn't really implement anything on my own, or should I?
I tested this code and it works on the Animal struct but doesn't work on the AnimalCollection struct. I also tried to implement the Encode trait on AnimalCollection but immediately got "conflicting implementation" error, so I am kind of stuck on how to solve this.
Cargo.toml is a bit tricky, you need to use derive feature:
[package]
name = "encmap"
version = "0.0.1"
edition = "2018"
[dependencies]
parity-codec = { version = "3.3", features = ["derive"] }
indexmap = "1.0.2"

the trait `serde::Deserialize<'_>` is not implemented for `diesel_geography::types::GeogPoint`

I'm trying to use Diesel and diesel_geography to read from a PostGIS database using Rust.
Here's the error I'm getting:
error[E0277]: the trait bound `diesel_geography::types::GeogPoint: serde::Serialize` is not satisfied
--> src/models.rs:11:5
|
11 | pub coordinates: GeogPoint,
| ^^^ the trait `serde::Serialize` is not implemented for `diesel_geography::types::GeogPoint`
|
= note: required by `serde::ser::SerializeStruct::serialize_field`
error[E0277]: the trait bound `diesel_geography::types::GeogPoint: serde::Deserialize<'_>` is not satisfied
--> src/models.rs:11:5
|
11 | pub coordinates: GeogPoint,
| ^^^ the trait `serde::Deserialize<'_>` is not implemented for `diesel_geography::types::GeogPoint`
|
= note: required by `serde::de::SeqAccess::next_element`
error[E0277]: the trait bound `diesel_geography::types::GeogPoint: serde::Deserialize<'_>` is not satisfied
--> src/models.rs:11:5
|
11 | pub coordinates: GeogPoint,
| ^^^ the trait `serde::Deserialize<'_>` is not implemented for `diesel_geography::types::GeogPoint`
|
= note: required by `serde::de::MapAccess::next_value`
Looking around, I found that a similar error happens when there are several versions of serde used as dependency, this can be checked using cargo tree -d. I've tried and serde does not appear as a duplicate dependency.
This is my code so far:
Cargo.toml
[package]
name = "123"
version = "0.1.0"
authors = ["ASD"]
edition = "2018"
[dependencies]
diesel = { version = "1.4.2", features = ["postgres"] }
serde = { version = "1.0", features = ["derive"] }
serde_json="1.0"
dotenv = "0.14.1"
diesel-geography = "0.2.0"
schema.rs
table! {
use diesel::sql_types::*;
use diesel_geography::sql_types::*;
users (email) {
email -> Varchar,
password -> Varchar,
coordinates -> Geography
}
}
models.rs
use diesel_geography::types::*;
use crate::schema::users;
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize, Queryable, Insertable)]
#[table_name = "users"]
pub struct User {
pub email: String,
pub password: String,
pub coordinates: GeogPoint
}
main.rs
extern crate serde;
extern crate dotenv;
#[macro_use] extern crate diesel;
//#[macro_use] extern crate serde_derive;
mod models;
mod schema;
use diesel::PgConnection;
use dotenv::dotenv;
use std::env;
use diesel::prelude::*;
fn main() {
dotenv().ok();
let database_url = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
let connection = PgConnection::establish(&database_url)
.expect(&format!("Error connecting to {}", database_url));
use crate::schema::users::dsl::*;
use crate::models::User;
let results = users
.limit(5)
.load::<User>(&connection)
.expect("Error loading users");
println!("Displaying {} users", results.len());
for user in results {
println!("{}", user.email);
println!("----------\n");
println!("{}", user.password);
}
}
Serde is an optional dependency of diesel-geography. You need to enable the feature:
[dependencies]
diesel-geography = { version = "0.2.0", features = ["serde"] }

Resources