unresolved import `serde`/`serde_json` - rust

I build the project without any visible errors but when compiling it I encounter the error E0432 that tells me that serde and serde_json are not found when they have been declared in the Cargo.toml. I tried rebuilding the project from scratch, cargo check and cargo build multiple times and I'm still stuck
The error(s):
error[E0432]: unresolved import `serde`
--> main.rs:1:5
|
1 | use serde::{Deserialize, Serialize};
| ^^^^^ maybe a missing crate `serde`?
error[E0432]: unresolved import `serde_json`
--> main.rs:2:5
|
2 | use serde_json::Result;
| ^^^^^^^^^^ maybe a missing crate `serde_json`?
error: cannot determine resolution for the derive macro `Serialize`
--> main.rs:4:10
|
4 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^
|
= note: import resolution is stuck, try simplifying macro imports
error: cannot determine resolution for the derive macro `Deserialize`
--> main.rs:4:21
|
4 | #[derive(Serialize, Deserialize)]
| ^^^^^^^^^^^
|
= note: import resolution is stuck, try simplifying macro imports
error[E0433]: failed to resolve: use of undeclared crate or module `serde_json`
--> main.rs:14:32
|
14 | let config: ConfigStruct = serde_json::from_str(&config_data).unwrap();
| ^^^^^^^^^^ use of undeclared crate or module `serde_json`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0432, E0433.
For more information about an error, try `rustc --explain E0432`.
main.rs file:
use serde::{Deserialize, Serialize};
use serde_json::Result;
#[derive(Serialize, Deserialize)]
struct ConfigStruct {
playlist_name: String,
replace_cover: bool,
delete_songs: bool,
songs_ids: Vec<String>,
}
fn get_config() -> Result<ConfigStruct> {
let config_data = std::fs::read_to_string("../config.json").unwrap();
let config: ConfigStruct = serde_json::from_str(&config_data).unwrap();
Ok(config)
}
fn main() {
let config = get_config().unwrap();
println!("{}", config.playlist_name);
}
Cargo.toml file:
[package]
name = "grrs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = {version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
Cargo.lock file:
# This file is automatically #generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "grrs"
version = "0.1.0"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "itoa"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
[[package]]
name = "proc-macro2"
version = "1.0.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
[[package]]
name = "serde"
version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.85"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"

You need to enable derive feature from serde crate.
Your cargo.toml file should look something like this:
[package]
name = "grrs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
rspotify = "0.11.5"
Notice the feature key in the serde dependency decleration.

Related

How to let a package use the same version of dependencies as B?

I have a project A and B like the following, B depend on A. A is a git submoudle.
repo
|- contrib
|--- A
|----- components
|------- package A
|------- package B
|----- Cargo.toml
|- B
|--- Cargo.toml
A have dependency like the following
// A/Cargo.toml
serde = "1.0"
serde_derive = "1.0"
serde_ignored = "0.1"
serde_json = "1.0"
tempfile = "3.0"
lazy_static = "1.3"
I want B have the same dependency version like A, like the following
// B/Cargo.toml
compA = { path = "../A/components/compA" }
compB = { path = "../A/components/compB" }
serde = "1.0"
serde_derive = "1.0"
serde_ignored = "0.1"
serde_json = "1.0"
tempfile = "3.0"
lazy_static = "1.3"
However, once A is updated, it may updates its dependencies. So A may use serde = "2.0" later. So how can B "automaticly" update its serde to 2.0?
I think I need something that says "B depends the serde which A is depending".
I think I need something that says "B depends the serde which A is depending".
A should expose/re-export the relevant crates (or parts thereof), for example:
pub use serde; // etc
and then B should use those exports rather than declaring each dependency in its Cargo.toml:
use A::serde; // etc

How to publish a crate with optional dependency?

I have some trouble about publishing crates with optional dependencies.
First, I execute cargo publish, but I don't see any optional dependencies compiled.
Then, I run cargo publish --all-features. The dependencies were compiled, but I don't see any modules with optional dependency in the documentation generated by crates.io.
What is the correct way to publish a crate with an optional dependency, which does not a default feature setting in Cargo.toml?
cargo publish is the correct way to do it.
If you want that docs.rs (not crates.io) builds your documentation with some features enabled, use the package.metadata.docs.rs section in your Cargo.toml. I use the Cargo.toml from the petgraph crate as an example (stripped):
[package]
name = "petgraph"
version = "0.6.0"
description = "Graph data structure library. Provides graph types and graph algorithms."
edition = "2018"
[dependencies]
fixedbitset = { version = "0.4.0", default-features = false }
indexmap = { version = "1.6.2" }
quickcheck = { optional = true, version = "0.8", default-features = false }
serde = { version = "1.0", optional = true }
serde_derive = { version = "1.0", optional = true }
[...]
[features]
default = ["graphmap", "stable_graph", "matrix_graph"]
graphmap = []
stable_graph = []
matrix_graph = []
serde-1 = ["serde", "serde_derive"]
[package.metadata.docs.rs]
features = ["serde-1", "quickcheck"]

