Skip to main content

dnspls_provider/
lib.rs

1//! Provider capability vocabulary and adapter boundary.
2//!
3//! Raw provider payloads do not cross this boundary. Adapters translate them
4//! into typed `dnspls-core` observations before reduction.
5
6pub use dnspls_core::{
7    EvidenceFact, Observation, ProviderAuthority, ProviderOperation, ProviderStatus, SourceId,
8};
9
10/// Contract-qualified capability of one provider source.
11#[derive(Clone, Debug, Eq, PartialEq)]
12pub struct ProviderCapability {
13    source: SourceId,
14    authority: ProviderAuthority,
15    operations: Box<[ProviderOperation]>,
16}
17
18impl ProviderCapability {
19    pub fn new(
20        source: SourceId,
21        authority: ProviderAuthority,
22        operations: impl Into<Box<[ProviderOperation]>>,
23    ) -> Self {
24        Self {
25            source,
26            authority,
27            operations: operations.into(),
28        }
29    }
30
31    pub const fn source(&self) -> &SourceId {
32        &self.source
33    }
34
35    pub const fn authority(&self) -> ProviderAuthority {
36        self.authority
37    }
38
39    pub fn supports(&self, operation: ProviderOperation) -> bool {
40        self.operations.contains(&operation)
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn capability_is_explicit_per_operation() {
50        let capability = ProviderCapability::new(
51            SourceId::parse("registrar:test").unwrap(),
52            ProviderAuthority::RegistrationCapable,
53            [ProviderOperation::Availability],
54        );
55        assert!(capability.supports(ProviderOperation::Availability));
56        assert!(!capability.supports(ProviderOperation::Register));
57    }
58}