Rust config::builder::ConfigBuilder with static string source? - rust

I am using the Rust config crate and want to switch from loading configuration from a file at runtime to a static string created at compile time.
Right now, it works like this:
config::Config::builder().add_source(File::new("default.toml", FileFormat::Toml));
However when I try it with a static string, it does not:
static DEFAULT: &str = std::include_str!("./default.toml");
[...]
config::Config::builder().add_source(DEFAULT)
Error Message
error[E0277]: the trait bound `&str: Source` is not satisfied
--> src/config.rs:21:25
|
21 | .add_source(DEFAULT)
| ---------- ^^^^^^^ the trait `Source` is not implemented for `&str`
| |
| required by a bound introduced by this call
|
note: required by a bound in `ConfigBuilder::<DefaultState>::add_source`
--> /home/konrad/.cargo/registry/src/github.com-1ecc6299db9ec823/config-0.13.1/src/builder.rs:207:12
|
207 | T: Source + Send + Sync + 'static,
| ^^^^^^ required by this bound in `ConfigBuilder::<DefaultState>::add_source`
How can I read my config from a static string instead of a file?

Use File::from_str():
config::Config::builder().add_source(File::from_str(DEFAULT, FileFormat::Toml));

Related

implementing obj-rs example to glium

I am trying to load a model into glium, I am using crate obj-rs for this. My model works fine with this example. Unfortunately whenever I try to move code from the example to my project (which is basically code copied from here) I fail with an error:
error[E0277]: the trait bound `glium::Display: glium::backend::Facade` is not satisfied
--> src/main.rs:27:32
|
27 | let vb = obj.vertex_buffer(&display)?;
| ------------- ^^^^^^^^ the trait `glium::backend::Facade` is not implemented for `glium::Display`
| |
| required by a bound introduced by this call
|
= help: the trait `glium::backend::Facade` is implemented for `Rc<glium::context::Context>`
note: required by a bound in `obj::glium_support::<impl Obj<V, I>>::vertex_buffer`
--> /Users/user/project/obj-rs/src/lib.rs:309:33
|
309 | pub fn vertex_buffer<F: Facade>(
| ^^^^^^ required by this bound in `obj::glium_support::<impl Obj<V, I>>::vertex_buffer`
error[E0277]: the trait bound `glium::Display: glium::backend::Facade` is not satisfied
--> src/main.rs:28:31
|
28 | let ib = obj.index_buffer(&display)?;
| ------------ ^^^^^^^^ the trait `glium::backend::Facade` is not implemented for `glium::Display`
| |
| required by a bound introduced by this call
|
= help: the trait `glium::backend::Facade` is implemented for `Rc<glium::context::Context>`
note: required by a bound in `obj::glium_support::<impl Obj<V, I>>::index_buffer`
--> /Users/user/project/obj-rs/src/lib.rs:317:32
|
317 | pub fn index_buffer<F: Facade>(
| ^^^^^^ required by this bound in `obj::glium_support::<impl Obj<V, I>>::index_buffer`
I am new to rust so most of the time I don't know what I am doing. I find it really hard to simply make copied code work. I tried implementing Facade for Display but that didn't seem to make any difference, just more errors. Could you tell me what's wrong, or at least provide me with an example that works, I just want to add my own models to glium examples.
Here are the parts of code that I changed:
fn main() -> Result<(), Box<dyn std::error::Error>>{
#[allow(unused_imports)]
use glium::{glutin, Surface};
use obj::{load_obj, Obj};
use glium::glutin::dpi::LogicalSize;
let event_loop = glutin::event_loop::EventLoop::new();
let window = glutin::window::WindowBuilder::new()
.with_inner_size(LogicalSize::new(500.0, 400.0))
.with_title("obj-rs");
let context = glutin::ContextBuilder::new().with_depth_buffer(24);
let display = glium::Display::new(window, context, &event_loop)?;
let input = include_bytes!("model.obj");
let obj: Obj = load_obj(&input[..])?;
//two lines causing the problem
//let vb = obj.vertex_buffer(&display)?;
//let ib = obj.index_buffer(&display)?;
let positions = glium::VertexBuffer::new(&display, &teapot::VERTICES).unwrap();
..... rest is the same as in the glium example
One thing that I would like to differ from obj-rs example is not to use local source if you know what I mean. Basically something like this:
[dependencies]
glium = "*"
obj-rs = { version = "*", features = ["glium"] }

Error compiling dependency to a proc-macro when targeting wasm

I have a procedural macro I have implemented which depends on the proc-macro-error crate. My client project depends on this macro crate.
When I build for native, everything works perfectly, but when I build for wasm, I get a number of errors thrown from proc-macro-error:
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:33:38
|
33 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:49:53
|
49 | res.span_note(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:52:53
|
52 | res.span_help(span_range.collapse().unwrap(), msg)
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0599]: no method named `unwrap` found for struct `proc_macro2::Span` in the current scope
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/imp/delegate.rs:60:42
|
60 | let span = span_range.collapse().unwrap();
| ^^^^^^ method not found in `proc_macro2::Span`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:459:29
|
459 | gen_error().into()
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro::TokenStream: From<TokenStream2>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:464:34
|
464 | Ok(_) => gen_error().into(),
| ^^^^ the trait `From<TokenStream2>` is not implemented for `proc_macro::TokenStream`
|
= help: the trait `From<proc_macro::TokenTree>` is implemented for `proc_macro::TokenStream`
= note: required because of the requirements on the impl of `Into<proc_macro::TokenStream>` for `TokenStream2`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:549:37
|
549 | first: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
error[E0277]: the trait bound `proc_macro2::Span: From<proc_macro::Span>` is not satisfied
--> /Users/spencerkohan/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro-error-1.0.4/src/lib.rs:550:36
|
550 | last: self.clone().into(),
| ^^^^ the trait `From<proc_macro::Span>` is not implemented for `proc_macro2::Span`
|
= note: required because of the requirements on the impl of `Into<proc_macro2::Span>` for `proc_macro::Span`
It doesn't make sense to me why there should be an issue: this code is not actually compiled for wasm, it's only called inside the proc macro, which is used at compile time.
How can I solve this issue?

Impl Into<B> trait for all types which impl Into<A>

I wanted to implement a conversion trait that would cover all types supporting already existing conversion. I thought that this could be done in following way:
impl<T> Into<B> for T
where
T: Into<A>,
{
fn into(self) -> B {
let a: A = self.into();
B::CaseA(a)
}
}
However compiler throws a following error:
error[E0119]: conflicting implementations of trait `std::convert::Into<block::ItemContent>`
--> yrs\src\block.rs:945:1
|
945 | / impl<T> Into<B> for T
946 | | where
947 | | T: Into<A>,
948 | | {
... |
952 | | }
953 | | }
| |_^
|
= note: conflicting implementation in crate `core`:
- impl<T, U> Into<U> for T
where U: From<T>;
error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`B`)
--> yrs\src\block.rs:945:6
|
945 | impl<T> Into<B> for T
| ^ type parameter `T` must be covered by another type when it appears before the first local type (`B`)
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
= note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
Is it possible to achieve this? I'm looking for a way to automatically extend conversion for a new type for all instances, that support conversion to another existing type.
What you are trying to do can be achieved (as the error says) by covering T with a local type. The reason you cannot do it without that is because otherwise someone else could also do the same and the Rust won't be able to tell which impl to use. So you need a local wrapper type to keep the separation.
The complete reasoning behind this is referenced in the error explanation:
https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md
And https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html
hope this helps ;)
A

