use serde::{Deserialize, Serialize};
use crate::tier::TrustTier;
use crate::Version;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Caps {
pub live: bool,
pub mime: Vec<String>,
pub side_channel: bool,
pub tiers: Vec<TrustTier>,
#[serde(rename = "v")]
pub version: Version,
}
const SUPPORTED_MIME: &[&str] = &[
"text/html",
"image/svg+xml",
"text/markdown",
"text/csv",
"image/png",
"image/jpeg",
"image/gif",
"application/json",
"text/plain",
];
impl Caps {
pub fn spaceterm_default() -> Self {
Self {
live: true,
mime: SUPPORTED_MIME.iter().map(|s| (*s).to_string()).collect(),
side_channel: true,
tiers: vec![
TrustTier::Trusted,
TrustTier::Restricted,
TrustTier::Isolated,
],
version: crate::PROTOCOL_VERSION,
}
}
pub fn to_json(&self) -> String {
serde_json::to_string(self).expect("Caps is always serializable")
}
}
#[cfg(test)]
mod tests {
use crate::PROTOCOL_VERSION;
use super::*;
#[test]
fn test_version_serializes_as_bare_v_field() {
let caps = Caps {
live: true,
mime: vec!["text/plain".to_string()],
side_channel: false,
tiers: vec![TrustTier::Restricted],
version: PROTOCOL_VERSION,
};
let json = serde_json::to_value(&caps).unwrap();
assert_eq!(json["v"], serde_json::json!(PROTOCOL_VERSION.0));
}
#[test]
fn test_spaceterm_default_has_supported_mime() {
let caps = Caps::spaceterm_default();
assert!(caps.mime.contains(&"text/html".to_string()));
assert!(caps.mime.contains(&"text/plain".to_string()));
assert!(caps.live);
assert!(caps.side_channel);
}
#[test]
fn test_spaceterm_default_serializes_to_json() {
let caps = Caps::spaceterm_default();
let json = caps.to_json();
assert!(json.contains("\"v\":1"), "{json}");
assert!(json.contains("text/html"), "{json}");
}
}