pub mod storage;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
pub use storage::{
DEFAULT_DEPARTURE_PREFERENCE, MEMBER_EXTENSIONS_MAX_BYTES, delete_member, get_member,
list_members, list_members_paginated, store_member,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Member {
pub did: String,
pub joined_at: DateTime<Utc>,
#[serde(default)]
pub status_list_index: Option<u32>,
#[serde(default)]
pub publish_consent: bool,
#[serde(default = "Disposition::default_preference")]
pub departure_preference: Disposition,
#[serde(default)]
pub current_vmc_id: Option<String>,
#[serde(default)]
pub current_role_vec_id: Option<String>,
#[serde(default)]
pub extensions: JsonValue,
#[serde(default)]
pub removed_at: Option<DateTime<Utc>>,
#[serde(default)]
pub personhood: bool,
#[serde(default)]
pub personhood_asserted_at: Option<DateTime<Utc>>,
}
impl Member {
pub fn fresh(did: impl Into<String>) -> Self {
Self {
did: did.into(),
joined_at: Utc::now(),
status_list_index: None,
publish_consent: false,
departure_preference: Disposition::default_preference(),
current_vmc_id: None,
current_role_vec_id: None,
extensions: JsonValue::Null,
removed_at: None,
personhood: false,
personhood_asserted_at: None,
}
}
pub fn is_removed(&self) -> bool {
self.removed_at.is_some()
}
pub fn tombstone(&mut self) {
self.publish_consent = false;
self.departure_preference = Disposition::default_preference();
self.current_vmc_id = None;
self.current_role_vec_id = None;
self.extensions = JsonValue::Null;
self.removed_at = Some(Utc::now());
self.personhood = false;
self.personhood_asserted_at = None;
}
pub fn mark_historical(&mut self) {
self.removed_at = Some(Utc::now());
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum Disposition {
Purge,
Tombstone,
Historical,
PolicyDefault,
}
impl Disposition {
fn default_preference() -> Self {
Disposition::PolicyDefault
}
pub fn resolve(self) -> Disposition {
match self {
Disposition::PolicyDefault => Disposition::Tombstone,
other => other,
}
}
}