Skip to main content

compose_lens/model/
capability.rs

1//! Raw-preserving service capability declarations.
2
3use crate::source::SourceSpan;
4
5use super::Located;
6
7fn is_exact_candidate(value: &str) -> bool {
8    !value.is_empty() && !value.chars().any(char::is_whitespace)
9}
10
11/// One exact service capability name from `cap_add`.
12#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct CapabilityAddItem {
14    raw: Located<String>,
15}
16
17impl CapabilityAddItem {
18    pub(crate) const fn new(raw: Located<String>) -> Self {
19        Self { raw }
20    }
21
22    /// Returns the exact authored string value.
23    #[must_use]
24    pub fn value(&self) -> &str {
25        self.raw.value()
26    }
27
28    /// Returns the exact source span of this sequence item.
29    #[must_use]
30    pub const fn span(&self) -> SourceSpan {
31        self.raw.span()
32    }
33
34    /// Reports whether this value is a conservative future cross-format exact candidate.
35    ///
36    /// This classification is purely lexical: the value must be non-empty and contain no
37    /// whitespace. It does not normalize case or consult a capability whitelist or target.
38    #[must_use]
39    pub fn is_exact_candidate(&self) -> bool {
40        is_exact_candidate(self.value())
41    }
42}
43
44/// An explicitly authored `cap_add` sequence, including an explicit empty sequence.
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct CapabilityAdd {
47    span: SourceSpan,
48    items: Vec<CapabilityAddItem>,
49}
50
51impl CapabilityAdd {
52    pub(crate) const fn new(span: SourceSpan, items: Vec<CapabilityAddItem>) -> Self {
53        Self { span, items }
54    }
55
56    /// Returns the exact span of the authored sequence value.
57    #[must_use]
58    pub const fn span(&self) -> SourceSpan {
59        self.span
60    }
61
62    /// Returns items in authored order, including exact duplicates.
63    #[must_use]
64    pub fn items(&self) -> &[CapabilityAddItem] {
65        &self.items
66    }
67}
68
69/// One exact service capability name from `cap_drop`.
70#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct CapabilityDropItem {
72    raw: Located<String>,
73}
74
75impl CapabilityDropItem {
76    pub(crate) const fn new(raw: Located<String>) -> Self {
77        Self { raw }
78    }
79
80    /// Returns the exact authored string value.
81    #[must_use]
82    pub fn value(&self) -> &str {
83        self.raw.value()
84    }
85
86    /// Returns the exact source span of this sequence item.
87    #[must_use]
88    pub const fn span(&self) -> SourceSpan {
89        self.raw.span()
90    }
91
92    /// Reports whether this value is a conservative future cross-format exact candidate.
93    ///
94    /// This classification is purely lexical: the value must be non-empty and contain no
95    /// whitespace. It does not normalize case or consult a capability whitelist or target.
96    #[must_use]
97    pub fn is_exact_candidate(&self) -> bool {
98        is_exact_candidate(self.value())
99    }
100}
101
102/// An explicitly authored `cap_drop` sequence, including an explicit empty sequence.
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct CapabilityDrop {
105    span: SourceSpan,
106    items: Vec<CapabilityDropItem>,
107}
108
109impl CapabilityDrop {
110    pub(crate) const fn new(span: SourceSpan, items: Vec<CapabilityDropItem>) -> Self {
111        Self { span, items }
112    }
113
114    /// Returns the exact span of the authored sequence value.
115    #[must_use]
116    pub const fn span(&self) -> SourceSpan {
117        self.span
118    }
119
120    /// Returns items in authored order, including exact duplicates.
121    #[must_use]
122    pub fn items(&self) -> &[CapabilityDropItem] {
123        &self.items
124    }
125}