oparl_types/
consultation.rs

1// SPDX-FileCopyrightText: Politik im Blick developers
2// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2
5
6use url::Url;
7
8use crate::{
9    namespace::ConsultationNamespaceUrl, AgendaItemId, ConsultationId, DateTime, Keyword,
10    MeetingId, OrganizationId, PaperId,
11};
12
13#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct Consultation {
16    pub id: ConsultationId,
17
18    #[serde(rename = "type")]
19    pub namespace: ConsultationNamespaceUrl,
20
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub paper: Option<PaperId>,
23
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub agenda_item: Option<AgendaItemId>,
26
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub meeting: Option<MeetingId>,
29
30    #[serde(default, skip_serializing_if = "Vec::is_empty")]
31    pub organization: Vec<OrganizationId>,
32
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub authoritative: Option<bool>,
35
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    pub role: Option<String>,
38
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub license: Option<Url>,
41
42    #[serde(default, skip_serializing_if = "Vec::is_empty")]
43    pub keyword: Vec<Keyword>,
44
45    pub created: DateTime,
46
47    pub modified: DateTime,
48
49    #[serde(default, skip_serializing_if = "Option::is_none")]
50    pub web: Option<Url>,
51
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub deleted: Option<bool>,
54}
55
56#[cfg(test)]
57mod serde_tests {
58    use super::Consultation;
59    use crate::namespace::ConsultationNamespaceUrl;
60
61    use pretty_assertions::assert_eq;
62    use serde_json::json;
63    use time::macros::datetime;
64
65    fn example_consultation() -> Consultation {
66        Consultation {
67            id: "https://oparl.example.org/consultation/47594"
68                .parse()
69                .expect("value must be parseable as id"),
70            namespace: ConsultationNamespaceUrl::Identifier,
71            paper: Some(
72                "https://oparl.example.org/paper/749"
73                    .parse()
74                    .expect("value must be parseable as url"),
75            ),
76            agenda_item: Some(
77                "https://oparl.example.org/agendaitem/15569"
78                    .parse()
79                    .expect("value must be parseable as url"),
80            ),
81            meeting: Some(
82                "https://oparl.example.org/meeting/243"
83                    .parse()
84                    .expect("value must be parseable as url"),
85            ),
86            organization: vec!["https://oparl.example.org/organization/96"
87                .parse()
88                .expect("value must be parseable as url")],
89            authoritative: Some(false),
90            role: Some("Beschlussfassung".into()),
91            license: None,
92            keyword: vec![],
93            created: datetime!(2012-01-08 14:05:27 +01:00).into(),
94            modified: datetime!(2012-01-08 14:05:27 +01:00).into(),
95            web: None,
96            deleted: None,
97        }
98    }
99
100    fn example_consultation_json() -> serde_json::Value {
101        json!({
102            "id": "https://oparl.example.org/consultation/47594",
103            "type": "https://schema.oparl.org/1.1/Consultation",
104            "paper": "https://oparl.example.org/paper/749",
105            "agendaItem": "https://oparl.example.org/agendaitem/15569",
106            "meeting": "https://oparl.example.org/meeting/243",
107            "organization": [
108                "https://oparl.example.org/organization/96"
109            ],
110            "authoritative": false,
111            "role": "Beschlussfassung",
112            "created": "2012-01-08T14:05:27+01:00",
113            "modified": "2012-01-08T14:05:27+01:00"
114        })
115    }
116
117    #[test]
118    fn serialize() {
119        assert_eq!(json!(example_consultation()), example_consultation_json());
120    }
121
122    #[test]
123    fn deserialize_good() {
124        let deserialized: Consultation = serde_json::from_value(example_consultation_json())
125            .expect("value must be deserializable as Consultation");
126        assert_eq!(deserialized, example_consultation());
127    }
128
129    #[test]
130    fn deserialize_bad() {
131        assert!(serde_json::from_value::<Consultation>(json!("xyzabcd")).is_err());
132        assert!(serde_json::from_value::<Consultation>(json!(true)).is_err());
133        assert!(serde_json::from_value::<Consultation>(json!(123)).is_err());
134    }
135}