1use cxx::UniquePtr;
4
5#[derive(Debug)]
10pub struct Config {}
11
12impl Default for Config {
18 fn default() -> Self { Self::new() }
23}
24impl Config {
26 pub fn new() -> Self {
31 init_config_system();
32 Self {}
33 }
34
35 pub fn new_clear() -> Self {
38 raw::clear_all();
39 Self::new()
40 }
41
42 pub fn reset(&self) {
47 self.clear_all();
48 init_config_system();
49 }
50
51 pub fn clear(&self, key: &str) { raw::clear(key.to_string()); }
56
57 pub fn clear_value(&self, key: &str, value: &str) {
60 raw::clear_value(key.to_string(), value.to_string());
61 }
62
63 pub fn clear_all(&self) { raw::clear_all(); }
68
69 pub fn dump(&self) -> String { raw::dump() }
71
72 pub fn find(&self, key: &str, default: &str) -> String {
76 raw::find(key.to_string(), default.to_string())
77 }
78
79 pub fn get(&self, key: &str) -> Option<String> {
81 let value = raw::find(key.to_string(), "".to_string());
82 if value.is_empty() {
83 return None;
84 }
85 Some(value)
86 }
87
88 pub fn file(&self, key: &str, default: &str) -> String {
99 raw::find_file(key.to_string(), default.to_string())
100 }
101
102 pub fn dir(&self, key: &str, default: &str) -> String {
112 raw::find_dir(key.to_string(), default.to_string())
113 }
114
115 pub fn bool(&self, key: &str, default: bool) -> bool {
117 raw::find_bool(key.to_string(), default)
118 }
119
120 pub fn int(&self, key: &str, default: i32) -> i32 { raw::find_int(key.to_string(), default) }
122
123 pub fn find_vector(&self, key: &str) -> Vec<String> { raw::find_vector(key.to_string()) }
127
128 pub fn get_architectures(&self) -> Vec<String> { raw::get_architectures() }
131
132 pub fn contains(&self, key: &str) -> bool { raw::exists(key.to_string()) }
134
135 pub fn set(&self, key: &str, value: &str) { raw::set(key.to_string(), value.to_string()) }
137
138 pub fn tree(&self, key: &str) -> Option<ConfigTree> {
139 let tree = unsafe { raw::tree(key.to_string()) };
140 if tree.end() {
141 return None;
142 }
143 Some(ConfigTree::new(tree))
144 }
145
146 pub fn root_tree(&self) -> Option<ConfigTree> {
147 let tree = unsafe { raw::root_tree() };
148 if tree.end() {
149 return None;
150 }
151 Some(ConfigTree::new(tree))
152 }
153
154 pub fn set_vector(&self, key: &str, values: &Vec<&str>) {
169 let mut vec_key = String::from(key);
170 if !vec_key.ends_with("::") {
171 vec_key.push_str("::");
172 }
173
174 for value in values {
175 raw::set(vec_key.to_string(), value.to_string());
176 }
177 }
178}
179
180pub struct ConfigTree {
181 pub ptr: UniquePtr<raw::ConfigTree>,
182}
183
184impl ConfigTree {
185 pub fn new(ptr: UniquePtr<raw::ConfigTree>) -> Self { ConfigTree { ptr } }
186
187 pub fn tag(&self) -> Option<String> {
188 let tag = self.ptr.tag();
189 if tag.is_empty() {
190 return None;
191 }
192 Some(tag)
193 }
194
195 pub fn full_tag(&self) -> Option<String> {
197 let tag = self.ptr.full_tag();
198 if tag.is_empty() {
199 return None;
200 }
201 Some(tag)
202 }
203
204 pub fn value(&self) -> Option<String> {
205 let value = self.ptr.value();
206 if value.is_empty() {
207 return None;
208 }
209 Some(value)
210 }
211
212 pub fn child(&self) -> Option<ConfigTree> {
213 let child = unsafe { self.ptr.child() };
214 if child.end() { None } else { Some(ConfigTree::new(child)) }
215 }
216
217 pub fn sibling(&self) -> Option<ConfigTree> {
218 let child = unsafe { self.ptr.raw_next() };
219 if child.end() { None } else { Some(ConfigTree::new(child)) }
220 }
221
222 pub fn parent(&self) -> Option<ConfigTree> {
223 let parent = unsafe { self.ptr.parent() };
224 if parent.end() { None } else { Some(ConfigTree::new(parent)) }
225 }
226
227 pub fn iter(&self) -> IterConfigTree {
228 IterConfigTree(unsafe { ConfigTree::new(self.ptr.unique()) })
229 }
230}
231
232impl IntoIterator for ConfigTree {
233 type IntoIter = IterConfigTree;
234 type Item = ConfigTree;
235
236 fn into_iter(self) -> Self::IntoIter { IterConfigTree(self) }
237}
238
239pub struct IterConfigTree(ConfigTree);
240
241impl Iterator for IterConfigTree {
242 type Item = ConfigTree;
243
244 fn next(&mut self) -> Option<Self::Item> {
245 if self.0.ptr.end() {
246 None
247 } else {
248 let ret = unsafe { self.0.ptr.unique() };
249 let next = unsafe { self.0.ptr.raw_next() };
250 self.0.ptr = next;
251 Some(ConfigTree::new(ret))
252 }
253 }
254}
255
256pub fn init_config_system() {
262 if !raw::exists("APT::Architecture".to_string()) {
263 raw::init_config();
264 }
265 raw::init_system();
266}
267
268#[cxx::bridge]
269pub(crate) mod raw {
270 unsafe extern "C++" {
271 include!("rust-apt/apt-pkg-c/configuration.h");
272
273 type ConfigTree;
274
275 pub fn init_system();
277
278 pub fn init_config();
280
281 pub fn dump() -> String;
283
284 pub fn find(key: String, default_value: String) -> String;
286
287 pub fn find_file(key: String, default_value: String) -> String;
289
290 pub fn find_dir(key: String, default_value: String) -> String;
292
293 pub fn find_bool(key: String, default_value: bool) -> bool;
295
296 pub fn find_int(key: String, default_value: i32) -> i32;
298
299 pub fn find_vector(key: String) -> Vec<String>;
301
302 pub fn get_architectures() -> Vec<String>;
305
306 pub fn set(key: String, value: String);
308
309 pub fn exists(key: String) -> bool;
311
312 pub fn clear(key: String);
317
318 pub fn clear_all();
320
321 pub fn clear_value(key: String, value: String);
324
325 unsafe fn tree(key: String) -> UniquePtr<ConfigTree>;
326 unsafe fn root_tree() -> UniquePtr<ConfigTree>;
327
328 pub fn end(self: &ConfigTree) -> bool;
329 unsafe fn raw_next(self: &ConfigTree) -> UniquePtr<ConfigTree>;
330 unsafe fn unique(self: &ConfigTree) -> UniquePtr<ConfigTree>;
331
332 unsafe fn parent(self: &ConfigTree) -> UniquePtr<ConfigTree>;
333 unsafe fn child(self: &ConfigTree) -> UniquePtr<ConfigTree>;
334 pub fn tag(self: &ConfigTree) -> String;
335 pub fn full_tag(self: &ConfigTree) -> String;
336 pub fn value(self: &ConfigTree) -> String;
337 }
338}