verifyos_cli/parsers/
plist_reader.rs1use plist::Value;
2use std::path::Path;
3
4#[derive(Debug, thiserror::Error)]
5pub enum PlistError {
6 #[error("Plist Error: {0}")]
7 ParseError(#[from] plist::Error),
8 #[error("Not a dictionary")]
9 NotADictionary,
10}
11
12pub struct InfoPlist {
13 pub root: Value,
14}
15
16impl InfoPlist {
17 pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, PlistError> {
18 let value = Value::from_file(path)?;
19 if value.as_dictionary().is_none() {
20 return Err(PlistError::NotADictionary);
21 }
22 Ok(Self { root: value })
23 }
24
25 pub fn from_bytes(bytes: &[u8]) -> Result<Self, PlistError> {
26 let value = Value::from_reader(std::io::Cursor::new(bytes))?;
27 if value.as_dictionary().is_none() {
28 return Err(PlistError::NotADictionary);
29 }
30 Ok(Self { root: value })
31 }
32
33 pub fn get_string(&self, key: &str) -> Option<&str> {
34 self.root
35 .as_dictionary()
36 .and_then(|dict| dict.get(key))
37 .and_then(|v| v.as_string())
38 }
39
40 pub fn get_bool(&self, key: &str) -> Option<bool> {
41 self.root
42 .as_dictionary()
43 .and_then(|dict| dict.get(key))
44 .and_then(|v| v.as_boolean())
45 }
46
47 pub fn has_key(&self, key: &str) -> bool {
48 self.root
49 .as_dictionary()
50 .map(|dict| dict.contains_key(key))
51 .unwrap_or(false)
52 }
53}