use crate::{
AgendaItemUrl, ConsultationUrl, DateTime, Keyword, MeetingUrl, OrganizationUrl, PaperUrl, Url,
namespace::ConsultationNamespaceUrl,
};
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Consultation {
pub id: ConsultationUrl,
#[serde(rename = "type")]
pub namespace: ConsultationNamespaceUrl,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub paper: Option<PaperUrl>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agenda_item: Option<AgendaItemUrl>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub meeting: Option<MeetingUrl>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub organization: Vec<OrganizationUrl>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authoritative: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub license: Option<Url>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub keyword: Vec<Keyword>,
pub created: DateTime,
pub modified: DateTime,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub web: Option<Url>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub deleted: Option<bool>,
#[serde(default, flatten)]
pub extensions: serde_json::Map<String, serde_json::Value>,
}
#[cfg(test)]
mod serde_tests {
use pretty_assertions::assert_eq;
use serde_json::json;
use time::macros::datetime;
use super::Consultation;
use crate::namespace::ConsultationNamespaceUrl;
fn example_consultation() -> Consultation {
Consultation {
id: "https://oparl.example.org/consultation/47594"
.parse()
.expect("value must be parseable as id"),
namespace: ConsultationNamespaceUrl::Identifier,
paper: Some(
"https://oparl.example.org/paper/749"
.parse()
.expect("value must be parseable as url"),
),
agenda_item: Some(
"https://oparl.example.org/agendaitem/15569"
.parse()
.expect("value must be parseable as url"),
),
meeting: Some(
"https://oparl.example.org/meeting/243"
.parse()
.expect("value must be parseable as url"),
),
organization: vec![
"https://oparl.example.org/organization/96"
.parse()
.expect("value must be parseable as url"),
],
authoritative: Some(false),
role: Some("Beschlussfassung".into()),
license: None,
keyword: vec![],
created: datetime!(2012-01-08 14:05:27 +01:00).into(),
modified: datetime!(2012-01-08 14:05:27 +01:00).into(),
web: None,
deleted: None,
extensions: serde_json::Map::new(),
}
}
fn example_consultation_json() -> serde_json::Value {
json!({
"id": "https://oparl.example.org/consultation/47594",
"type": "https://schema.oparl.org/1.1/Consultation",
"paper": "https://oparl.example.org/paper/749",
"agendaItem": "https://oparl.example.org/agendaitem/15569",
"meeting": "https://oparl.example.org/meeting/243",
"organization": [
"https://oparl.example.org/organization/96"
],
"authoritative": false,
"role": "Beschlussfassung",
"created": "2012-01-08T14:05:27+01:00",
"modified": "2012-01-08T14:05:27+01:00"
})
}
#[test]
fn serialize() {
assert_eq!(json!(example_consultation()), example_consultation_json());
}
#[test]
fn deserialize_good() {
let deserialized: Consultation = serde_json::from_value(example_consultation_json())
.expect("value must be deserializable as Consultation");
assert_eq!(deserialized, example_consultation());
}
#[test]
fn deserialize_bad() {
assert!(serde_json::from_value::<Consultation>(json!("xyzabcd")).is_err());
assert!(serde_json::from_value::<Consultation>(json!(true)).is_err());
assert!(serde_json::from_value::<Consultation>(json!(123)).is_err());
}
}