I'm working on a pallet and after switching to the newest node template it stopped building. Here is declaration
#[derive(Encode, Decode, Clone)]
pub struct VendorData<T :Config>
{
pub vendor : VendorId,
pub owner_account_id : T::AccountId,
}
impl<T:Config> Default for VendorData<T> {
fn default() -> Self {
Self {
vendor : Default::default(),
owner_account_id : Default::default(),
}
}
}
#[pallet::storage]
pub(super) type Vendors<T: Config> = StorageMap<_, Blake2_128Concat, VendorId, VendorData<T>, ValueQuery>;
The cargo build error:
error[E0277]: the trait bound `VendorData<T>: TypeInfo` is not satisfied
...
#[pallet::storage]
^^^^^^^ the trait `TypeInfo` is not implemented for `VendorData<T>`
I've tried declaring struct in a different ways, for example by adding TypeInfo:
#[derive(Encode, Decode, Default, Eq, PartialEq, TypeInfo)]
but every time another errors arise, like this:
error: cannot find macro `format` in this scope
--> /home/psu/.cargo/git/checkouts/substrate-7e08433d4c370a21/352c46a/primitives/consensus/aura/src/lib.rs:50:3
|
50 | app_crypto!(ed25519, AURA);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: consider importing this macro:
scale_info::prelude::format
= note: this error originates in the macro `$crate::app_crypto_public_common_if_std` (in Nightly builds, run with -Z macro-backtrace for more info)
There is another storage item which does not cause errors
pub type Cid = Vec<u8>;
#[pallet::storage]
pub(super) type VendorModels<T: Config> = StorageMap<_, Blake2_128Concat, VendorId, Vec<Cid>, ValueQuery>;
So it seems it's only about storing VendorData struct. Please assist, after hours of experiments and googling I'm lost
UPDATE: after adding TypeInfo to all storage structs declaration the pallet is compiled but a lot of errors like below arised:
error: cannot find macro `format` in this scope
error: cannot find macro `vec` in this scope
You will need to either make sure that all your generic types implement TypeInfo or skip the types explicitly.
Based on this example code in Substrate you could write:
#[derive(Encode, Decode, Clone, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct VendorData<T :Config>
{
pub vendor : VendorId,
pub owner_account_id : T::AccountId,
}
Or alternatively the following should work:
#[derive(Encode, Decode, Clone, TypeInfo)]
pub struct VendorData<AccountId>
{
pub vendor : VendorId,
pub owner_account_id : AccountId,
}
Related
I want to provide default values for structs to be used only within tests (and not accidentally in production). I thought that I could make the defaults opt-in by defining my own trait TestDefault and implement Default for any type that implements it. Then, one could access all the features of the standard Default trait using something like this
use TestDefault; // TestStruct (defined in my crate) implements TestDefault, thus also Default
let test_struct = TestStruct::default();
To clarify, I want to implement a foreign trait on local type, which should be allowed, but with an artificial layer of indirection to make it opt-in.
I've tried
pub trait TestDefault {
fn test_default() -> Self;
}
impl Default for TestDefault {
fn default() -> Self {
Self::test_default()
}
}
where the compiler complains that error[E0782]: trait objects must include the 'dyn' keyword, inserting it instead causes it to fail because error[E0038]: the trait 'TestDefault' cannot be made into an object.
Then I tried
impl<T> Default for T
where
T: TestDefault,
{
fn default() -> T {
T::test_default()
}
}
and got
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/lib.rs:158:14
|
158 | impl<T> Default for T
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
which probably hints at the actual error, but I don't entirely understand it. Is there any way to do this? Or get opt-in default some other way?
You can use the #[cfg(test)] annotation to only enable the Default implementation when testing:
struct MyStruct {
data: u32,
}
#[cfg(test)]
impl Default for MyStruct {
fn default() -> Self {
Self { data: 42 }
}
}
fn main() {
let s = MyStruct::default(); // FAILS
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let s = MyStruct::default(); // WORKS
assert_eq!(s.data, 42);
}
}
> cargo test
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
> cargo run
error[E0599]: no function or associated item named `default` found for struct `MyStruct` in the current scope
--> src/main.rs:13:23
|
1 | struct MyStruct {
| --------------- function or associated item `default` not found for this
...
13 | let s = MyStruct::default(); // FAILS
| ^^^^^^^ function or associated item not found in `MyStruct`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `default`, perhaps you need to implement it:
candidate #1: `Default`
I am working with a course on coatings with the Solana Spotify Project and studying on YouTube. Please tell me the code produces such errors, but everything is written correctly and clearly. I don't know where I forgot.
use anchor_lang::prelude::*;
use anchor_lang::solana_program::entrypoint::ProgramResult;
use anchor_spl::token::{self,Token};
use std::mem::size_of;
// This is your program's public key and it will update
// automatically when you build the project.
declare_id!("11111111111111111111111111111111");
#[program]
mod spotify_clone {
use super::*;
pub fn accept_payment(ctx: Context<PayerContext>, data: u64) -> ProgramResult {
let payer_wallet = &mut ctx.accounts.payer_wallet;
payer_wallet.wallet = ctx.accounts.authority.key();
let ix = anchor_lang::solana_program::system_instruction::transfer(
&ctx.accounts.authority.key(),
&ctx.accounts.receiver.key(),
100000000,
);
anchor_lang::solana_program::program::invoke(
&ix,
&[
ctx.accounts.authority.to_account_info(),
ctx.accounts.receiver.to_account_info(),
],
)
}
}
#[derive(Accounts)]
pub struct PayerContext<'info> {
#[account(
init,
seeds = [b"payer".as_ref(), authority.key().as_ref()],
bump,
payer = authority,
space = size_of::<PayerAccount>() + 8,
)]
pub payer_wallet: Account<'info, PayerAccount>,
//Specific param to object
#[account(mut)]
pub receiver: AccountInfo<'info>,
//Specific param to object
//Authority[this is signer who paid transaction fee]
#[account(mut)]
pub authority: Signer<'info>,
pub system_programm: UncheckedAccount <'info>,
//Token Programm
#[account(constraint = token_program.key == &token::ID)]
pub token_program: Program<'info, Token>,
//Clock to the Save Your Time
pub clock: Sysvar<'info,Clock>,
}
#[account]
pub struct PayerAccount{
pub wallet: Pubkey,
}
Error appears here. The main problem in the code i think is here:
pub payer_wallet: Account<'info, PayerAccount>,
Code of error E0277:
error[E0277]: the trait bound `PayerContext<'_>: anchor_lang::Accounts<'_>` is not satisfied
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ the trait `anchor_lang::Accounts<'_>` is not implemented for `PayerContext<'_>`
|
note: required by `anchor_lang::context::Context::<'a, 'b, 'c, 'info, T>::new`
Second error E0432:
error[E0432]: unresolved import `crate`
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ could not find `__client_accounts_payer_context` in the crate root
|
= note: this error originates in the attribute macro `program` (in Nightly builds, run with -Z macro-backtrace for more info)
Third error E0599:
error[E0599]: no method named `exit` found for struct `PayerContext` in the current scope
--> /src/lib.rs:10:1
|
10 | #[program]
| ^^^^^^^^^^ method not found in `PayerContext<'_>`
...
34 | pub struct PayerContext<'info> {
| ------------------------------ method `exit` not found for this
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `exit`, perhaps you need to implement it:
candidate #1: `anchor_lang::AccountsExit`
= note: this error originates in the attribute macro `program` (in Nightly builds, run with -Z macro-backtrace for more info)
Try adding
#[derive(Accounts)] to PayerContext
Like this
#[derive(Accounts)]
pub struct PayerContext<'info> {}
In the code below: Rust Playground
//////////////////////////////////////
// External code from another crate //
//////////////////////////////////////
trait FooExternal {
fn foo(&self);
}
fn foo_external(f: impl FooExternal) {
f.foo();
}
/////////////////////////////////////
// My generated library code below //
/////////////////////////////////////
trait FooImpl {
fn foo_impl(&self);
}
impl<T: FooImpl> FooExternal for T {
fn foo(&self) {
println!("foo: boilerplate");
self.foo_impl();
}
}
////////////////////////
// My user code below //
////////////////////////
#[derive(Debug, Default)]
struct Foo;
// NB: the compiler will yell if FooImpl is not implemented
// try commenting out the impl below
impl FooImpl for Foo {
fn foo_impl(&self) {
println!("foo_impl");
}
}
fn main() {
println!("Hello, world!");
let f = Foo::default();
foo_external(f);
}
The external code expects user to supply a type that implements FooExternal, so foo_external can work on an instance of the type.
However, when implementing the FooExternal trait for a user defined struct Foo, there is some boilerplate code (e.g. setting up opentelemetry tracing span context for each tonic grpc handler) that is common and error prone and a little complex to require an end user to type out.
So I plan to generate (think: proc macro, but codegen is not the issue here!) the common boilerplate implementation of FooExternal, and want user to only focus on the core app logic, and not worrying about the complex and boring chore of typing the same boilerplate over and over again!
So, instead of having user to implement FooExternal for her type Foo, I want the user to implement a generated trait FooImpl, where in the generated blanket trait implementation of FooExternal::foo, the boilerplate code is emitted, and the control is forwarded to FooImpl::foo_impl.
Here's the nice thing in the user code: FooImpl becomes a requirement for the user type Foo (when using foo_external) - if the user forgets to implement FooImpl for Foo, the compiler would kindly yell at you when calling foo_external(f)!
So it seems that the trait blanket implementation effectively have FooExternal bound on FooImpl - even the compiler error message (when the impl FooImpl for Foo is commented out) says:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `Foo: FooImpl` is not satisfied
--> src/main.rs:49:18
|
49 | foo_external(f);
| ^ the trait `FooImpl` is not implemented for `Foo`
|
note: required because of the requirements on the impl of `FooExternal` for `Foo`
--> src/main.rs:23:18
|
23 | impl<T: FooImpl> FooExternal for T {
| ^^^^^^^^^^^ ^
note: required by a bound in `foo_external`
--> src/main.rs:11:25
|
11 | fn foo_external(f: impl FooExternal) {
| ^^^^^^^^^^^ required by this bound in `foo_external`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
So, I'm wondering that is trait blanket implementation ever designed to be used in such a scenario (basically tie FooImpl and FooExternal together, a little like extension trait trait FooExternal: FooImpl, but not quite!), and can I rely on this behavior to define my code generation logic to generate the library code as in the code sample?
Any insights would be greatly appreciated!
According to the trait coherence rules, impl<T: FooImpl> FooExternal for T must be in the same crate as FooExternal. So, if you do not control the crate FooExternal is defined in, you cannot do this.
The rules are are designed so that adding more crates can never create a conflict between trait implementations that wasn't there already. There can only be one blanket implementation impl<T...> FooExternal for T (because if there was more than one, they might both apply to the same type T), and only the crate defining FooExternal is allowed to write that implementation.
I currently trying to implement abstract function which will update a few meta fields for any table in the database, but getting problems with Identifiable.
I have a database where every table has meta-fields:
....
pub updu: Option<Uuid>, // ID of a user who changed it
pub updt: Option<NaiveDateTime>, //updated with current date/time on every change
pub ver: Option<i32>, //Version increases on every change
.....
I want to implement a function which would make update for every entity. Currently I have this implementation:
pub fn update<Model>(
conn: &PgConnection,
old_model: Model,
mut updated_model: Model,
user_id: Uuid,
) -> Result<Model, diesel::result::Error>
where
Model: MetaFields + AsChangeset<Target = <Model as HasTable>::Table> + IntoUpdateTarget,
Update<Model, Model>: LoadQuery<PgConnection, Model>
{
updated_model.update_fields(user_id);
Ok(
diesel::update(old_model)
.set(updated_model)
.get_result(conn).unwrap()
)
When I am trying to call it it shows this error:
error[E0277]: the trait bound `Marking: Identifiable` is not satisfied
--> src/service/marking_service.rs:116:24
|
116 | web::block(move || common::dao::update(&conn2, real_marking1[0].clone(), marking2_to_update, jwt_token.user_id))
| ^^^^^^^^^^^^^^^^^^^ the trait `Identifiable` is not implemented for `Marking`
|
= help: the following implementations were found:
<&'ident Marking as Identifiable>
= note: required because of the requirements on the impl of `IntoUpdateTarget` for `Marking`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `testapi` due to previous error
An entity which I am trying to update in this example is:
use chrono::{NaiveDateTime, Utc};
use common::model::MetaFields;
use common::utils::constants::DEL_MARK_AVAILABLE;
use serde::{Deserialize, Serialize};
use serde_json;
use uuid::Uuid;
use crate::schema::marking;
#[derive(
Clone,
Serialize,
Deserialize,
Debug,
Queryable,
Insertable,
AsChangeset,
Identifiable,
QueryableByName,
Default,
)]
#[primary_key(uuid)]
#[table_name = "marking"]
pub struct Marking {
pub uuid: Uuid,
pub updt: Option<NaiveDateTime>,
pub ver: Option<i32>,
pub updu: Option<Uuid>,
pub comment: Option<String>,
pub status: Option<String>,
}
impl MetaFields for Marking {
fn update_fields(&mut self, user_id: Uuid) {
self.updu = Option::from(user_id);
self.ver = Option::from(self.ver.unwrap() + 1);
self.updt = Option::from(Utc::now().naive_local());
}
}
As you can see Identifiable is defined for this entity, but for some reason update cannot see it. Could someone suggest what I am missing here?
Update, schema:
table! {
marking (uuid) {
uuid -> Uuid,
updt -> Nullable<Timestamp>,
ver -> Nullable<Int4>,
updu -> Nullable<Uuid>,
comment -> Nullable<Varchar>,
status -> Nullable<Varchar>,
}
}
diesel = { version = "1.4.6", features = ["postgres", "uuid", "chrono", "uuidv07", "serde_json"] }
r2d2 = "0.8"
r2d2-diesel = "1.0.0"
diesel_json = "0.1.0"
Your code is almost correct. The error message already mentions the issue:
#[derive(Identifiable)] does generate basically the following impl: impl<'a> Identifiable for &'a struct {}, which means that trait is only implemented for a reference to self. Depending on your other trait setup you can try the following things:
Pass a reference as old_model common::dao::update
Change the definition of common::dao::update to take a reference as second argument. Then you can separate the trait bounds for Model so that you bound IntoUpdateTarget on &Model instead.
(It's hard to guess which one will be the better solution as your question is missing a lot of important context. Please try to provide a complete minimal example in the future.)
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 {