Can cargo.toml contain custom properties

I've recently started with Rust and coming from a Node background I'm curious if the cargo.toml file for a project can be extended to include custom properties.
For example, in Node, some packages let you put configuration options in the package.json file (like babel):
{
"name": "my-package",
"version": "1.0.0",
"babel": {
"presets": [ ... ],
"plugins": [ ... ],
}
}
I've looked through the manifest docs but I can't seem to find anything about custom properties.
For example, what if I had a CLI tool and it has a configurable option. Do I have to have the user make a config file just for this option or could I include in the cargo.toml like so:
[package]
name = "my_project"
version = "0.1.0"
edition = "2018"
# custom property
store: ["one", "two", "three"]
[dependencies]
Also, if this is a "sure, as long as you have name and version as required", is it something that should be avoided?
The Rust equivalent would be Cargo features. You can define features for a crate like this in the crate's Cargo.toml:
[package]
name = "crate_with_features"
version = "1.0.0"
edition = "2018"
[features]
# default set of features
default = ["has_foo", "has_bar"]
# can use these for conditional compilation
has_foo = []
has_bar = []
And then if you had a lib.rs like this:
[cfg(feature = "has_foo")]
pub fn foo() {
println!("foo");
}
[cfg(feature = "has_bar")]
pub fn bar() {
println!("bar");
}
People would be able to select just which features of your crate they want. For example:
[package]
name = "other_project"
[dependencies]
crate_with_features = "1.0.0"
In the default case, crate_with_features would come with both foo and bar functions since the default feature requires both of them, but people could choose to only use one or the other by specifying:
[package]
name = "other_project"
[dependencies.crate_with_features]
version = "1.0.0"
# don't include default feature set
default-features = false
# cherry pick individual features
features = ["has_foo"]
In the above example crate_with_features would only be compiled with the foo function for that project.
The Rust Reference has a page on conditional compilation if you'd like to learn more about that specifically.

Can you test if the feature of a dependency is set using the `cfg!` macro?

I am trying to test if a feature of one of my dependencies has been set using the cfg! macro.
Below is an example:
my-lib/Cargo.toml
[package]
name = "my-lib"
version = "0.1.0"
edition = "2018"
[features]
some-feature = []
my-lib/lib.rs
pub fn some_function() {
if cfg!(feature = "some-feature") {
println!("SET");
} else {
println!("NOT SET");
}
}
my-bin/Cargo.toml
[package]
name = "my-bin"
version = "0.1.0"
edition = "2018"
[dependencies]
my-lib = { path = "../my-lib" }
my-bin/main.rs
use my_lib;
fn main() {
my_lib::some_function();
if cfg!(feature = "my-lib/some-feature") {
println!("is SET in bin");
} else {
println!("is NOT SET in bin");
}
}
Below shows the output given different run conditions. I would expect the second scenario to show is SET in bin.
> cargo run --features ""
NOT SET
is NOT SET in bin
> cargo run --features "my-lib/some-feature"
SET
is NOT SET in bin
A workaround is to add bin-some-feature = ["my-lib/some-feature"] to "my-bin/Cargo.toml" and change the check in "my-bin/main.rs" to cfg!(feature = "bin-some-feature"). This produces the desired output.
> cargo run --features "bin-some-feature"
SET
is SET in bin

How to stop recompiling an extern crate in Rust

I have a local dependency on some SDK. I make use of
extern crate local_sdk;
use local_sdk::foo;
to use the local_sdk in my implementation.
I am making use of cargo to build. While building, the logs print the following at some stage -
Compiling local_sdk v0.1.0 (file:///project/project-core/sdk/rust)
This happens even though I have already compiled the local_sdk earlier.
How do I prevent recompiling the local_sdk ? It consumes some significant time.
Contents of the my Cargo.toml:
[package]
name = "service"
version = "0.1.0"
authors = ["Rajeev"]
[dependencies]
local_sdk = { path = "../../sdk/rust" }
The local_sdk has the following Cargo.toml:
[package]
name = "local_sdk"
version = "0.1.0"
authors = ["Rajeev"]
[dependencies]
hex = "0.3"
protobuf="2.0"
rand = "0.4.2"
zmq = { git = "https://github.com/erickt/rust-zmq", branch = "release/v0.8" }
uuid = { version = "0.5", features = ["v4"] }
log = "0.3"
libc = "0.2"
ctrlc = { version = "3.0", features = ["termination"] }
[dev-dependencies]
env_logger = "0.3"
[build-dependencies]
cc = "1.0"
glob = "0.2"
Assuming you're using it, there was an issue with RLS that was causing unnecessary rebuilds.
This issue has been fixed, to get the latest version of RLS, use
$ rustup update

Resources