Reputation: 155
I'm using config-rs crate. I want to set an array to a default value in my configuration. I want to use set_default() method from the crate that accepts an argument of type Value<Array
> https://docs.rs/config/latest/config/builder/struct.ConfigBuilder.html#method.set_default
I'm new to rust and having a hard time as to how I can quickly create a vector<Value
>
let default: Vec<ValueKind>= vec![1,2,3];// Errors
let default: Vec<Value>= vec![1,2,3]; // Errros
Upvotes: 1
Views: 1625
Reputation: 8934
If you want to create a Vec<T>
, the items have to be of type T
. Rust does not perform implicit conversions so you need to write a little more code to make this work. It won't even allow implicit conversions between primitive types (Ex: i32
to i64
).
For this, you can create a new Value
or ValueKind
by using From
. I know this can be done because the documentation states that ValueKind
implements From<i32>
. The same thing also applies to Value
, but it is much harder to spot when reading through the documentation.
// Same applies to `Value`.
let default: Vec<ValueKind> = vec![ValueKind::from(1), ValueKind::from(2), ValueKind::from(3)];
To make this easier, you also have a few other options. Into
is implemented automatically for all types implementing From
, we can replace the lengthy ValueKind::from(1)
with a shorter 1.into()
call.
let default: Vec<ValueKind> = vec![1.into(), 2.into(), 3.into()];
If you have a lot of values you could also choose to use an iterator to convert an array of values all in one go.
let default: Vec<ValueKind> = [1, 2, 3, 4, 5, 6, 7, 8, 9]
.into_iter()
.map(|x| ValueKind::from(x))
.collect();
That being said, I am somewhat surprised the crate authors did not give the option to use *. It is not too difficult to write a generic function which accepts any iterable type like a Vec<i32>
as-is (Though I have not checked the documentation on this since I do not know how it is used)Vec
, array, or a bunch of other things, and turn it into ValueKind
or Value
as it goes.
/// Takes some iterable value and turns it into a Vec<ValueKind>.
pub fn to_valuekind<A, T>(values: A) -> Vec<ValueKind>
where
A: IntoIterator<Item = T>,
ValueKind: From<T>,
{
values.into_iter().map(|x| ValueKind::from(x)).collect()
}
*Looks like it is a restriction on how set_default
functions. It accepts any Into<Value>
, but by doing so they can't also implement across IntoIterator
since it could theoretically cause a conflict if a type implemented both Into<Value>
and IntoIterator<T> where T: Into<Value>
.
Upvotes: 5