Skip to main content
added 531 characters in body
Source Link
Shepmaster
  • 439.3k
  • 116
  • 1.3k
  • 1.5k

Adding on to oli_obk's answer, you can use Serde's enum representation to distinguish between the types.

Here, I use the internally-tagged representation to deserialize these two similar objects into the appropriate variant:

{ "driver": "file", "path": "/var/log/foo" } 
{ "driver": "http", "port": 8080, "endpoint": "/api/bar" } 
use serde; // 1.0.82 use serde_derive::*; // 1.0.82 use serde_json; // 1.0.33 #[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File { path: String }, #[serde(rename = "http")] Http { port: u16, endpoint: String } } fn main() { let f = r#" { "driver": "file", "path": "/var/log/foo" } "#; let h = r#" { "driver": "http", "port": 8080, "endpoint": "/api/bar" } "#; let f: Driver = serde_json::from_str(f).unwrap(); assert_eq!(f, Driver::File { path: "/var/log/foo".into() }); let h: Driver = serde_json::from_str(h).unwrap(); assert_eq!(h, Driver::Http { port: 8080, endpoint: "/api/bar".into() }); } 

You don't have to squash it all into one enum, you can create separate types as well:

#[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File(File), #[serde(rename = "http")] Http(Http), } #[derive(Debug, Deserialize, PartialEq)] struct File { path: String, } #[derive(Debug, Deserialize, PartialEq)] struct Http { port: u16, endpoint: String, } 

Adding on to oli_obk's answer, you can use Serde's enum representation to distinguish between the types.

Here, I use the internally-tagged representation to deserialize these two similar objects into the appropriate variant:

{ "driver": "file", "path": "/var/log/foo" } 
{ "driver": "http", "port": 8080, "endpoint": "/api/bar" } 
use serde; // 1.0.82 use serde_derive::*; // 1.0.82 use serde_json; // 1.0.33 #[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File { path: String }, #[serde(rename = "http")] Http { port: u16, endpoint: String } } fn main() { let f = r#" { "driver": "file", "path": "/var/log/foo" } "#; let h = r#" { "driver": "http", "port": 8080, "endpoint": "/api/bar" } "#; let f: Driver = serde_json::from_str(f).unwrap(); assert_eq!(f, Driver::File { path: "/var/log/foo".into() }); let h: Driver = serde_json::from_str(h).unwrap(); assert_eq!(h, Driver::Http { port: 8080, endpoint: "/api/bar".into() }); } 

Adding on to oli_obk's answer, you can use Serde's enum representation to distinguish between the types.

Here, I use the internally-tagged representation to deserialize these two similar objects into the appropriate variant:

{ "driver": "file", "path": "/var/log/foo" } 
{ "driver": "http", "port": 8080, "endpoint": "/api/bar" } 
use serde; // 1.0.82 use serde_derive::*; // 1.0.82 use serde_json; // 1.0.33 #[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File { path: String }, #[serde(rename = "http")] Http { port: u16, endpoint: String } } fn main() { let f = r#" { "driver": "file", "path": "/var/log/foo" } "#; let h = r#" { "driver": "http", "port": 8080, "endpoint": "/api/bar" } "#; let f: Driver = serde_json::from_str(f).unwrap(); assert_eq!(f, Driver::File { path: "/var/log/foo".into() }); let h: Driver = serde_json::from_str(h).unwrap(); assert_eq!(h, Driver::Http { port: 8080, endpoint: "/api/bar".into() }); } 

You don't have to squash it all into one enum, you can create separate types as well:

#[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File(File), #[serde(rename = "http")] Http(Http), } #[derive(Debug, Deserialize, PartialEq)] struct File { path: String, } #[derive(Debug, Deserialize, PartialEq)] struct Http { port: u16, endpoint: String, } 
Source Link
Shepmaster
  • 439.3k
  • 116
  • 1.3k
  • 1.5k

Adding on to oli_obk's answer, you can use Serde's enum representation to distinguish between the types.

Here, I use the internally-tagged representation to deserialize these two similar objects into the appropriate variant:

{ "driver": "file", "path": "/var/log/foo" } 
{ "driver": "http", "port": 8080, "endpoint": "/api/bar" } 
use serde; // 1.0.82 use serde_derive::*; // 1.0.82 use serde_json; // 1.0.33 #[derive(Debug, Deserialize, PartialEq)] #[serde(tag = "driver")] enum Driver { #[serde(rename = "file")] File { path: String }, #[serde(rename = "http")] Http { port: u16, endpoint: String } } fn main() { let f = r#" { "driver": "file", "path": "/var/log/foo" } "#; let h = r#" { "driver": "http", "port": 8080, "endpoint": "/api/bar" } "#; let f: Driver = serde_json::from_str(f).unwrap(); assert_eq!(f, Driver::File { path: "/var/log/foo".into() }); let h: Driver = serde_json::from_str(h).unwrap(); assert_eq!(h, Driver::Http { port: 8080, endpoint: "/api/bar".into() }); }