60 lines
1.7 KiB
Rust
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;
|
|
}
|
|
}
|