use url::Url;
use crate::{
namespace::ConsultationNamespaceUrl, AgendaItemId, ConsultationId, DateTime, Keyword,
MeetingId, OrganizationId, PaperId,
};
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Consultation {
pub id: ConsultationId,
#[serde(rename = "type")]
pub namespace: ConsultationNamespaceUrl,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub paper: Option<PaperId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agenda_item: Option<AgendaItemId>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub meeting: Option<MeetingId>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub organization: Vec<OrganizationId>,
#[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>,
}
#[cfg(test)]
mod serde_tests {
use super::Consultation;
use crate::namespace::ConsultationNamespaceUrl;
use pretty_assertions::assert_eq;
use serde_json::json;
use time::macros::datetime;
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,
}
}
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());
}
}