1use core::{
4 iter::{DoubleEndedIterator, FusedIterator},
5 num::{IntErrorKind, 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 let handle_error = |error: ParseIntError| match error.kind() {
77 IntErrorKind::Empty | IntErrorKind::Zero => Ok(0),
78 _ => Err(error),
79 };
80 self.as_str().parse().or_else(handle_error)
81 }
82 }
83 };
84}
85
86macro_rules! def_str_wrappers {
87 ($(
88 $(#[$attrs:meta])*
89 $name:ident;
90 )*) => {$(
91 $(#[$attrs])*
92 #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, AsRef, Deref)]
93 pub struct $name<'a>(pub &'a str);
94 impl_str!($name);
95 )*};
96}
97
98macro_rules! def_structured_wrappers {
99 ($(
100 $(#[$attrs:meta])*
101 $name:ident;
102 )*) => {$(
103 $(#[$attrs])*
104 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
105 pub struct $name<'a>(pub &'a str);
106 impl_str!($name);
107 )*};
108}
109
110macro_rules! def_hex_wrappers {
111 ($(
112 $(#[$attrs:meta])*
113 $name:ident {
114 size = $size:literal;
115 }
116 )*) => {$(
117 $(#[$attrs])*
118 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
119 pub struct $name<'a>(pub &'a str);
120 impl_str!($name);
121 impl_hex!($name, $size);
122 )*};
123}
124
125macro_rules! def_srcinfo_checksum_wrappers {
126 ($(
127 $(#[$attrs:meta])*
128 $name:ident {
129 size = $size:literal;
130 }
131 )*) => {$(
132 $(#[$attrs])*
133 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
134 pub struct $name<'a>(pub &'a str);
135 impl_str!($name);
136 impl_srcinfo_checksum!($name, $size);
137 )*};
138}
139
140macro_rules! def_b64_wrappers {
141 ($(
142 $(#[$attrs:meta])*
143 $name:ident;
144 )*) => {$(
145 $(#[$attrs])*
146 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
147 pub struct $name<'a>(pub &'a str);
148 impl_str!($name);
149 )*};
150}
151
152macro_rules! def_num_wrappers {
153 ($(
154 $(#[$attrs:meta])*
155 $name:ident = $num:ty;
156 )*) => {$(
157 $(#[$attrs])*
158 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
159 pub struct $name<'a>(&'a str);
160 impl_num!($name, $num);
161 )*};
162}
163
164macro_rules! def_list_wrappers {
165 ($(
166 $(#[$container_attrs:meta])*
167 $container_name:ident {
168 $(#[$iter_attrs:meta])*
169 Iter = $iter_name:ident;
170 $(#[$item_attrs:meta])*
171 Item = $item_name:ident;
172 }
173 )*) => {$(
174 $(#[$container_attrs])*
175 #[derive(Debug, Clone, Copy)]
176 pub struct $container_name<'a>(&'a str);
177
178 impl<'a> $container_name<'a> {
179 pub fn new(text: &'a str) -> Self {
181 $container_name(text)
182 }
183
184 pub fn iter(&self) -> $iter_name<'_> {
186 self.into_iter()
187 }
188 }
189
190 impl<'a> IntoIterator for $container_name<'a> {
191 type IntoIter = $iter_name<'a>;
192 type Item = $item_name<'a>;
193 fn into_iter(self) -> Self::IntoIter {
194 $iter_name(self.0.split('\n'))
195 }
196 }
197
198 $(#[$iter_attrs])*
199 #[derive(Debug, Clone)]
200 pub struct $iter_name<'a>(Split<'a, char>);
201
202 impl<'a> Iterator for $iter_name<'a> {
203 type Item = $item_name<'a>;
204 fn next(&mut self) -> Option<Self::Item> {
205 self.0.next().map($item_name)
206 }
207 fn size_hint(&self) -> (usize, Option<usize>) {
208 self.0.size_hint()
209 }
210 }
211
212 impl<'a> DoubleEndedIterator for $iter_name<'a> {
213 fn next_back(&mut self) -> Option<Self::Item> {
214 self.0.next_back().map($item_name)
215 }
216 }
217
218 impl<'a> FusedIterator for $iter_name<'a> {}
219
220 $(#[$item_attrs])*
221 #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, AsRef, Deref)]
222 pub struct $item_name<'a>(pub &'a str);
223 impl_str!($item_name);
224 )*};
225}
226
227def_str_wrappers! {
228 FileName;
230 Name;
232 Base;
234 Description;
236 Url;
238 Packager;
240 ChangeLog;
242 FilePath;
244 Source;
246}
247
248def_structured_wrappers! {
249 Version;
251 UpstreamVersion;
253 BuildOption;
255 PgpKey;
257}
258
259def_hex_wrappers! {
260 Hex128 {
262 size = 16;
263 }
264 Hex256 {
266 size = 32;
267 }
268}
269
270def_srcinfo_checksum_wrappers! {
271 SkipOrHex128 {
273 size = 16;
274 }
275 SkipOrHex160 {
277 size = 20;
278 }
279 SkipOrHex224 {
281 size = 28;
282 }
283 SkipOrHex256 {
285 size = 32;
286 }
287 SkipOrHex384 {
289 size = 48;
290 }
291 SkipOrHex512 {
293 size = 64;
294 }
295}
296
297def_b64_wrappers! {
298 PgpSignature;
300}
301
302def_num_wrappers! {
303 Size = u64;
305 Timestamp = u64;
307 Epoch = u64;
309 Release = u64; }
312
313def_list_wrappers! {
314 GroupList {
316 Iter = GroupIterator;
318 Item = Group;
320 }
321
322 LicenseList {
324 Iter = LicenseIterator;
326 Item = License;
328 }
329
330 ArchitectureList {
332 Iter = ArchitectureIterator;
334 Item = Architecture;
336 }
337
338 DependencyList {
340 Iter = DependencyIterator;
342 Item = Dependency;
344 }
345
346 DependencyAndReasonList {
348 Iter = DependencyAndReasonIterator;
350 Item = DependencyAndReason;
352 }
353}
354
355def_str_wrappers! {
356 DependencyName;
358 DependencyReason;
360 DependencySpecification;
362}
363
364mod dependency;
365mod dependency_and_reason;
366mod dependency_name;
367mod dependency_specification;
368mod dependency_specification_operator;
369mod hex128;
370mod parse_array;
371mod parse_hex;
372mod skip_or_array;
373mod upstream_version;
374mod version;
375
376pub use dependency_specification_operator::DependencySpecificationOperator;
377pub use parse_array::ParseArray;
378pub use skip_or_array::SkipOrArray;
379pub use upstream_version::{
380 UpstreamVersionComponent, UpstreamVersionComponentIter, ValidUpstreamVersion,
381 ValidateUpstreamVersionError,
382};
383pub use version::{ParseVersionError, ParsedVersion, SplitVersionError};