oparl_types/
legislative_term.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    date::Date, namespace::LegislativeTermNamespaceUrl, BodyId, DateTime, Keyword,
10    LegislativeTermId, Name,
11};
12
13#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct LegislativeTerm {
16    pub id: LegislativeTermId,
17
18    #[serde(rename = "type")]
19    pub namespace: LegislativeTermNamespaceUrl,
20
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub body: Option<BodyId>,
23
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub name: Option<Name>,
26
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub start_date: Option<Date>,
29
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub end_date: Option<Date>,
32
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub license: Option<Url>,
35
36    #[serde(default, skip_serializing_if = "Vec::is_empty")]
37    pub keyword: Vec<Keyword>,
38
39    pub created: DateTime,
40
41    pub modified: DateTime,
42
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub web: Option<Url>,
45
46    #[serde(default, skip_serializing_if = "Option::is_none")]
47    pub deleted: Option<bool>,
48}
49
50#[cfg(test)]
51mod serde_tests {
52    use super::LegislativeTerm;
53    use crate::namespace::LegislativeTermNamespaceUrl;
54
55    use pretty_assertions::assert_eq;
56    use serde_json::json;
57    use time::macros::{date, datetime};
58
59    fn example_legislative_term() -> LegislativeTerm {
60        LegislativeTerm {
61            id: "https://oparl.example.org/term/0"
62                .parse()
63                .expect("value must be parseable as id"),
64            namespace: LegislativeTermNamespaceUrl::Identifier,
65            body: None,
66            name: Some("Gemeinderat 2021-2025".into()),
67            start_date: Some(date!(2021 - 01 - 08).into()),
68            end_date: Some(date!(2025 - 01 - 07).into()),
69            license: None,
70            keyword: vec![],
71            created: datetime!(2014-01-08 14:28:31 +01:00).into(),
72            modified: datetime!(2014-01-08 14:28:31 +01:00).into(),
73            web: None,
74            deleted: None,
75        }
76    }
77
78    fn example_legislative_term_json() -> serde_json::Value {
79        json!({
80            "id": "https://oparl.example.org/term/0",
81            "type": "https://schema.oparl.org/1.1/LegislativeTerm",
82            "name": "Gemeinderat 2021-2025",
83            "startDate": "2021-01-08",
84            "endDate": "2025-01-07",
85            "created": "2014-01-08T14:28:31+01:00",
86            "modified": "2014-01-08T14:28:31+01:00",
87        })
88    }
89
90    #[test]
91    fn serialize() {
92        assert_eq!(
93            json!(example_legislative_term()),
94            example_legislative_term_json()
95        );
96    }
97
98    #[test]
99    fn deserialize_good() {
100        let deserialized: LegislativeTerm = serde_json::from_value(example_legislative_term_json())
101            .expect("value must be deserializable as LegislativeTerm");
102        assert_eq!(deserialized, example_legislative_term());
103    }
104
105    #[test]
106    fn deserialize_bad() {
107        assert!(serde_json::from_value::<LegislativeTerm>(json!("xyzabcd")).is_err());
108        assert!(serde_json::from_value::<LegislativeTerm>(json!(true)).is_err());
109        assert!(serde_json::from_value::<LegislativeTerm>(json!(123)).is_err());
110    }
111}