Compiler Unaware of Provided Methods of Trait - rust

I'm using the prost crate in a very "hello world" way, with a basic ProtoBuf file:
foo.proto
syntax = "proto3";
package foo;
message Foo {
string mystring = 1;
}
I can verify the types that prost produces at compile time by inspecting ./target/PROJECT/build/PROJECT-{some hash}/out/foo.rs:
foo.rs
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Foo {
#[prost(string, tag="1")]
pub mystring: ::prost::alloc::string::String,
}
See that the prost::Message trait gets derived? Its docs claim I have tons of functions at my disposal for this trait, but only the two required ones, encoded_len() and clear(), can be called without error. Any of the provided ones (those with default implementations) result in a cannot find function in this scope error.
main.rs
use prost::Message;
pub mod foo {
include!(concat!(env!("OUT_DIR"), "/foo.rs"));
}
fn main() {
let f = foo::Foo { mystring: "bar".to_string() };
let v = encode_to_vec(&f);
}
cargo run
error[E0425]: cannot find function `encode_to_vec` in this scope
|
| let v = encode_to_vec(&f);
| ^^^^^^^^^^^^^ not found in this scope
And, worryingly, this warning implies it's not even looking at the trait it needs to:
warning: unused import: prost::Message
(edit) For reference:
Cargo.toml
[package]
name = "testing"
version = "0.1.0"
edition = "2018"
[dependencies]
prost = { version = "0.7.0", features = ["std"] }
[build-dependencies]
prost-build = "0.7.0"

encode_to_vec is not a free function. You need to call it as one of
f.encode_to_vec()
foo::Foo::encode_to_vec(&f)
Message::encode_to_vec(&f)
<foo::Foo as Message>::encode_to_vec(&f)
The first method is the most normal, but the other ones may produce useful error messages when you get confused about what's going on.
[Edit:] Well, encode_to_vec was added in prost 0.8.0, so with 0.7.0, it won't be usable.

Related

How do I remove this compiler error for use_store with yewdux?

I am learning yewdux and have implemented the tutorial code for global state:
use yew::prelude::*;
use yewdux::prelude::*;
#[derive(Default, Clone, PartialEq, Eq, Store)]
struct State {
count: u32,
}
#[function_component]
fn App() -> Html {
let (state, dispatch) = use_store::<State>();
let onclick = dispatch.reduce_mut_callback(|state| state.count += 1);
html! {
<>
<p>{ state.count }</p>
<button {onclick}>{"+1"}</button>
</>
}
}
fn main() {
yew::Renderer::<App>::new().render();
}
However I am getting a compiler error for the line:
let (state, dispatch) = use_store::<State>();
The compiler error reads:
error[E0277]: the trait bound `impl yew::functional::hooks::Hook<Output = (Rc<State>, Dispatch<State>)>: Hook` is not satisfied
--> src/main.rs:11:29
|
11 | let (state, dispatch) = use_store::<State>();
| ---------^^^^^^^^^^^
| |
| the trait `Hook` is not implemented for `impl yew::functional::hooks::Hook<Output = (Rc<State>, Dispatch<State>)>`
| required by a bound introduced by this call
|
= help: the trait `Hook` is implemented for `BoxedHook<'_, T>`
My Cargo.toml file is:
[package]
name = "yewdux_tutorial"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
yew = { git = "https://github.com/yewstack/yew/", features = ["csr"] }
stdweb = "0.4.20"
yewdux = "0.9.0"
Please could someone help point me in the right direction for solving this compiler error.
I have searched online for this this answer and found this question Failed to follow yew tutorial on Mac m1 - use of undeclared type `Vec` (Also on a mac m1) and followed the answer to no success.
I also attempted to manually implement a default Store on the State struct but that also did not fix it.
Try to add yew crate this way:
[dependencies]
yew = { version = "0.20", features = ["csr"] }
yewdux = "0.9"
When we did not specify yew by its source, we actually refer to the one in the official crate registry. But if we specify yew by its git repository, we refer to the crate at the default branch if no branch specified. The two crates are not the same in the eye of the Rust compiler.
The crate yewdux in the official crate registry probably also relies on the yew that is in the official crate registry as well, so we need to refer to yew in the official crate registry.
The file Cargo.lock shows more details about crate dependencies. If source = "registry+https://github.com/rust-lang/crates.io-index", then the crate is from the official crate registry. If source = "git+https://github.com/yewstack/yew.git#c40bd0b456f9c80146c99d56bc0b441c88c3fefe", then the crate is from the repo specified and the code version is at the commit c40bd0b456f9c80146c99d56bc0b441c88c3fefe.
Reference: https://intendednull.github.io/yewdux/setup.html#stable-release

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,
}

The trait `std::convert::From<cli::Opts>` is not implemented

