use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::error::TrustTaskCode;
use crate::type_uri::TypeUri;
pub trait Payload: Serialize + DeserializeOwned {
const TYPE_URI: &'static str;
const IS_BEARER: bool = false;
const IS_PROOF_REQUIRED: bool = false;
fn type_uri() -> TypeUri {
Self::TYPE_URI
.parse()
.expect("TYPE_URI constant must be a valid Type URI")
}
fn extended_code(local: impl Into<String>) -> TrustTaskCode {
let slug = Self::type_uri().slug().to_string();
let local = local.into();
TrustTaskCode::new_extended(&slug, &local).unwrap_or_else(|e| {
panic!(
"Payload::extended_code({:?}) on slug {:?} failed validation: {e}",
local, slug
)
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::specs::acl::change_role::v0_1 as change_role;
use crate::specs::acl::grant::v0_1 as grant;
use crate::specs::trust_task_discovery::v0_1 as discovery;
#[test]
fn extended_code_sources_slug_from_type_uri() {
let code = grant::Payload::extended_code("role_not_recognized");
match code {
TrustTaskCode::Extended { slug, local } => {
assert_eq!(slug, "acl/grant");
assert_eq!(local, "role_not_recognized");
}
other => panic!("expected Extended, got {other:?}"),
}
let code = change_role::Payload::extended_code("last_authority_protected");
assert_eq!(code.to_string(), "acl/change-role:last_authority_protected");
}
#[test]
fn extended_code_works_for_single_segment_slug() {
let code = discovery::Payload::extended_code("filter_unsupported");
assert_eq!(code.to_string(), "trust-task-discovery:filter_unsupported");
}
#[test]
#[should_panic(expected = "failed validation")]
fn extended_code_panics_on_invalid_local() {
let _ = grant::Payload::extended_code("BadLocal");
}
#[test]
fn extended_code_strips_response_fragment_from_slug() {
let code = grant::Response::extended_code("role_not_recognized");
match code {
TrustTaskCode::Extended { slug, .. } => {
assert_eq!(slug, "acl/grant", "response variant must yield bare slug");
}
other => panic!("expected Extended, got {other:?}"),
}
}
}