use glib::GString;
use ostree::glib;
pub trait KeyFileExt {
fn optional_string(&self, group: &str, key: &str) -> Result<Option<GString>, glib::Error>;
fn optional_bool(&self, group: &str, key: &str) -> Result<Option<bool>, glib::Error>;
fn optional_string_list(
&self,
group: &str,
key: &str,
) -> Result<Option<Vec<GString>>, glib::Error>;
}
pub fn map_keyfile_optional<T>(res: Result<T, glib::Error>) -> Result<Option<T>, glib::Error> {
match res {
Ok(v) => Ok(Some(v)),
Err(e) => {
if let Some(t) = e.kind::<glib::KeyFileError>() {
match t {
glib::KeyFileError::GroupNotFound | glib::KeyFileError::KeyNotFound => Ok(None),
_ => Err(e),
}
} else {
Err(e)
}
}
}
}
impl KeyFileExt for glib::KeyFile {
fn optional_string(&self, group: &str, key: &str) -> Result<Option<GString>, glib::Error> {
map_keyfile_optional(self.string(group, key))
}
fn optional_bool(&self, group: &str, key: &str) -> Result<Option<bool>, glib::Error> {
map_keyfile_optional(self.boolean(group, key))
}
fn optional_string_list(
&self,
group: &str,
key: &str,
) -> Result<Option<Vec<GString>>, glib::Error> {
map_keyfile_optional(self.string_list(group, key))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_optional() {
let kf = glib::KeyFile::new();
assert_eq!(kf.optional_string("foo", "bar").unwrap(), None);
kf.set_string("foo", "baz", "someval");
assert_eq!(kf.optional_string("foo", "bar").unwrap(), None);
assert_eq!(
kf.optional_string("foo", "baz").unwrap().unwrap(),
"someval"
);
assert!(kf.optional_bool("foo", "baz").is_err());
assert_eq!(kf.optional_bool("foo", "bar").unwrap(), None);
kf.set_boolean("foo", "somebool", false);
assert_eq!(kf.optional_bool("foo", "somebool").unwrap(), Some(false));
assert_eq!(kf.optional_string_list("foo", "bar").unwrap(), None);
kf.set_string("foo", "somelist", "one;two;three");
assert_eq!(
kf.optional_string_list("foo", "somelist").unwrap(),
Some(
vec!["one", "two", "three"]
.iter()
.map(|&v| GString::from(v))
.collect()
)
);
}
}