I try to create a simple application parsing command line arguments using clap library and converting them to a Config custom structure. I implemented From trait for my structure, however, when I try to call from function, I receive the following error:
the trait bound `minimal_example::Config: std::convert::From<cli::Opts>` is not satisfied
the following implementations were found:
<minimal_example::Config as std::convert::From<minimal_example::cli::Opts>>
required by `std::convert::From::from`
Here is the code:
main.rs:
mod cli;
use clap::Clap;
use minimal_example::Config;
fn main() {
println!("Hello, world!");
let opts = cli::Opts::parse();
let config = Config::from(opts);
}
cli.rs:
use clap::{Clap, crate_version};
/// This doc string acts as a help message when the user runs '--help'
/// as do all doc strings on fields
#[derive(Clap)]
#[clap(version = crate_version!(), author = "Yury")]
pub struct Opts {
/// Simple option
pub opt: String,
}
lib.rs:
mod cli;
pub struct Config {
pub opt: String,
}
impl From<cli::Opts> for Config {
fn from(opts: cli::Opts) -> Self {
Config {
opt: opts.opt,
}
}
}
cargo.toml:
[package]
name = "minimal_example"
version = "0.1.0"
authors = ["Yury"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = {version="3.0.0-beta.2", features=["wrap_help"]}
What am I doing wrong?
You have added mod cli to both lib.rs and main.rs.
They are different from the standpoint of each other.
Rust modules confusion when there is main.rs and lib.rs
may help in understanding that.
That's what the error says. It's satisfied for std::convert::From<minimal_example::cli::Opts> but not for std::convert::From<cli::Opts>.
A simple fix:
main.rs
mod cli;
use clap::Clap;
use minimal_example::Config;
impl From<cli::Opts> for Config {
fn from(opts: cli::Opts) -> Self {
Config {
opt: opts.opt,
}
}
}
fn main() {
println!("Hello, world!");
let opts = cli::Opts::parse();
let config = Config::from(opts);
}
Now std::convert::From<cli::Opts> is implemented for Config.
How you actually want to place all this depends on your package architecture.

Parsing yaml in Rust using serde_yaml

I am new to Rust. I am trying to parse yaml in Rust using serde_yaml, but can't make the code compile:
My Cargo.toml:
[package]
name = "apmdeps"
version = "0.1.0"
authors = ["Roger Rabbit"]
edition = "2018"
[dependencies]
git2 = "0.10"
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
I tried to adapt the code sample found on the serde_yaml website, to no avail:
use serde::{Deserialize, Serialize};
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Dependency {
url: String,
tag: String,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Project {
dependencies: Vec<Dependency>,
}
fn main() {
let s = "---\ndependencies:\n--url:http://test1\ntag:tag1\n--url:http://test2\ntag:tag2";
let project: Project = serde_yaml::from_str(&s);
}
I get the following error:
error[E0308]: mismatched types
--> src/main.rs:17:28
|
17 | let project: Project = serde_yaml::from_str(&s);
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `Project`, found enum `std::result::Result`
|
= note: expected type `Project`
found type `std::result::Result<_, serde_yaml::error::Error>`
Your problem is that serde_yaml::from_str(&s) does not return a Dependency struct directly as you expect, but a Result struct.
Result structs are rust's way of error handling. Results are either Ok(value) or an Err and you need to check which one it is. Typically in a match expression.
In your case the parsed dependency is wrapped in Ok(project) if parsing the string is successful.
I could get your code to compile with the following match expression:
let project_result : Result<Project, _> = serde_yaml::from_str(&s);
match project_result {
Ok(project) => println!("dependencies = {:?}", project),
Err(_) => println!("Error!")
}
The next problem however is that your string seemed not proper yaml, at least not as expected from serde, and I do get "Error!" from the program.
I changed your string to the following to get some useful output. I don't know if that is your intended yaml though.
let s = "---\ndependencies:\n - {url: http://test1, tag: tag1}\n - {url: http://test2, tag: tag2}\n";

How do I access exported functions inside a crate's "tests" directory?

How do I access my libraries exported functions inside the create's "tests" directory?
src/relations.rs:
#![crate_type = "lib"]
mod relations {
pub fn foo() {
println!("foo");
}
}
tests/test.rs:
use relations::foo;
#[test]
fn first() {
foo();
}
$ cargo test
Compiling relations v0.0.1 (file:///home/chris/github/relations)
/home/chris/github/relations/tests/test.rs:1:5: 1:14 error: unresolved import `relations::foo`. Maybe a missing `extern crate relations`?
/home/chris/github/relations/tests/test.rs:1 use relations::foo;
^~~~~~~~~
If I add the suggested extern crate relations, the error is:
/home/chris/github/relations/tests/test.rs:2:5: 2:19 error: unresolved import `relations::foo`. There is no `foo` in `relations`
/home/chris/github/relations/tests/test.rs:2 use relations::foo;
^~~~~~~~~~~~~~
I want to test my relations in this separate tests/test.rs file. How can I solve these use issues?
Your problem is that, first, mod relations is not public so it is not visible outside of the crate, and second, you don't import your crate in tests.
If you build your program with Cargo, then the crate name will be the one you defined in Cargo.toml. For example, if Cargo.toml looks like this:
[package]
name = "whatever"
authors = ["Chris"]
version = "0.0.1"
[lib]
name = "relations" # (1)
And src/lib.rs file contains this:
pub mod relations { // (2); note the pub modifier
pub fn foo() {
println!("foo");
}
}
Then you can write this in tests/test.rs:
extern crate relations; // corresponds to (1)
use relations::relations; // corresponds to (2)
#[test]
fn test() {
relations::foo();
}
The solution was to specify a crate_id at the top of src/relations.rs:
#![crate_id = "relations"]
#![crate_type = "lib"]
pub fn foo() {
println!("foo");
}
This seems to declare that all the contained code is part of a "relations" module, though I'm still not sure how this is different to the earlier mod block.

Resources