I am looking for a way to use a functional event-type mechanism in my project. Nothing is in production yet so this can even be rewritten from scratch (currently using Rocket).
I want to look for 2 things:
Option<T>
)I've done the latter but I have some issues with the first one. I am receiving JSON requests that look like this:
{
"source_id": "user:asdf",
"key": "temperature",
"value": 25
}
I've set up the following structs and enums:
use serde::Deserialize;
#[derive(Deserialize, Debug)]
pub struct EventPayload<T> {
pub key: String,
pub tag: Option<String>,
pub value: Option<T>,
}
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum EventValue {
String(EventPayload<String>),
Float(EventPayload<f32>),
Int(EventPayload<i32>),
Bool(EventPayload<bool>),
}
#[derive(Deserialize, Debug)]
pub struct PublishSingleValueEventRequest {
pub source_id: String,
#[serde(flatten)]
pub manifest: EventValue,
}
Problems appear when trying to access the values:
let event: PublishSingleValueEventRequest = ...;
/* This region does not compile
let evt_val: Option = match event.manifest {
EventValue::String(x) => x.value,
EventValue::Float(x) => x.value,
EventValue::Int(x) => x.value,
EventValue::Bool(x) => x.value
};
match evt_val {
Some(x) => println!("Event value: {:?}", x),
None => println!("No event value provided")
}
*/
println!("{:?}", event.manifest);
match event.manifest {
EventValue::String(x) => {
println!("String payload: {:?}", x.value);
}
EventValue::Float(x) => {
println!("Float payload: {:?}", x.value);
}
EventValue::Int(x) => {
println!("Int payload: {:?}", x.value);
}
EventValue::Bool(x) => {
println!("Bool payload: {:?}", x.value);
}
}
I would like this to be more like:
match event.manifest.value {
Some(x) => ...,
None => ...
}
instead of manually unwrapping the .value
Option<>
fields.
You can pattern match nested structurues:
fn main() {
let payload: EventPayload<i32> = EventPayload {
key: "foo".to_string(),
tag: None,
value: Some(10),
};
let value = EventValue::Int(payload);
match value {
EventValue::Int(EventPayload {value: Some(x), ..}) => {
println!("Some value: {}", x);
}
EventValue::String(EventPayload {value: Some(message), ..}) => {
println!("Some message: {}", message);
}
_ => {
println!("whatever");
}
}
}