use cxx::UniquePtr;
#[derive(Debug)]
pub struct Config {}
impl Default for Config {
fn default() -> Self { Self::new() }
}
impl Config {
pub fn new() -> Self {
init_config_system();
Self {}
}
pub fn new_clear() -> Self {
raw::clear_all();
Self::new()
}
pub fn reset(&self) {
self.clear_all();
init_config_system();
}
pub fn clear(&self, key: &str) { raw::clear(key.to_string()); }
pub fn clear_value(&self, key: &str, value: &str) {
raw::clear_value(key.to_string(), value.to_string());
}
pub fn clear_all(&self) { raw::clear_all(); }
pub fn dump(&self) -> String { raw::dump() }
pub fn find(&self, key: &str, default: &str) -> String {
raw::find(key.to_string(), default.to_string())
}
pub fn get(&self, key: &str) -> Option<String> {
let value = raw::find(key.to_string(), "".to_string());
if value.is_empty() {
return None;
}
Some(value)
}
pub fn file(&self, key: &str, default: &str) -> String {
raw::find_file(key.to_string(), default.to_string())
}
pub fn dir(&self, key: &str, default: &str) -> String {
raw::find_dir(key.to_string(), default.to_string())
}
pub fn bool(&self, key: &str, default: bool) -> bool {
raw::find_bool(key.to_string(), default)
}
pub fn int(&self, key: &str, default: i32) -> i32 { raw::find_int(key.to_string(), default) }
pub fn find_vector(&self, key: &str) -> Vec<String> { raw::find_vector(key.to_string()) }
pub fn get_architectures(&self) -> Vec<String> { raw::get_architectures() }
pub fn contains(&self, key: &str) -> bool { raw::exists(key.to_string()) }
pub fn set(&self, key: &str, value: &str) { raw::set(key.to_string(), value.to_string()) }
pub fn tree(&self, key: &str) -> Option<ConfigTree> {
let tree = unsafe { raw::tree(key.to_string()) };
if tree.end() {
return None;
}
Some(ConfigTree::new(tree))
}
pub fn root_tree(&self) -> Option<ConfigTree> {
let tree = unsafe { raw::root_tree() };
if tree.end() {
return None;
}
Some(ConfigTree::new(tree))
}
pub fn set_vector(&self, key: &str, values: &Vec<&str>) {
let mut vec_key = String::from(key);
if !vec_key.ends_with("::") {
vec_key.push_str("::");
}
for value in values {
raw::set(vec_key.to_string(), value.to_string());
}
}
}
pub struct ConfigTree {
pub ptr: UniquePtr<raw::ConfigTree>,
}
impl ConfigTree {
pub fn new(ptr: UniquePtr<raw::ConfigTree>) -> Self { ConfigTree { ptr } }
pub fn tag(&self) -> Option<String> {
let tag = self.ptr.tag();
if tag.is_empty() {
return None;
}
Some(tag)
}
pub fn full_tag(&self) -> Option<String> {
let tag = self.ptr.full_tag();
if tag.is_empty() {
return None;
}
Some(tag)
}
pub fn value(&self) -> Option<String> {
let value = self.ptr.value();
if value.is_empty() {
return None;
}
Some(value)
}
pub fn child(&self) -> Option<ConfigTree> {
let child = unsafe { self.ptr.child() };
if child.end() { None } else { Some(ConfigTree::new(child)) }
}
pub fn sibling(&self) -> Option<ConfigTree> {
let child = unsafe { self.ptr.raw_next() };
if child.end() { None } else { Some(ConfigTree::new(child)) }
}
pub fn parent(&self) -> Option<ConfigTree> {
let parent = unsafe { self.ptr.parent() };
if parent.end() { None } else { Some(ConfigTree::new(parent)) }
}
pub fn iter(&self) -> IterConfigTree {
IterConfigTree(unsafe { ConfigTree::new(self.ptr.unique()) })
}
}
impl IntoIterator for ConfigTree {
type IntoIter = IterConfigTree;
type Item = ConfigTree;
fn into_iter(self) -> Self::IntoIter { IterConfigTree(self) }
}
pub struct IterConfigTree(ConfigTree);
impl Iterator for IterConfigTree {
type Item = ConfigTree;
fn next(&mut self) -> Option<Self::Item> {
if self.0.ptr.end() {
None
} else {
let ret = unsafe { self.0.ptr.unique() };
let next = unsafe { self.0.ptr.raw_next() };
self.0.ptr = next;
Some(ConfigTree::new(ret))
}
}
}
pub fn init_config_system() {
if !raw::exists("APT::Architecture".to_string()) {
raw::init_config();
}
raw::init_system();
}
#[cxx::bridge]
pub(crate) mod raw {
unsafe extern "C++" {
include!("rust-apt/apt-pkg-c/configuration.h");
type ConfigTree;
pub fn init_system();
pub fn init_config();
pub fn dump() -> String;
pub fn find(key: String, default_value: String) -> String;
pub fn find_file(key: String, default_value: String) -> String;
pub fn find_dir(key: String, default_value: String) -> String;
pub fn find_bool(key: String, default_value: bool) -> bool;
pub fn find_int(key: String, default_value: i32) -> i32;
pub fn find_vector(key: String) -> Vec<String>;
pub fn get_architectures() -> Vec<String>;
pub fn set(key: String, value: String);
pub fn exists(key: String) -> bool;
pub fn clear(key: String);
pub fn clear_all();
pub fn clear_value(key: String, value: String);
unsafe fn tree(key: String) -> UniquePtr<ConfigTree>;
unsafe fn root_tree() -> UniquePtr<ConfigTree>;
pub fn end(self: &ConfigTree) -> bool;
unsafe fn raw_next(self: &ConfigTree) -> UniquePtr<ConfigTree>;
unsafe fn unique(self: &ConfigTree) -> UniquePtr<ConfigTree>;
unsafe fn parent(self: &ConfigTree) -> UniquePtr<ConfigTree>;
unsafe fn child(self: &ConfigTree) -> UniquePtr<ConfigTree>;
pub fn tag(self: &ConfigTree) -> String;
pub fn full_tag(self: &ConfigTree) -> String;
pub fn value(self: &ConfigTree) -> String;
}
}