Files
k-os/crates/manifest/src/decision.rs

60 lines
1.7 KiB
Rust

//! 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;
}
}