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, Hash, AsRef, Deref)]
93 pub struct $name<'a>(pub &'a str);
94 impl_str!($name);
95 )*};
96}
97
98macro_rules! def_hex_wrappers {
99 ($(
100 $(#[$attrs:meta])*
101 $name:ident {
102 size = $size:literal;
103 }
104 )*) => {$(
105 $(#[$attrs])*
106 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
107 pub struct $name<'a>(pub &'a str);
108 impl_str!($name);
109 impl_hex!($name, $size);
110 )*};
111}
112
113macro_rules! def_srcinfo_checksum_wrappers {
114 ($(
115 $(#[$attrs:meta])*
116 $name:ident {
117 size = $size:literal;
118 }
119 )*) => {$(
120 $(#[$attrs])*
121 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
122 pub struct $name<'a>(pub &'a str);
123 impl_str!($name);
124 impl_srcinfo_checksum!($name, $size);
125 )*};
126}
127
128macro_rules! def_b64_wrappers {
129 ($(
130 $(#[$attrs:meta])*
131 $name:ident;
132 )*) => {$(
133 $(#[$attrs])*
134 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
135 pub struct $name<'a>(pub &'a str);
136 impl_str!($name);
137 )*};
138}
139
140macro_rules! def_num_wrappers {
141 ($(
142 $(#[$attrs:meta])*
143 $name:ident = $num:ty;
144 )*) => {$(
145 $(#[$attrs])*
146 #[derive(Debug, Display, Clone, Copy, AsRef, Deref)]
147 pub struct $name<'a>(&'a str);
148 impl_num!($name, $num);
149 )*};
150}
151
152macro_rules! def_list_wrappers {
153 ($(
154 $(#[$container_attrs:meta])*
155 $container_name:ident {
156 $(#[$iter_attrs:meta])*
157 Iter = $iter_name:ident;
158 $(#[$item_attrs:meta])*
159 Item = $item_name:ident;
160 }
161 )*) => {$(
162 $(#[$container_attrs])*
163 #[derive(Debug, Clone, Copy)]
164 pub struct $container_name<'a>(&'a str);
165
166 impl<'a> $container_name<'a> {
167 pub fn new(text: &'a str) -> Self {
169 $container_name(text)
170 }
171
172 pub fn iter(&self) -> $iter_name<'_> {
174 self.into_iter()
175 }
176 }
177
178 impl<'a> IntoIterator for $container_name<'a> {
179 type IntoIter = $iter_name<'a>;
180 type Item = $item_name<'a>;
181 fn into_iter(self) -> Self::IntoIter {
182 $iter_name(self.0.split('\n'))
183 }
184 }
185
186 $(#[$iter_attrs])*
187 #[derive(Debug, Clone)]
188 pub struct $iter_name<'a>(Split<'a, char>);
189
190 impl<'a> Iterator for $iter_name<'a> {
191 type Item = $item_name<'a>;
192 fn next(&mut self) -> Option<Self::Item> {
193 self.0.next().map($item_name)
194 }
195 fn size_hint(&self) -> (usize, Option<usize>) {
196 self.0.size_hint()
197 }
198 }
199
200 impl<'a> DoubleEndedIterator for $iter_name<'a> {
201 fn next_back(&mut self) -> Option<Self::Item> {
202 self.0.next_back().map($item_name)
203 }
204 }
205
206 impl<'a> FusedIterator for $iter_name<'a> {}
207
208 $(#[$item_attrs])*
209 #[derive(Debug, Display, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, AsRef, Deref)]
210 pub struct $item_name<'a>(pub &'a str);
211 impl_str!($item_name);
212 )*};
213}
214
215def_str_wrappers! {
216 FileName;
218 Name;
220 Base;
222 Version;
224 UpstreamVersion;
226 Description;
228 Url;
230 Packager;
232 ChangeLog;
234 BuildOption;
236 FilePath;
238 Source;
240 PgpKey;
242}
243
244def_hex_wrappers! {
245 Hex128 {
247 size = 16;
248 }
249 Hex256 {
251 size = 32;
252 }
253}
254
255def_srcinfo_checksum_wrappers! {
256 SkipOrHex128 {
258 size = 16;
259 }
260 SkipOrHex160 {
262 size = 20;
263 }
264 SkipOrHex224 {
266 size = 28;
267 }
268 SkipOrHex256 {
270 size = 32;
271 }
272 SkipOrHex384 {
274 size = 48;
275 }
276 SkipOrHex512 {
278 size = 64;
279 }
280}
281
282def_b64_wrappers! {
283 PgpSignature;
285}
286
287def_num_wrappers! {
288 Size = u64;
290 Timestamp = u64;
292 Epoch = u64;
294 Release = u64; }
297
298def_list_wrappers! {
299 GroupList {
301 Iter = GroupIterator;
303 Item = Group;
305 }
306
307 LicenseList {
309 Iter = LicenseIterator;
311 Item = License;
313 }
314
315 ArchitectureList {
317 Iter = ArchitectureIterator;
319 Item = Architecture;
321 }
322
323 DependencyList {
325 Iter = DependencyIterator;
327 Item = Dependency;
329 }
330
331 DependencyAndReasonList {
333 Iter = DependencyAndReasonIterator;
335 Item = DependencyAndReason;
337 }
338}
339
340def_str_wrappers! {
341 DependencyName;
343 DependencyReason;
345 DependencySpecification;
347}
348
349mod dependency;
350mod dependency_and_reason;
351mod dependency_name;
352mod dependency_specification;
353mod dependency_specification_operator;
354mod hex128;
355mod parse_array;
356mod parse_hex;
357mod skip_or_array;
358mod upstream_version;
359mod version;
360
361pub use dependency_specification_operator::DependencySpecificationOperator;
362pub use parse_array::ParseArray;
363pub use skip_or_array::SkipOrArray;
364pub use upstream_version::{
365 UpstreamVersionComponent, UpstreamVersionComponentIter, ValidUpstreamVersion,
366 ValidateUpstreamVersionError,
367};
368pub use version::{ParseVersionError, ParsedVersion, SplitVersionError};