1use core::{
4 iter::{DoubleEndedIterator, FusedIterator},
5 num::ParseIntError,
6 str::Split,
7};
8use derive_more::{AsRef, Deref, Display};
9use parse_hex::ParseHex;
10
11macro_rules! impl_str {
12 ($container:ident) => {
13 impl<'a> $container<'a> {
14 pub fn new(text: &'a str) -> Self {
16 $container(text)
17 }
18
19 pub fn as_str(&self) -> &'a str {
21 &self.0.as_ref()
22 }
23 }
24 };
25}
26
27macro_rules! impl_hex {
28 ($container:ident, $size:literal) => {
29 impl<'a> $container<'a> {
30 pub fn u8_array(self) -> Option<[u8; $size]> {
32 let (invalid, array) = ParseHex::parse_hex(self.0);
33 invalid.is_empty().then_some(array)
34 }
35 }
36
37 impl<'a> ParseArray for $container<'a> {
38 type Array = [u8; $size];
39 type Error = ();
40 fn parse_array(&self) -> Result<Self::Array, Self::Error> {
41 self.u8_array().ok_or(())
42 }
43 }
44 };
45}
46
47macro_rules! impl_srcinfo_checksum {
48 ($container:ident, $size:literal) => {
49 impl<'a> $container<'a> {
50 pub fn u8_array(self) -> Option<SkipOrArray<$size>> {
52 if self.as_str() == "SKIP" {
53 return Some(SkipOrArray::Skip);
54 }
55 let (invalid, array) = ParseHex::parse_hex(self.0);
56 invalid.is_empty().then_some(SkipOrArray::Array(array))
57 }
58 }
59
60 impl<'a> ParseArray for $container<'a> {
61 type Array = SkipOrArray<$size>;
62 type Error = ();
63 fn parse_array(&self) -> Result<Self::Array, Self::Error> {
64 self.u8_array().ok_or(())
65 }
66 }
67 };
68}
69
70macro_rules! impl_num {
71 ($container:ident, $num:ty) => {
72 impl_str!($container);
73 impl<'a> $container<'a> {
74 pub fn parse(&self) -> Result<$num, ParseIntError> {
76 self.as_str().parse()
77 }
78 }
79 };
80}
81
82macro_rules! def_str_wrappers {
83 ($(
84 $(#[$attrs:meta])*
85 $name:ident;
86 )*) => {$(
87 $(#[$attrs])*
88 #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, AsRef, Deref)]
89 pub struct $name<'a>(pub &'a str);
90 impl_str!($name);
91 )*};
92}
93
94macro_rules! def_hex_wrappers {
95 ($(
96 $(#[$attrs:meta])*
97 $name:ident {
98 size = $size:literal;
99 }
100 )*) => {$(
101 $(#[$attrs])*
102 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
103 pub struct $name<'a>(pub &'a str);
104 impl_str!($name);
105 impl_hex!($name, $size);
106 )*};
107}
108
109macro_rules! def_srcinfo_checksum_wrappers {
110 ($(
111 $(#[$attrs:meta])*
112 $name:ident {
113 size = $size:literal;
114 }
115 )*) => {$(
116 $(#[$attrs])*
117 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
118 pub struct $name<'a>(pub &'a str);
119 impl_str!($name);
120 impl_srcinfo_checksum!($name, $size);
121 )*};
122}
123
124macro_rules! def_b64_wrappers {
125 ($(
126 $(#[$attrs:meta])*
127 $name:ident;
128 )*) => {$(
129 $(#[$attrs])*
130 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
131 pub struct $name<'a>(pub &'a str);
132 impl_str!($name);
133 )*};
134}
135
136macro_rules! def_num_wrappers {
137 ($(
138 $(#[$attrs:meta])*
139 $name:ident = $num:ty;
140 )*) => {$(
141 $(#[$attrs])*
142 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
143 pub struct $name<'a>(&'a str);
144 impl_num!($name, $num);
145 )*};
146}
147
148macro_rules! def_list_wrappers {
149 ($(
150 $(#[$container_attrs:meta])*
151 $container_name:ident {
152 $(#[$iter_attrs:meta])*
153 Iter = $iter_name:ident;
154 $(#[$item_attrs:meta])*
155 Item = $item_name:ident;
156 }
157 )*) => {$(
158 $(#[$container_attrs])*
159 #[derive(Debug, Clone, Copy)]
160 pub struct $container_name<'a>(&'a str);
161
162 impl<'a> $container_name<'a> {
163 pub fn new(text: &'a str) -> Self {
165 $container_name(text)
166 }
167
168 pub fn iter(&self) -> $iter_name<'_> {
170 self.into_iter()
171 }
172 }
173
174 impl<'a> IntoIterator for $container_name<'a> {
175 type IntoIter = $iter_name<'a>;
176 type Item = $item_name<'a>;
177 fn into_iter(self) -> Self::IntoIter {
178 $iter_name(self.0.split('\n'))
179 }
180 }
181
182 $(#[$iter_attrs])*
183 #[derive(Debug, Clone)]
184 pub struct $iter_name<'a>(Split<'a, char>);
185
186 impl<'a> Iterator for $iter_name<'a> {
187 type Item = $item_name<'a>;
188 fn next(&mut self) -> Option<Self::Item> {
189 self.0.next().map($item_name)
190 }
191 fn size_hint(&self) -> (usize, Option<usize>) {
192 self.0.size_hint()
193 }
194 }
195
196 impl<'a> DoubleEndedIterator for $iter_name<'a> {
197 fn next_back(&mut self) -> Option<Self::Item> {
198 self.0.next_back().map($item_name)
199 }
200 }
201
202 impl<'a> FusedIterator for $iter_name<'a> {}
203
204 $(#[$item_attrs])*
205 #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, AsRef, Deref)]
206 pub struct $item_name<'a>(pub &'a str);
207 impl_str!($item_name);
208 )*};
209}
210
211def_str_wrappers! {
212 FileName;
214 Name;
216 Base;
218 Version;
220 UpstreamVersion;
222 Description;
224 Url;
226 Packager;
228 ChangeLog;
230 BuildOption;
232 FilePath;
234 Source;
236 PgpKey;
238}
239
240def_hex_wrappers! {
241 Hex128 {
243 size = 16;
244 }
245 Hex256 {
247 size = 32;
248 }
249}
250
251def_srcinfo_checksum_wrappers! {
252 SkipOrHex128 {
254 size = 16;
255 }
256 SkipOrHex160 {
258 size = 20;
259 }
260 SkipOrHex224 {
262 size = 28;
263 }
264 SkipOrHex256 {
266 size = 32;
267 }
268 SkipOrHex384 {
270 size = 48;
271 }
272 SkipOrHex512 {
274 size = 64;
275 }
276}
277
278def_b64_wrappers! {
279 PgpSignature;
281}
282
283def_num_wrappers! {
284 Size = u64;
286 Timestamp = u64;
288 Epoch = u64;
290 Release = u64; }
293
294def_list_wrappers! {
295 GroupList {
297 Iter = GroupIterator;
299 Item = Group;
301 }
302
303 LicenseList {
305 Iter = LicenseIterator;
307 Item = License;
309 }
310
311 ArchitectureList {
313 Iter = ArchitectureIterator;
315 Item = Architecture;
317 }
318
319 DependencyList {
321 Iter = DependencyIterator;
323 Item = Dependency;
325 }
326
327 DependencyAndReasonList {
329 Iter = DependencyAndReasonIterator;
331 Item = DependencyAndReason;
333 }
334}
335
336def_str_wrappers! {
337 DependencyName;
339 DependencyReason;
341 DependencySpecification;
343}
344
345mod dependency;
346mod dependency_and_reason;
347mod dependency_name;
348mod dependency_specification;
349mod dependency_specification_operator;
350mod hex128;
351mod parse_array;
352mod parse_hex;
353mod skip_or_array;
354
355pub use dependency_specification_operator::DependencySpecificationOperator;
356pub use parse_array::ParseArray;
357pub use skip_or_array::SkipOrArray;