4

Is there a nice way to tentatively deserialize a JSON into different structs? Couldn't find anything in the docs and unfortunately the structs have "tag" to differentiate as in How to conditionally deserialize JSON to two different variants of an enum?

So far my approach has been like this:

use aws_lambda_events::event::{ firehose::KinesisFirehoseEvent, kinesis::KinesisEvent, kinesis_analytics::KinesisAnalyticsOutputDeliveryEvent, }; use lambda::{lambda, Context}; use serde_json::Value; type Error = Box<dyn std::error::Error + Send + Sync + 'static>; enum MultipleKinesisEvent { KinesisEvent(KinesisEvent), KinesisFirehoseEvent(KinesisFirehoseEvent), KinesisAnalyticsOutputDeliveryEvent(KinesisAnalyticsOutputDeliveryEvent), None, } #[lambda] #[tokio::main] async fn main(event: Value, _: Context) -> Result<String, Error> { let multi_kinesis_event = if let Ok(e) = serde_json::from_value::<KinesisEvent>(event.clone()) { MultipleKinesisEvent::KinesisEvent(e) } else if let Ok(e) = serde_json::from_value::<KinesisFirehoseEvent>(event.clone()) { MultipleKinesisEvent::KinesisFirehoseEvent(e) } else if let Ok(e) = serde_json::from_value::<KinesisAnalyticsOutputDeliveryEvent>(event) { MultipleKinesisEvent::KinesisAnalyticsOutputDeliveryEvent(e) } else { MultipleKinesisEvent::None }; // code below is just sample let s = match multi_kinesis_event { MultipleKinesisEvent::KinesisEvent(_) => "Kinesis Data Stream!", MultipleKinesisEvent::KinesisFirehoseEvent(_) => "Kinesis Firehose!", MultipleKinesisEvent::KinesisAnalyticsOutputDeliveryEvent(_) => "Kinesis Analytics!", MultipleKinesisEvent::None => "Not Kinesis!", }; Ok(s.to_owned()) } 

1 Answer 1

5

You should use the #untagged option.

use serde::{Serialize, Deserialize}; #[derive(Serialize, Deserialize, Debug)] struct KinesisFirehoseEvent { x: i32, y: i32 } #[derive(Serialize, Deserialize, Debug)] struct KinesisEvent(i32); #[derive(Serialize, Deserialize, Debug)] #[serde(untagged)] enum MultipleKinesisEvent { KinesisEvent(KinesisEvent), KinesisFirehoseEvent(KinesisFirehoseEvent), None, } fn main() { let event = MultipleKinesisEvent::KinesisFirehoseEvent(KinesisFirehoseEvent { x: 1, y: 2 }); // Convert the Event to a JSON string. let serialized = serde_json::to_string(&event).unwrap(); // Prints serialized = {"x":1,"y":2} println!("serialized = {}", serialized); // Convert the JSON string back to a MultipleKinesisEvent. // Since it is untagged let deserialized: MultipleKinesisEvent = serde_json::from_str(&serialized).unwrap(); // Prints deserialized = KinesisFirehoseEvent(KinesisFirehoseEvent { x: 1, y: 2 }) println!("deserialized = {:?}", deserialized); } 

See in playground

Docs for: Untagged

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot! There is always something awesome I missed in the docs :P

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.