use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentRequestBody {
pub subject: Value,
pub scope: String,
pub challenge: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub display_hint: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context_hint: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentDecisionBody {
pub subject: Value,
pub effect: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub scope: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expires_at: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentRevokeBody {
pub subject: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentListBody {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub agent: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub platform: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub subject: Option<Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentApproverSetBody {
pub platform: String,
pub context: String,
pub approver: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub route: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub route_hint: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConsentApproverListBody {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub platform: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub context: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unfiltered_list_bodies_are_empty_objects() {
assert_eq!(
serde_json::to_value(ConsentListBody::default()).expect("serialises"),
serde_json::json!({})
);
assert_eq!(
serde_json::to_value(ConsentApproverListBody::default()).expect("serialises"),
serde_json::json!({})
);
}
#[test]
fn an_unset_hint_is_absent_from_a_request() {
let body = ConsentRequestBody {
subject: serde_json::json!({
"platform": "signal",
"conversationRef": "sig-1a2b3c4d",
"kind": "dm",
"agent": "did:key:z6MkAgent",
}),
scope: "converse".into(),
challenge: "Y2hhbGxlbmdlLW5vbmNlLTEyOA".into(),
display_hint: None,
context_hint: None,
};
let v = serde_json::to_value(&body).expect("serialises");
assert!(v.get("displayHint").is_none());
assert!(v.get("contextHint").is_none());
assert_eq!(v.as_object().expect("object").len(), 3);
}
#[test]
fn set_members_serialise_camel_case() {
let body = ConsentApproverSetBody {
platform: "signal".into(),
context: "openvtc".into(),
approver: "did:key:z6MkApprover".into(),
route: Some("push".into()),
route_hint: Some("apns".into()),
};
let v = serde_json::to_value(&body).expect("serialises");
assert_eq!(v.get("routeHint").and_then(Value::as_str), Some("apns"));
}
}