Why can't I pass a String from env::Args to Path::new?

Consider the following example:
use std::env;
use std::path::Path;
fn main() {
let args: Vec<_> = env::args().collect();
let out_path: String = args[2];
let _path = Path::new(out_path);
}
Here's the error I'm getting while compiling:
error[E0308]: mismatched types
--> main.rs:8:27
|
8 | let _path = Path::new(out_path);
| ^^^^^^^^
| |
| expected reference, found struct `std::string::String`
| help: consider borrowing here: `&out_path`
|
= note: expected type `&_`
found type `std::string::String`
Now if I follow compiler's suggestion, I get this:
error[E0507]: cannot move out of indexed content
--> main.rs:7:28
|
7 | let out_path: String = args[2];
| ^^^^^^^
| |
| cannot move out of indexed content
| help: consider using a reference instead: `&args[2]`
error: aborting due to previous error
Which, after applying the suggestion, leads me to the previous error:
error[E0308]: mismatched types
--> main.rs:7:28
|
7 | let out_path: String = &args[2];
| ^^^^^^^^
| |
| expected struct `std::string::String`, found reference
| help: consider removing the borrow: `args[2]`
|
= note: expected type `std::string::String`
found type `&std::string::String`
How can I understand the situation and solve the problem?
This was indeed an unfortunate sequence of suggestions (use a reference > remove that reference), but this was caused by the manual type ascription related to out_path.
You want a string slice, not an owned String:
let out_path: &str = &args[2];
This fits both the restriction of args (you can't move out of indexed content) and the requirements of Path::new, which requires a reference.
As for your comment, a clone() "fixes" the cannot move out of indexed content error because it doesn't require a move from the args vector - it copies an element from it instead. This fix is of course inferior to just borrowing it, which also works with Path::new.

Multithreaded application fails to compile with error-chain

I introduced error-chain into a previously working application. The error itself is clear, std::error::Error + 'static lacks an implementation of the trait std::marker::Send:
error[E0277]: the trait bound `std::error::Error + 'static: std::marker::Send` is not satisfied
--> src/main.rs:35:5
|
35 | / error_chain!{
36 | |
37 | | foreign_links {
38 | | Mqttc(::mqttc::Error);
... |
53 | | }
54 | | }
| |_____^ `std::error::Error + 'static` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `std::error::Error + 'static`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<std::error::Error + 'static>`
= note: required because it appears within the type `std::boxed::Box<std::error::Error + 'static>`
= note: required because it appears within the type `mqttc::netopt::Error`
= note: required because it appears within the type `mqttc::Error`
= note: required because it appears within the type `errors::ErrorKind`
= note: required because it appears within the type `errors::Error`
= note: required by `error_chain::ChainedError`
= note: this error originates in a macro outside of the current crate
I am not sure how to resolve this. Note that I am using the more up to date fork of mqttc/mqtt3 instead of the upstream crates.
mqttc::Error contains a mqttc::netopt::Error, which in turns contains a Box<std::error::Error> (which desugars to std::boxed::Box<std::error::Error + 'static>. std::error::Error here is a trait object. Because the Error trait doesn't have Send as a supertrait, implementations of Error are not required to implement Send. Therefore, Box<std::error::Error> doesn't implement Send because not all types T: std::error::Error implement Send.
This could be fixed by changing the mqttc::netopt::Error type to use Box<std::error::Error + Send> instead of Box<std::error::Error> (which would be a breaking change for the library).

Resources