If it doesn’t work, the problem is in (or related to) a part of the code you haven’t shared yet, be it the implementation of deserialize or a call-site.
Try to give more complete code examples, otherwise it’s impossible to help.
Also more complete error messages help. Try to provide either the complete out put of cargo check/cargo build or at least everything related to the error in question.
// This function doesn't need to be generic, works fine, used by below function
fn deserialize_to_number(val: &Value) -> Result<Box<dyn ToValue<i32>>, CustomError> { ...}
error[E0277]: a value of type `Vec<(Box<dyn ToValue<T>>, Box<dyn ToValue<T>>)>` cannot be built from an iterator over elements of type `(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>)`
--> src/main.rs:3057:14
|
3057 | .collect()
| ^^^^^^^ value of type `Vec<(Box<dyn ToValue<T>>, Box<dyn ToValue<T>>)>` cannot be built from `std::iter::Iterator<Item=(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>)>`
|
= help: the trait `FromIterator<(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>)>` is not implemented for `Vec<(Box<dyn ToValue<T>>, Box<dyn ToValue<T>>)>`
= note: required because of the requirements on the impl of `FromIterator<Result<(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>), CustomError>>` for `Result<Vec<(Box<dyn ToValue<T>>, Box<dyn ToValue<T>>)>, CustomError>`
help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement
|
2688 | impl Expression where Vec<(Box<dyn ToValue<T>>, Box<dyn ToValue<T>>)>: FromIterator<(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>)> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
To learn more, run the command again with --verbose.
Seems like the Box<dyn ToValue<i32>> from deserialize_to_number ends up in the Vec that deserialize is supposed to return.
I haven’t tried to really understand your code; maybe a generic function isn’t quite what you need here though? Or you’ll need to make deserialize_to_number generic, too? You could try to explain what deserialize does and how you (plan to) call it, including the information what you’re trying to achieve by making it generic.
Note that deserialize being generic would mean that the caller of deserialize gets to choose what T is (that’s why in the implementation of deserialize you cannot just turn a Box<dyn ToValue<i32>> into a Box<dyn ToValue<T>>; and that’s also why I’m asking about how you plan to call deserialize).
I could do without a generic function for now. But this exponentially increases the non generic functions I will have to keep around. deserialize_to_number() does not need to be generic.
deserialize() takes a serde_json::Value as input, this value needs to a JsonArray consisting of other JsonArrays, each of inner JsonArray contains two serde_json::Value, both of these values need to be deserialized with non generic helper functions like deserialize_to_number().
result returned by deserialize() will be directly put(after unwrap) into an enum Variant like the one below.
enum MatchExpression {
Expression(
(
Box<dyn ToValue<i32>>,
// result returned by `deserialize()` will be filled be in as second argument to this variant
Vec<(Box<dyn ToValue<i32>>, Box<dyn ToValue<i32>>)>,
Box<dyn ToValue<i32>>,
),
),