use crate::{
DateTime, Keyword, MembershipUrl, OrganizationUrl, PersonUrl, Url, date::Date,
namespace::MembershipNamespaceUrl,
};
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Membership {
pub id: MembershipUrl,
#[serde(rename = "type")]
pub namespace: MembershipNamespaceUrl,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub person: Option<PersonUrl>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub organization: Option<OrganizationUrl>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub voting_right: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub start_date: Option<Date>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub end_date: Option<Date>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub on_behalf_of: Option<OrganizationUrl>,
#[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>,
#[serde(default, flatten)]
pub extensions: serde_json::Map<String, serde_json::Value>,
}
#[cfg(test)]
mod serde_tests {
use pretty_assertions::assert_eq;
use serde_json::json;
use time::macros::{date, datetime};
use super::Membership;
use crate::namespace::MembershipNamespaceUrl;
fn example_membership() -> Membership {
Membership {
id: "https://oparl.example.org/memberships/385"
.parse()
.expect("value must be parseable as id"),
namespace: MembershipNamespaceUrl::Identifier,
person: Some(
"https://oparl.example.org/person/29"
.parse()
.expect("value must be parseable as url"),
),
organization: Some(
"https://oparl.example.org/organizations/5"
.parse()
.expect("value must be parseable as url"),
),
role: Some("Vorsitzende".into()),
voting_right: Some(true),
start_date: Some(date!(2013 - 12 - 03).into()),
end_date: None,
on_behalf_of: None,
license: None,
keyword: vec![],
created: datetime!(2011-11-11 11:11:00 +01:00).into(),
modified: datetime!(2012-08-16 14:05:27 +02:00).into(),
web: None,
deleted: None,
extensions: serde_json::Map::new(),
}
}
fn example_membership_json() -> serde_json::Value {
json!({
"id": "https://oparl.example.org/memberships/385",
"type": "https://schema.oparl.org/1.1/Membership",
"person": "https://oparl.example.org/person/29",
"organization": "https://oparl.example.org/organizations/5",
"role": "Vorsitzende",
"votingRight": true,
"startDate": "2013-12-03",
"created": "2011-11-11T11:11:00+01:00",
"modified": "2012-08-16T14:05:27+02:00"
})
}
#[test]
fn serialize() {
assert_eq!(json!(example_membership()), example_membership_json());
}
#[test]
fn deserialize_good() {
let deserialized: Membership = serde_json::from_value(example_membership_json())
.expect("value must be deserializable as Membership");
assert_eq!(deserialized, example_membership());
}
#[test]
fn deserialize_bad() {
assert!(serde_json::from_value::<Membership>(json!("xyzabcd")).is_err());
assert!(serde_json::from_value::<Membership>(json!(true)).is_err());
assert!(serde_json::from_value::<Membership>(json!(123)).is_err());
}
}