rust_apt/
macros.rs

1#[macro_export]
2/// Macro to create the cache, optionally including local valid files.
3///
4/// This includes the following:
5/// - `*.deb` or `*.ddeb` files
6/// - `Packages` and `Sources` files from apt repositories. These files can be
7///   compressed.
8/// - `*.dsc` or `*.changes` files
9/// - A valid directory containing the file `./debian/control`
10///
11/// Here is an example of the two ways you can use this.
12///
13/// ```
14/// use rust_apt::new_cache;
15///
16/// let cache = new_cache!().unwrap();
17///
18/// println!("{}", cache.get("apt").unwrap().name());
19///
20/// // Any file that can be added to the cache
21/// let local_files = vec![
22///     "tests/files/cache/apt.deb",
23///     "tests/files/cache/Packages",
24/// ];
25///
26/// let cache = new_cache!(&local_files).unwrap();
27/// println!("{}", cache.get("apt").unwrap().get_version("5000:1.0.0").unwrap().version());
28/// ```
29///
30/// Returns [`Result<rust_apt::cache::Cache, rust_apt::error::AptErrors>`]
31macro_rules! new_cache {
32	() => {{
33		let files: Vec<String> = Vec::new();
34		$crate::cache::Cache::new(&files)
35	}};
36	($slice:expr) => {{ $crate::cache::Cache::new($slice) }};
37}
38
39/// Implements RawIter trait for raw apt iterators
40macro_rules! raw_iter {
41	($($ty:ty),*) => {$(
42		paste!(
43			#[doc = "Iterator Struct for [`" $ty "`]."]
44			pub struct [<Iter $ty>](UniquePtr<$ty>);
45
46			impl Iterator for [<Iter $ty>] {
47				type Item = UniquePtr<$ty>;
48
49				fn next(&mut self) -> Option<Self::Item> {
50					if self.0.end() {
51						None
52					} else {
53						let ptr = unsafe { self.0.unique() };
54						self.0.pin_mut().raw_next();
55						Some(ptr)
56					}
57				}
58			}
59
60			impl IntoRawIter for UniquePtr<$ty> {
61				type Item = [<Iter $ty>];
62
63				fn raw_iter(self) -> Self::Item { [<Iter $ty>](self) }
64
65				fn make_safe(self) -> Option<Self> { if self.end() { None } else { Some(self) } }
66
67				fn to_vec(self) -> Vec<Self> { self.raw_iter().collect() }
68			}
69		);
70	)*};
71}
72
73/// Generates the boiler plate for wrapper structs
74/// where we need to change a Result to an option.
75macro_rules! cxx_convert_result {
76	($wrapper:ident, $($(#[$meta:meta])* $method:ident ( $( $arg:ident : $arg_ty:ty ),* ) -> $ret:ty ),* $(,)? ) => {
77		impl<'a> $wrapper<'a> {
78			$(
79				$(#[$meta])*
80				pub fn $method(&self, $( $arg : $arg_ty ),* ) -> Option<$ret> {
81					self.ptr.$method($( $arg ),*).ok()
82				}
83			)*
84		}
85	};
86}
87
88macro_rules! impl_partial_eq {
89	($($wrapper:ident $(<$lt:lifetime>)?),* $(,)?) => {
90		$(
91			impl $(<$lt>)? PartialEq for $wrapper $(<$lt>)? {
92				fn eq(&self, other: &Self) -> bool { self.index() == other.index() }
93			}
94		)*
95	};
96}
97
98macro_rules! impl_hash_eq {
99	($($wrapper:ident $(<$lt:lifetime>)?),* $(,)?) => {
100		$(
101			impl $(<$lt>)? std::hash::Hash for $wrapper $(<$lt>)? {
102				fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.index().hash(state); }
103			}
104
105			impl $(<$lt>)? Eq for $wrapper $(<$lt>)? {}
106		)*
107	};
108}
109
110/// Implements deref for apt smart pointer structs.
111macro_rules! impl_deref {
112	($($wrapper:ident $(<$lt:lifetime>)? -> $target:ty),* $(,)?) => {
113		$(
114			impl $(<$lt>)? std::ops::Deref for $wrapper $(<$lt>)? {
115				type Target = $target;
116
117				#[inline]
118				fn deref(&self) -> &Self::Target {
119					&self.ptr
120				}
121			}
122		)*
123	};
124}