feat(manifest): app manifest + decision crate (strict TOML subset, checked newtypes, capability catalog); docs/apps.md spec
This commit is contained in:
59
crates/manifest/src/decision.rs
Normal file
59
crates/manifest/src/decision.rs
Normal file
@@ -0,0 +1,59 @@
|
||||
//! The owner's decision about one app: what it was granted.
|
||||
|
||||
use crate::Error;
|
||||
use crate::capability::{Capabilities, Capability};
|
||||
use crate::toml;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct Decision {
|
||||
pub granted: Capabilities,
|
||||
}
|
||||
|
||||
/// Longest decision file `write` produces: the header and every name.
|
||||
pub const MAX_TEXT: usize = 512;
|
||||
|
||||
impl Decision {
|
||||
pub fn parse(text: &str) -> Result<Self, Error> {
|
||||
let mut granted = None;
|
||||
toml::parse(text, |e| match (e.table, e.key) {
|
||||
("decision", "granted") if granted.is_none() => {
|
||||
granted = Some(crate::manifest::capabilities(e.value, e.line)?);
|
||||
Ok(())
|
||||
}
|
||||
("decision", "granted") => Err(Error::Duplicate { line: e.line }),
|
||||
_ => Err(Error::Unknown { line: e.line }),
|
||||
})?;
|
||||
Ok(Self {
|
||||
granted: granted.ok_or(Error::Missing("granted"))?,
|
||||
})
|
||||
}
|
||||
|
||||
/// The file this decision is stored as, in `out`; its length.
|
||||
pub fn write(&self, out: &mut [u8; MAX_TEXT]) -> usize {
|
||||
let mut w = Writer { out, len: 0 };
|
||||
w.put("[decision]\ngranted = [");
|
||||
for (i, c) in self.granted.iter().enumerate() {
|
||||
if i > 0 {
|
||||
w.put(", ");
|
||||
}
|
||||
w.put("\"");
|
||||
w.put(Capability::name(c));
|
||||
w.put("\"");
|
||||
}
|
||||
w.put("]\n");
|
||||
w.len
|
||||
}
|
||||
}
|
||||
|
||||
struct Writer<'a> {
|
||||
out: &'a mut [u8; MAX_TEXT],
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl Writer<'_> {
|
||||
fn put(&mut self, s: &str) {
|
||||
let end = (self.len + s.len()).min(MAX_TEXT);
|
||||
self.out[self.len..end].copy_from_slice(&s.as_bytes()[..end - self.len]);
|
||||
self.len = end;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user