Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[macro_use]
- extern crate serde_derive;
- extern crate serde;
- extern crate serde_json;
- use serde::de::{self, Deserialize, Deserializer};
- use serde_json::Value;
- #[derive(Debug)]
- enum ConnectRequest {
- Unspecified(UnspecifiedSecurity),
- Wpa2(Wpa2Security),
- }
- #[derive(Deserialize, Debug)]
- struct UnspecifiedSecurity {
- ssid: String,
- psk: Option<String>,
- }
- #[derive(Deserialize, Debug)]
- struct Wpa2Security {
- ssid: String,
- psk: String,
- }
- impl<'de> Deserialize<'de> for ConnectRequest {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- #[derive(Deserialize)]
- #[serde(field_identifier, rename_all = "lowercase")]
- enum Tag {
- Wpa2,
- Other(String),
- }
- let v = Value::deserialize(deserializer)?;
- match Option::deserialize(&v["security"]).map_err(de::Error::custom)? {
- Some(Tag::Wpa2) => {
- let inner = Wpa2Security::deserialize(v).map_err(de::Error::custom)?;
- Ok(ConnectRequest::Wpa2(inner))
- }
- None => {
- let inner = UnspecifiedSecurity::deserialize(v).map_err(de::Error::custom)?;
- Ok(ConnectRequest::Unspecified(inner))
- }
- Some(Tag::Other(other)) => {
- const VARIANTS: &[&str] = &["wpa2"];
- Err(de::Error::unknown_variant(&other, VARIANTS))
- }
- }
- }
- }
- fn main() {
- let present = r#"{"ssid": "foo", "psk": "bar", "security": "wpa2"}"#;
- println!("{:?}", serde_json::from_str::<ConnectRequest>(&present).unwrap());
- let missing = r#"{"ssid": "foo", "psk": "bar"}"#;
- println!("{:?}", serde_json::from_str::<ConnectRequest>(&missing).unwrap());
- let unknown = r#"{"ssid": "foo", "psk": "bar", "security": "unrecognized"}"#;
- println!("{}", serde_json::from_str::<ConnectRequest>(&unknown).unwrap_err());
- }
Add Comment
Please, Sign In to add comment