Reputation: 2929
I've got an enum:
#[derive(PartialEq, Debug)]
pub enum EventValue {
Numeric(i32),
Bool(bool),
Text(String),
}
And it's used in a Vec
which is used in a HashMap:
type Events = Vec<Event>;
pub type Stream = HashMap<String, Events>;
and I've implemented the From
trait on it for i32
(and the other three types):
impl From<i32> for EventValue {
fn from(v: i32) -> Self {
EventValue::Numeric(v)
}
}
impl From<String> for EventValue {
fn from(v: String) -> Self {
EventValue::Text(v)
}
}
impl From<bool> for EventValue {
fn from(v: bool) -> Self {
EventValue::Bool(v)
}
}
but when I try to use it in a function:
let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
let amount: i32 = motion.value.into(); // <-- here is where I get the error
// .. do somthing with amount
}
I get this error:
the trait bound `i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not satisfied
--> src/game/system/entity/movement.rs:17:48
|
17 | let amount: i32 = motion.value.into();
| ^^^^ the trait `std::convert::From<prelude::game::entity::components::event_stream::EventValue>` is not implemented for `i32`
|
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
<i32 as std::convert::From<i16>>
<i32 as std::convert::From<i8>>
<i32 as std::convert::From<std::num::NonZeroI32>>
and 2 others
= note: required because of the requirements on the impl of `std::convert::Into<i32>` for `prelude::game::entity::components::event_stream::EventValue`
What have I missed?
Bonus:
It's possible to build a function that auto converts incoming values for you provided you implement From
like this:
impl Event {
pub fn new<V: Into<EventValue>>(message: String, value: V) -> Event {
Self {
message: message,
value: value.into(),
}
}
}
Is it possible to create a function that can do the same thing but for returning a value?
Upvotes: 1
Views: 1412
Reputation: 10434
The error says that From<EventValue>
isn't implemented for i32
, not that From<i32>
isn't implemented for EventValue
. With the fully qualified names, it's a little harder to read, but that's what
the trait bound
i32: std::convert::From<prelude::game::entity::components::event_stream::EventValue>
is not satisfied
is saying.
The problem is that you're going the wrong direction. You've implemented the conversion i32
-> EventValue
, but not EventValue
-> i32
, which is what your sample code is trying to do.
You'll probably want to match on the value instead and handle not only the Numeric
case, but also the Bool
and Text
cases.
let motions = event_stream.get_channel("motions"); // << return a Vec
for motion in motions.drain(0..) {
match motion.value {
Numeric(value) => {// handle `Numeric` case},
Bool(value) => {// handle `Bool` case},
Text(text) => {// handle `Text` case},
}
}
motion.value
could be any of those three variants, so you can't assume it'll always be convertible to i32
.
Upvotes: 5