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 => $iter:ident),* $(,)?) => {$(
42		#[doc = concat!("Iterator Struct for [`", stringify!($ty), "`].")]
43		pub struct $iter(UniquePtr<$ty>);
44
45		impl Iterator for $iter {
46			type Item = UniquePtr<$ty>;
47
48			fn next(&mut self) -> Option<Self::Item> {
49				if self.0.end() {
50					None
51				} else {
52					let ptr = unsafe { self.0.unique() };
53					self.0.pin_mut().raw_next();
54					Some(ptr)
55				}
56			}
57		}
58
59		impl IntoRawIter for UniquePtr<$ty> {
60			type Item = $iter;
61
62			fn raw_iter(self) -> Self::Item { $iter(self) }
63
64			fn make_safe(self) -> Option<Self> { if self.end() { None } else { Some(self) } }
65
66			fn to_vec(self) -> Vec<Self> { self.raw_iter().collect() }
67		}
68	)*};
69}
70
71/// Generates the boiler plate for wrapper structs
72/// where we need to change a Result to an option.
73macro_rules! cxx_convert_result {
74	($wrapper:ident, $($(#[$meta:meta])* $method:ident ( $( $arg:ident : $arg_ty:ty ),* ) -> $ret:ty ),* $(,)? ) => {
75		impl<'a> $wrapper<'a> {
76			$(
77				$(#[$meta])*
78				pub fn $method(&self, $( $arg : $arg_ty ),* ) -> Option<$ret> {
79					self.ptr.$method($( $arg ),*).ok()
80				}
81			)*
82		}
83	};
84}
85
86macro_rules! impl_partial_eq {
87	($($wrapper:ident $(<$lt:lifetime>)?),* $(,)?) => {
88		$(
89			impl $(<$lt>)? PartialEq for $wrapper $(<$lt>)? {
90				fn eq(&self, other: &Self) -> bool { self.index() == other.index() }
91			}
92		)*
93	};
94}
95
96macro_rules! impl_hash_eq {
97	($($wrapper:ident $(<$lt:lifetime>)?),* $(,)?) => {
98		$(
99			impl $(<$lt>)? std::hash::Hash for $wrapper $(<$lt>)? {
100				fn hash<H: std::hash::Hasher>(&self, state: &mut H) { self.index().hash(state); }
101			}
102
103			impl $(<$lt>)? Eq for $wrapper $(<$lt>)? {}
104		)*
105	};
106}
107
108/// Implements deref for apt smart pointer structs.
109macro_rules! impl_deref {
110	($($wrapper:ident $(<$lt:lifetime>)? -> $target:ty),* $(,)?) => {
111		$(
112			impl $(<$lt>)? std::ops::Deref for $wrapper $(<$lt>)? {
113				type Target = $target;
114
115				#[inline]
116				fn deref(&self) -> &Self::Target {
117					&self.ptr
118				}
119			}
120		)*
121	};
122}