I have this:
#[derive(FromPrimitive)]
pub enum MyEnum {
Var1 = 1,
Var2
}
And an error:
error: cannot find derive macro `FromPrimitive` in this scope
|
38 | #[derive(FromPrimitive)]
| ^^^^^^^^^^^^^
Why do I get this? How do I fix it?
The compiler has a small set of built-in derive macros. For any others, you have to import the custom derives before they can be used.
Before Rust 1.30, you need to use #[macro_use] on the extern crate line of the crate providing the macros. With Rust 1.30 and up, you can use them instead.
In this case, you need to import FromPrimitive from the num_derive crate:
After Rust 1.30
use num_derive::FromPrimitive; // 0.2.4 (the derive)
use num_traits::FromPrimitive; // 0.2.6 (the trait)
Before Rust 1.30
#[macro_use]
extern crate num_derive; // 0.2.4
extern crate num_traits; // 0.2.6
use num_traits::FromPrimitive;
Usage
#[derive(Debug, FromPrimitive)]
pub enum MyEnum {
Var1 = 1,
Var2,
}
fn main() {
println!("{:?}", MyEnum::from_u8(2));
}
Each project has their own crate containing their own derive macros. A small sample:
Num (e.g. FromPrimitive) => num_derive
Serde (e.g. Serialize, Deserialize) => serde_derive
Diesel (e.g. Insertable, Queryable) => diesel (it's actually the same as the regular crate!)
Some crates re-export their derive macros. For example, you can use the derive feature of Serde and then import it from the serde crate directly:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
use serde::{Serialize, Deserialize}; // imports both the trait and the derive macro
FromPrimitive was actually part of the standard library before Rust 1.0. It wasn't useful enough to continue existing in the standard library, so it was moved to the external num crate. Some very old references might not have been updated for this change.
For more information about converting C-like enums to and from integers, see:
How do I match enum values with an integer?
How do I get the integer value of an enum?
Related
how can i have crate that depend on with feature use another version of same crate like below
[features]
serde_1 = ["dep_serde_1"]
serde_1_0_133 = ["dep_serde_1_0_133"]
[dependencies]
dep_serde_1 = { package = "serde", version = "1.0.0", optional = true}
dep_serde_1_0_133 = { package = "serde", version = "1.0.133", optional = true}
my problem is compiler force me to use
use dep_serde_1::*;
except like this
use serde::*;
i just enable one of them at time and in code with cfg(feature = serde_1) i'll chose what code must compile
sorry about my poor English
[Edit]
main idea drive form this problem, for example
if my model use actix-0.10 and another crate that use my lib use actix-0.12 it generate compiler error
I'm not quite sure I understand what you want. If you want the name of the crate to be serde in your use statements, you can rename them back:
#[cfg(feature = "dep_serde_1")]
extern crate dep_serde_1 as serde;
#[cfg(feature = "dep_serde_1_0_133")]
extern crate dep_serde_1_0_133 as serde;
// Now you can
use serde::*;
[Edit:] The above takes care of your use of serde, but serde_derive has its own ideas. When you define a struct like
#[derive(Serialize)]
struct Asdf { /* … */ }
serde generates code that looks roughly like this:
const _: () = {
extern crate serde as _serde;
#[automatically_derived]
impl _serde::Serialize for Asdf { /* …
i.e. it ignores the renaming of the serde crate and tries to use the crate by its original name.
You can override this behavior with the crate container attribute:
#[derive(Serialize)]
#[serde(crate = "serde")]
struct Asdf { /* … */ }
which will make the generated code use the serde from the outer namespace:
const _: () = {
use serde as _serde;
#[automatically_derived]
impl serde::Serialize for Asdf {
Note, that mutually exclusive features are not a good idea. If you can, it's better to make one the default and the other to override it.
I'm also not sure your cargo dependencies are actually doing what you want them to. Cargo doesn't allow depending on a crate twice, and if I force dep_serde_1 to =1.0.0 cargo will complain that there is a conflict.
I have a struct of memory (obj) wrapped in an Arc<Mutex>. The Mutex is an improved version of the std::sync::Mutex in the parking_lot crate. I need to deserialize the wrapped object (obj), however, I get an error:
the trait `_IMPL_DESERIALIZE_FOR_SecurityLevel::_serde::Deserialize<'_>` is not implemented for `lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, Obj>`
In my Cargo.toml, I have (notably):
serde = { version = "1.0.89", features = ["rc"] }
parking_lot = {version = "0.8", features = ["nightly"]}
How should I go about this? Is there a workaround, or must I manually implement the traits?
Support for Serde was added to parking_lot 0.8 under the serde feature flag:
parking_lot = { version = "0.8", features = ["nightly", "serde"] }
Using this, the code you have provided compiles. This also compiles:
use parking_lot::Mutex;
use serde::{Deserialize, Serialize};
fn implements<T>()
where
Mutex<T>: for<'a> Deserialize<'a> + Serialize,
{
}
I come from a Java background, in which finding a symbol definition location is straightforward: it's ether in the same package or it comes via the imports.
Here Deserialize is defined in the serde crate, yet the source file contains no references to serde crate:
#[derive(Deserialize)]
struct Args {
arg_spec: Vec<String>,
flag_short: bool,
flag_porcelain: bool,
flag_branch: bool,
flag_z: bool,
flag_ignored: bool,
flag_untracked_files: Option<String>,
flag_ignore_submodules: Option<String>,
flag_git_dir: Option<String>,
flag_repeat: bool,
flag_list_submodules: bool,
}
(source)
Notice the declaration:
#[macro_use]
extern crate serde_derive;
(source)
This brings all the macros defined in the serde_derive crate into scope. One of those is the Deserialize macro which helps implement the Deserialize trait.
This was the old way of doing things. In the 2018 edition, the preferred way is to import macros with the more familiar use statements.
I have this:
#[derive(FromPrimitive)]
pub enum MyEnum {
Var1 = 1,
Var2
}
And an error:
error: cannot find derive macro `FromPrimitive` in this scope
|
38 | #[derive(FromPrimitive)]
| ^^^^^^^^^^^^^
Why do I get this? How do I fix it?
The compiler has a small set of built-in derive macros. For any others, you have to import the custom derives before they can be used.
Before Rust 1.30, you need to use #[macro_use] on the extern crate line of the crate providing the macros. With Rust 1.30 and up, you can use them instead.
In this case, you need to import FromPrimitive from the num_derive crate:
After Rust 1.30
use num_derive::FromPrimitive; // 0.2.4 (the derive)
use num_traits::FromPrimitive; // 0.2.6 (the trait)
Before Rust 1.30
#[macro_use]
extern crate num_derive; // 0.2.4
extern crate num_traits; // 0.2.6
use num_traits::FromPrimitive;
Usage
#[derive(Debug, FromPrimitive)]
pub enum MyEnum {
Var1 = 1,
Var2,
}
fn main() {
println!("{:?}", MyEnum::from_u8(2));
}
Each project has their own crate containing their own derive macros. A small sample:
Num (e.g. FromPrimitive) => num_derive
Serde (e.g. Serialize, Deserialize) => serde_derive
Diesel (e.g. Insertable, Queryable) => diesel (it's actually the same as the regular crate!)
Some crates re-export their derive macros. For example, you can use the derive feature of Serde and then import it from the serde crate directly:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
use serde::{Serialize, Deserialize}; // imports both the trait and the derive macro
FromPrimitive was actually part of the standard library before Rust 1.0. It wasn't useful enough to continue existing in the standard library, so it was moved to the external num crate. Some very old references might not have been updated for this change.
For more information about converting C-like enums to and from integers, see:
How do I match enum values with an integer?
How do I get the integer value of an enum?
I'm trying to write my own derive mode macro in Rust, and the documentation on it is somewhat lacking in examples.
I have a struct like:
#[derive(MyMacroHere)]
struct Example {
id: i64,
value: Option<String>,
}
I want my macro to generate a method à la
fn set_fields(&mut self, id: i64, value: Option<String>) {
// ...
}
What are the basic steps to use the TokenStream trait to achieve something like that?
Create a crate for your procedural macros:
cargo new my_derive --lib
Edit the Cargo.toml to make it a procedural macro crate:
[lib]
proc-macro = true
Implement your procedural macro:
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_derive(MyMacroHere)]
pub fn my_macro_here_derive(input: TokenStream) -> TokenStream {
// ...
}
Import the procedural macro and use it:
extern crate my_derive;
use my_derive::MyMacroHere;
#[derive(MyMacroHere)]
struct Example {
id: i64,
value: Option<String>,
}
The hard part is in implementation of the macro. Most people use the syn and quote crates to parse the incoming Rust code and then generate new code.
For example, syn's documentation starts with an example of a custom derive. You will parse the struct (or enum or union) and then handle the various ways of defining a struct (unit, tuple, named fields). You'll collect the information you need (type, maybe name), then you'll generate the appropriate code.
See also:
How to Write a Custom derive Macro
Documentation for proc_macro
Documentation for syn
Documentation for quote
Is it possible to add your own derivable traits, or are these fixed by the compiler?