oparl_types/
system.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::SystemNamespaceUrl, BodyListId, DateTime, EmailAddress, Name, OParlVersion, SystemId,
10};
11
12#[derive(
13    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
14)]
15#[serde(rename_all = "camelCase")]
16pub struct System {
17    pub id: SystemId,
18
19    #[serde(rename = "type")]
20    pub namespace: SystemNamespaceUrl,
21
22    pub oparl_version: OParlVersion,
23
24    #[serde(default, skip_serializing_if = "Vec::is_empty")]
25    pub other_oparl_versions: Vec<Url>,
26
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub license: Option<Url>,
29
30    pub body: BodyListId,
31
32    #[serde(default, skip_serializing_if = "Option::is_none")]
33    pub name: Option<Name>,
34
35    #[serde(default, skip_serializing_if = "Option::is_none")]
36    pub contact_email: Option<EmailAddress>,
37
38    #[serde(default, skip_serializing_if = "Option::is_none")]
39    pub contact_name: Option<Name>,
40
41    #[serde(default, skip_serializing_if = "Option::is_none")]
42    pub website: Option<Url>,
43
44    #[serde(default, skip_serializing_if = "Option::is_none")]
45    pub vendor: Option<Url>,
46
47    #[serde(default, skip_serializing_if = "Option::is_none")]
48    pub product: Option<Url>,
49
50    pub created: DateTime,
51
52    pub modified: DateTime,
53
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    pub web: Option<Url>,
56
57    #[serde(default, skip_serializing_if = "Option::is_none")]
58    pub deleted: Option<bool>,
59}
60
61#[cfg(test)]
62mod serde_tests {
63    use super::System;
64    use crate::{namespace::SystemNamespaceUrl, OParlVersion};
65
66    use pretty_assertions::assert_eq;
67    use serde_json::json;
68    use time::macros::datetime;
69
70    fn example_system() -> System {
71        System {
72            id: "https://oparl.example.org/"
73                .parse()
74                .expect("value must be parseable as id"),
75            namespace: SystemNamespaceUrl::Identifier,
76            oparl_version: OParlVersion::Version1_1,
77            other_oparl_versions: vec!["https://oparl2.example.org/"
78                .parse()
79                .expect("value must be parseable as url")],
80            license: None,
81            body: "https://oparl.example.org/bodies"
82                .parse()
83                .expect("value must be parseable as url"),
84            name: Some(
85                "Beispiel-System"
86                    .parse()
87                    .expect("value must be parseable as name"),
88            ),
89            contact_email: Some(
90                "info@example.org"
91                    .parse()
92                    .expect("value must be parseable as email"),
93            ),
94            contact_name: Some(
95                "Allgemeiner OParl Kontakt"
96                    .parse()
97                    .expect("value must be parseable as name"),
98            ),
99            website: Some(
100                "http://www.example.org/"
101                    .parse()
102                    .expect("value must be parseable as url"),
103            ),
104            vendor: Some(
105                "http://example-software.com/"
106                    .parse()
107                    .expect("value must be parseable as url"),
108            ),
109            product: Some(
110                "http://example-software.com/oparl-server/"
111                    .parse()
112                    .expect("value must be parseable as url"),
113            ),
114            created: datetime!(2011-11-11 11:11:00 +01:00).into(),
115            modified: datetime!(2012-11-11 11:11:00 +01:00).into(),
116            web: None,
117            deleted: None,
118        }
119    }
120
121    fn example_system_json() -> serde_json::Value {
122        json!({
123            "id": "https://oparl.example.org/",
124            "type": "https://schema.oparl.org/1.1/System",
125            "oparlVersion": "https://schema.oparl.org/1.1/",
126            "body": "https://oparl.example.org/bodies",
127            "name": "Beispiel-System",
128            "contactEmail": "info@example.org",
129            "contactName": "Allgemeiner OParl Kontakt",
130            "website": "http://www.example.org/",
131            "vendor": "http://example-software.com/",
132            "product": "http://example-software.com/oparl-server/",
133            "otherOparlVersions": [
134                "https://oparl2.example.org/"
135            ],
136            "created": "2011-11-11T11:11:00+01:00",
137            "modified": "2012-11-11T11:11:00+01:00"
138        })
139    }
140
141    #[test]
142    fn serialize() {
143        assert_eq!(json!(example_system()), example_system_json());
144    }
145
146    #[test]
147    fn deserialize_good() {
148        let deserialized: System = serde_json::from_value(example_system_json())
149            .expect("value must be deserializable as System");
150        assert_eq!(deserialized, example_system());
151    }
152
153    #[test]
154    fn deserialize_bad() {
155        assert!(serde_json::from_value::<System>(json!("xyzabcd")).is_err());
156        assert!(serde_json::from_value::<System>(json!(true)).is_err());
157        assert!(serde_json::from_value::<System>(json!(123)).is_err());
158    }
159}