oparl_types/
membership.rs1use url::Url;
7
8use crate::{
9 date::Date, namespace::MembershipNamespaceUrl, DateTime, Keyword, MembershipId, OrganizationId,
10 PersonId,
11};
12
13#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct Membership {
16 pub id: MembershipId,
17
18 #[serde(rename = "type")]
19 pub namespace: MembershipNamespaceUrl,
20
21 #[serde(default, skip_serializing_if = "Option::is_none")]
22 pub person: Option<PersonId>,
23
24 #[serde(default, skip_serializing_if = "Option::is_none")]
25 pub organization: Option<OrganizationId>,
26
27 #[serde(default, skip_serializing_if = "Option::is_none")]
28 pub role: Option<String>,
29
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub voting_right: Option<bool>,
32
33 #[serde(default, skip_serializing_if = "Option::is_none")]
34 pub start_date: Option<Date>,
35
36 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub end_date: Option<Date>,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
40 pub on_behalf_of: Option<OrganizationId>,
41
42 #[serde(default, skip_serializing_if = "Option::is_none")]
43 pub license: Option<Url>,
44
45 #[serde(default, skip_serializing_if = "Vec::is_empty")]
46 pub keyword: Vec<Keyword>,
47
48 pub created: DateTime,
49
50 pub modified: DateTime,
51
52 #[serde(default, skip_serializing_if = "Option::is_none")]
53 pub web: Option<Url>,
54
55 #[serde(default, skip_serializing_if = "Option::is_none")]
56 pub deleted: Option<bool>,
57}
58
59#[cfg(test)]
60mod serde_tests {
61 use super::Membership;
62 use crate::namespace::MembershipNamespaceUrl;
63
64 use pretty_assertions::assert_eq;
65 use serde_json::json;
66 use time::macros::{date, datetime};
67
68 fn example_membership() -> Membership {
69 Membership {
70 id: "https://oparl.example.org/memberships/385"
71 .parse()
72 .expect("value must be parseable as id"),
73 namespace: MembershipNamespaceUrl::Identifier,
74 person: Some(
75 "https://oparl.example.org/person/29"
76 .parse()
77 .expect("value must be parseable as url"),
78 ),
79 organization: Some(
80 "https://oparl.example.org/organizations/5"
81 .parse()
82 .expect("value must be parseable as url"),
83 ),
84 role: Some("Vorsitzende".into()),
85 voting_right: Some(true),
86 start_date: Some(date!(2013 - 12 - 03).into()),
87 end_date: None,
88 on_behalf_of: None,
89 license: None,
90 keyword: vec![],
91 created: datetime!(2011-11-11 11:11:00 +01:00).into(),
92 modified: datetime!(2012-08-16 14:05:27 +02:00).into(),
93 web: None,
94 deleted: None,
95 }
96 }
97
98 fn example_membership_json() -> serde_json::Value {
99 json!({
100 "id": "https://oparl.example.org/memberships/385",
101 "type": "https://schema.oparl.org/1.1/Membership",
102 "person": "https://oparl.example.org/person/29",
103 "organization": "https://oparl.example.org/organizations/5",
104 "role": "Vorsitzende",
105 "votingRight": true,
106 "startDate": "2013-12-03",
107 "created": "2011-11-11T11:11:00+01:00",
108 "modified": "2012-08-16T14:05:27+02:00"
109 })
110 }
111
112 #[test]
113 fn serialize() {
114 assert_eq!(json!(example_membership()), example_membership_json());
115 }
116
117 #[test]
118 fn deserialize_good() {
119 let deserialized: Membership = serde_json::from_value(example_membership_json())
120 .expect("value must be deserializable as Membership");
121 assert_eq!(deserialized, example_membership());
122 }
123
124 #[test]
125 fn deserialize_bad() {
126 assert!(serde_json::from_value::<Membership>(json!("xyzabcd")).is_err());
127 assert!(serde_json::from_value::<Membership>(json!(true)).is_err());
128 assert!(serde_json::from_value::<Membership>(json!(123)).is_err());
129 }
130}