I'm trying to use the criterion crate to benchmark a function in my binary crate.
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::Rng;
use enigma::enigma::Enigma; // failed to resolve: use of undeclared crate or module `enigma` use of undeclared crate or module `enigma`rustcE0433
fn gen_rand_string(n: usize) -> String {
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let mut rng = rand::thread_rng();
(0..n)
.map(|_| {
let idx = rng.gen_range(0..CHARSET.len());
CHARSET[idx] as char
})
.collect()
}
// Lots of red squigglies because of imports
fn construct_enigma() -> Enigma {
let rotors: RotorConfig =
RotorConfig::try_from([(Rotors::I, 'A'), (Rotors::II, 'X'), (Rotors::IV, 'N')])
.unwrap();
let plugs = Plugs::try_from(vec![]).unwrap();
let plugboard: Plugboard = Plugboard::try_from(plugs).unwrap();
let reflector: Reflectors = Reflectors::B;
Enigma::new(rotors, plugboard, reflector)
}
fn criterion_benchmark(c:&mut Criterion){
let e = construct_enigma();
let s1000 = gen_rand_string(1000);
c.bench_function("ENC 1000", |b|b.iter(||))
}
Here's my cargo.toml
[package]
name = "enigma"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
anyhow = "1.0.65"
bimap = "0.6.2"
bruh_moment = "0.1.1"
itertools = "0.10.3"
log = "0.4.17"
rand = "0.8.5"
strum = "0.24.1"
strum_macros = "0.24.3"
thiserror = "1.0.37"
[dev-dependencies]
criterion = "0.4.0"
[[bench]]
name = "encode_string"
harness = false
by my understanding i should be importing my function using %mycratename%::foo::bar instead of crate::foo::bar but i'm getting an error saying that my crate can't be found. How do I get rust to recognize my local unpublished crate for criterion benchmarks?
Related
I am trying to use the standard casper demo project as generated by command "cargo casper my-project" but with some std::io. I want to read a value from the console and then write it to the casper network. The example comes with the #![no_std] define at the start. If I remove this then I get the error message:
error: duplicate lang item in crate casper_contract (which contract depends on): panic__impl.
This is my main.rs with the #![no_std] commented out to try to allow std::io to be used.
//#![no_std]
#![no_main]
#[cfg(not(target_arch = "wasm32"))]
compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");
// We need to explicitly import the std alloc crate and `alloc::string::String` as we're in a
// `no_std` environment.
extern crate alloc;
use alloc::string::String;
use casper_contract::{
contract_api::{runtime, storage},
unwrap_or_revert::UnwrapOrRevert,
};
use casper_types::{ApiError, Key};
const KEY_NAME: &str = "my-key-name";
const RUNTIME_ARG_NAME: &str = "message";
/// An error enum which can be converted to a `u16` so it can be returned as an `ApiError::User`.
#[repr(u16)]
enum Error {
KeyAlreadyExists = 0,
KeyMismatch = 1,
}
impl From<Error> for ApiError {
fn from(error: Error) -> Self {
ApiError::User(error as u16)
}
}
#[no_mangle]
pub extern "C" fn call() {
// The key shouldn't already exist in the named keys.
let missing_key = runtime::get_key(KEY_NAME);
if missing_key.is_some() {
runtime::revert(Error::KeyAlreadyExists);
}
// This contract expects a single runtime argument to be provided. The arg is named "message"
// and will be of type `String`.
let value: String = runtime::get_named_arg(RUNTIME_ARG_NAME);
let mut guess = String::new();
std::io::stdin()
.read_line(&mut guess)
.expect("Failed to read line");
// Store this value under a new unforgeable reference a.k.a `URef`.
let value_ref = storage::new_uref(value);
// Store the new `URef` as a named key with a name of `KEY_NAME`.
let key = Key::URef(value_ref);
runtime::put_key(KEY_NAME, key);
// The key should now be able to be retrieved. Note that if `get_key()` returns `None`, then
// `unwrap_or_revert()` will exit the process, returning `ApiError::None`.
let retrieved_key = runtime::get_key(KEY_NAME).unwrap_or_revert();
if retrieved_key != key {
runtime::revert(Error::KeyMismatch);
}
}
And this is my cargo.toml file:
[package]
name = "contract"
version = "0.1.0"
edition = "2018"
[dependencies]
casper-contract = "1.4.3"
casper-types = "1.4.6"
[[bin]]
name = "contract"
path = "src/main.rs"
bench = false
doctest = false
test = false
[profile.release]
codegen-units = 1
lto = true
What am I doing wrong?
I’m trying to write a client to communicate with my grpc server written with tonic using Rust, but I’m having trouble understanding where to define and connect to the client, thus getting errors with my import statement. I’ve followed several tutorials and am having trouble finding information on how to create and import a client. My error is:
error[E0432]: unresolved import `user::client`
--> user/src/client.rs:2:36
|
2 | use user::client::{UserClient};
| ^^^^^^ could not find `client` in `user`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0432`.
error: could not compile `user`
In my proto.rs file:
syntax = "proto3";
package user;
message CreateUser {
string name = 1;
}
[package]
name = "user"
version = "0.1.0"
edition = "2018"
[lib]
[[bin]]
name = "server"
path = "src/server.rs"
[[bin]]
name = "client"
path = "src/client.rs"
[dependencies]
tonic = "0.5"
prost = "0.8"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
[build-dependencies]
tonic-build = "0.5"
My lib.rs file:
pub mod user {
tonic::include_proto!("user");
}
pub mod server;
pub mod client{
tonic::include_proto!("user");
}
main.rs:
use user::server;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing::info!(message = "Started user server");
server::start_server().await?;
Ok(())
}
client.rs:
use user::{UserRequest };
use user::client::{UserClient}; // what should this import be, where does the client et created?
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut client = UserClient::connect("http://[::1]:50051").await?; // how do I create UserClient
let request = tonic::Request::new(UserRequest {
id: "1".into(),
});
println!("Sending request to gRPC Server...");
let response = client.create_user(request).await?;
println!("RESPONSE={:?}", response);
Ok(())
}
For reference, I’m following:
https://tjtelan.com/blog/lets-build-a-single-binary-grpc-server-client-with-rust-in-2020/
https://blog.logrocket.com/rust-and-grpc-a-complete-guide/
https://dev.to/anshulgoyal15/a-beginners-guide-to-grpc-with-rust-3c7o
Why is the document object unknown. In fact, everything, even the window.document call is not linted. Linting is quite important for me to lean a new programming language/library.
lib.rs
use wasm_bindgen::prelude::*;
#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
let window = web_sys::window().expect("could not get window handle");
let document = window.document().expect("could not get document handle");
let body = document.body().expect("could not get body handle");
let val = document.create_element("p")?;
val.set_text_content(Some("Hello from rust"));
body.append_child(&val)?;
Ok(())
}
cargo.toml
[lib]
crate-type = ["cdylib"]
[dependencies]
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
[dependencies.web-sys]
version = "0.3.53"
features = [
"Document",
"Element",
"HtmlElement",
"Node",
"Window",
]
I'm trying to use the setup as outlined in the serde_with docs here to deserialize nested json into my struct: https://docs.rs/serde_with/1.4.0/serde_with/json/nested/index.html
After a few tries Cargo.toml file looks like:
[dependencies]
serde = { version = "1.0", features = ["derive"] }
//serde_with = { version = "1.4.0", features = ["..."] } // this doesn't work even though that's what the serde_with README calls for
serde_with = { version = "1.4.0", optional = true }
serde_json = "1.0"
Trying the above I get an error such as:
#[serde(default, rename(deserialize = "Plan"), with="serde_with::json::nested")]
^^^^^^^^^^^^^^^^^^^^^^^^^^ use of undeclared type or module `serde_with`
What am I doing wrong?
In your example the module serde_with is not optional and must provide the feature json.
Replace
serde_with = { version = "1.4.0", optional = true}
with
serde_with = { version = "1.4.0", features = ["json"]}
Full example:
Cargo.toml
[dependencies]
serde = { version = "1.0" }
serde_json = "1.0"
serde_derive = "1.0"
serde_with = { version = "1.4.0", features = ["json"]}
main.rs
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Serialize)]
struct A {
#[serde(with = "serde_with::json::nested")]
other_struct: B,
}
#[derive(Deserialize, Serialize)]
struct B {
value: usize,
}
fn main() {
let v: A = serde_json::from_str(r#"{"other_struct":"{\"value\":5}"}"#).unwrap();
assert_eq!(5, v.other_struct.value);
let x = A {
other_struct: B { value: 10 },
};
assert_eq!(r#"{"other_struct":"{\"value\":10}"}"#, serde_json::to_string(&x).unwrap());
}
reqwest v0.9 has serde v1.0 as a dependency and as a result implements converting serde_json errors into reqwest error.
In my code, I am doing some deserialization using serde_json instead of using .json() method that comes with reqwest.
// reqwest = "0.9"
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
pub fn get_meta(client: &reqwest::Client) -> Result<Meta, reqwest::Error> {
let mut resp = client
.get("http://localhost:8080/requests/playlist.json")
.send()?;
let data: Value = serde_json::from_str(&resp.text()?).unwrap();
let data = data["children"][0]["children"].clone();
let metas: Vec<Meta> = serde_json::from_value(data).unwrap();
let meta: Meta = metas.last().expect("nothing is playing").clone();
Ok(meta)
}
Currently, I am trying to return serde_json errors as reqwest errors. Changing let metas: Vec<Meta> = serde_json::from_value(data).unwrap(); to let metas: Vec<Meta> = serde_json::from_value(data)?; fails with the following error:
the trait `std::convert::From<serde_json::error::Error>` is not implemented for `reqwest::error::Error`
Is it possible to convert serde_json::error::Error to reqwest::error::Error by wrapping it inside Kind::Json error enum of reqwest, or do I have to make a custom error enum that encompasses both as mentioned in this article?
No, you can't construct reqwest::Error value yourself because it:
has non-public fields
does not expose public constructors
does not have From implementations for public types
Fortunately both reqwest::Error and serde_json::error::Error implement std::error::Error trait. Following the recommendation from the blog post you linked, the anyhow crate is very helpful here:
// reqwest = "0.9"
// serde = { version = "1.0", features = ["derive"] }
// serde_json = "1.0"
// anyhow = "1.0"
pub fn get_meta(client: &reqwest::Client) -> Result<Meta, anyhow::Error> {
let mut resp = client
.get("http://localhost:8080/requests/playlist.json")
.send()?;
let data: Value = serde_json::from_str(&resp.text()?).unwrap();
let data = data["children"][0]["children"].clone();
let metas: Vec<Meta> = serde_json::from_value(data).unwrap();
let meta: Meta = metas.last().expect("nothing is playing").clone();
Ok(meta)
}