use serde::{Deserialize, Serialize};
use vti_common::error::AppError;
use vti_common::store::KeyspaceHandle;
pub const JOIN_DISCOVERY_STORAGE_KEY: &[u8] = b"community/join-discovery";
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[derive(utoipa::ToSchema)]
pub struct JoinDiscovery {
#[serde(default = "yes")]
pub public: bool,
}
fn yes() -> bool {
true
}
impl Default for JoinDiscovery {
fn default() -> Self {
Self { public: true }
}
}
pub async fn load_join_discovery(ks: &KeyspaceHandle) -> Result<JoinDiscovery, AppError> {
match ks.get_raw(JOIN_DISCOVERY_STORAGE_KEY).await? {
Some(bytes) => serde_json::from_slice(&bytes)
.map_err(|e| AppError::Internal(format!("community join discovery decode: {e}"))),
None => Ok(JoinDiscovery::default()),
}
}
pub async fn store_join_discovery(
ks: &KeyspaceHandle,
setting: &JoinDiscovery,
) -> Result<JoinDiscovery, AppError> {
let key = String::from_utf8(JOIN_DISCOVERY_STORAGE_KEY.to_vec()).expect("key is ASCII");
ks.insert(key, setting).await?;
Ok(setting.clone())
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn a_community_that_never_chose_publishes() {
assert!(JoinDiscovery::default().public);
let absent: JoinDiscovery = serde_json::from_value(json!({})).expect("parse");
assert!(
absent.public,
"a stored row missing the member reads as answering"
);
}
#[test]
fn the_setting_travels_under_its_wire_name() {
let off: JoinDiscovery = serde_json::from_value(json!({ "public": false })).expect("parse");
assert!(!off.public);
assert_eq!(
serde_json::to_value(&off).expect("serialise"),
json!({ "public": false })
);
}
}