arch_pkg_text/parse/srcinfo/
data.rs

1use super::{
2    AddFailure, ParsedSrcinfo, ParsedSrcinfoDerivativeSectionEntryMut, unknown_field_from_parsed,
3};
4use crate::{
5    srcinfo::{FieldName, ParsedField, Query, QueryItem, QueryMut, QueryRawTextItem, Section},
6    value,
7};
8use derive_more::{Display, Error};
9use pipe_trait::Pipe;
10
11macro_rules! def_struct {
12    (
13        base single {$(
14            $base_single_name:ident, $base_single_name_mut:ident = $base_single_field:ident -> $base_single_type:ident;
15        )*}
16        base multi {$(
17            $base_multi_name:ident, $base_multi_name_mut:ident = $base_multi_field:ident -> $base_multi_type:ident;
18        )*}
19        shared single {$(
20            $shared_single_name:ident, $shared_single_name_mut:ident = $shared_single_field:ident -> $shared_single_type:ident;
21        )*}
22        shared multi no_arch {$(
23            $shared_multi_no_arch_name:ident, $shared_multi_no_arch_name_mut:ident = $shared_multi_no_arch_field:ident -> $shared_multi_no_arch_type:ident;
24        )*}
25        shared multi arch {$(
26            $shared_multi_arch_name:ident, $shared_multi_arch_name_mut:ident = $shared_multi_arch_field:ident -> $shared_multi_arch_type:ident;
27        )*}
28    ) => {
29        /// Private [iterator](Iterator) type to be used as the underlying return types in [`Query`] and [`QueryMut`].
30        enum QueryIter<
31            Name,
32            $($base_single_field,)*
33            $($base_multi_field,)*
34            $($shared_single_field,)*
35            $($shared_multi_no_arch_field,)*
36            $($shared_multi_arch_field,)*
37        > {
38            Name(Name),
39            $($base_single_field($base_single_field),)*
40            $($base_multi_field($base_multi_field),)*
41            $($shared_single_field($shared_single_field),)*
42            $($shared_multi_no_arch_field($shared_multi_no_arch_field),)*
43            $($shared_multi_arch_field($shared_multi_arch_field),)*
44        }
45
46        impl<
47            'a,
48            Name,
49            $($base_single_field,)*
50            $($base_multi_field,)*
51            $($shared_single_field,)*
52            $($shared_multi_no_arch_field,)*
53            $($shared_multi_arch_field,)*
54        > Iterator for QueryIter<
55            Name,
56            $($base_single_field,)*
57            $($base_multi_field,)*
58            $($shared_single_field,)*
59            $($shared_multi_no_arch_field,)*
60            $($shared_multi_arch_field,)*
61        > where
62            Name: Iterator<Item = QueryRawTextItem<'a>>,
63            $($base_single_field: Iterator<Item = QueryRawTextItem<'a>>,)*
64            $($base_multi_field: Iterator<Item = QueryRawTextItem<'a>>,)*
65            $($shared_single_field: Iterator<Item = QueryRawTextItem<'a>>,)*
66            $($shared_multi_no_arch_field: Iterator<Item = QueryRawTextItem<'a>>,)*
67            $($shared_multi_arch_field: Iterator<Item = QueryRawTextItem<'a>>,)*
68        {
69            type Item = QueryRawTextItem<'a>;
70            fn next(&mut self) -> Option<Self::Item> {
71                match self {
72                    QueryIter::Name(iter) => iter.next(),
73                    $(QueryIter::$base_single_field(iter) => iter.next(),)*
74                    $(QueryIter::$base_multi_field(iter) => iter.next(),)*
75                    $(QueryIter::$shared_single_field(iter) => iter.next(),)*
76                    $(QueryIter::$shared_multi_no_arch_field(iter) => iter.next(),)*
77                    $(QueryIter::$shared_multi_arch_field(iter) => iter.next(),)*
78                }
79            }
80        }
81
82        impl<'a> Query<'a> for ParsedSrcinfo<'a> {
83            fn query_raw_text(&self, field_name: FieldName) -> impl Iterator<Item = QueryRawTextItem<'a>> {
84                match field_name {
85                    FieldName::Name => {
86                        self.derivatives
87                            .keys()
88                            .map(|name| (name.as_str(), Section::Derivative(*name), None))
89                            .map(QueryRawTextItem::from_tuple3)
90                            .pipe(QueryIter::Name)
91                    }
92                    $(FieldName::$base_single_field => {
93                        self.$base_single_name()
94                            .into_iter()
95                            .map(|value| (value.as_str(), Section::Base, None))
96                            .map(QueryRawTextItem::from_tuple3)
97                            .pipe(QueryIter::$base_single_field)
98                    })*
99                    $(FieldName::$base_multi_field => {
100                        self.$base_multi_name()
101                            .map(|value| (value.as_str(), Section::Base, None))
102                            .map(QueryRawTextItem::from_tuple3)
103                            .pipe(QueryIter::$base_multi_field)
104                    })*
105                    $(FieldName::$shared_single_field => {
106                        self.$shared_single_name()
107                            .map(QueryItem::into_tuple2)
108                            .map(|(value, section)| (value.as_str(), section, None))
109                            .map(QueryRawTextItem::from_tuple3)
110                            .pipe(QueryIter::$shared_single_field)
111                    })*
112                    $(FieldName::$shared_multi_no_arch_field => {
113                        self.$shared_multi_no_arch_name()
114                            .map(QueryItem::into_tuple2)
115                            .map(|(value, section)| (value.as_str(), section, None))
116                            .map(QueryRawTextItem::from_tuple3)
117                            .pipe(QueryIter::$shared_multi_no_arch_field)
118                    })*
119                    $(FieldName::$shared_multi_arch_field => {
120                        self.$shared_multi_arch_name()
121                            .map(QueryItem::into_tuple3)
122                            .map(|(value, section, architecture)| (value.as_str(), section, architecture))
123                            .map(QueryRawTextItem::from_tuple3)
124                            .pipe(QueryIter::$shared_multi_arch_field)
125                    })*
126                }
127            }
128            $(fn $base_single_name(&self) -> Option<value::$base_single_type<'a>> {
129                self.base.$base_single_name
130            })*
131            $(fn $base_multi_name(&self) -> impl Iterator<Item = value::$base_multi_type<'a>> {
132                self.base.$base_multi_name.iter().copied()
133            })*
134            $(fn $shared_single_name(&self) -> impl Iterator<Item = QueryItem<'a, value::$shared_single_type<'a>, ()>> {
135                let tail = self
136                    .derivatives
137                    .iter()
138                    .map(|(name, derivative)| (name, derivative.$shared_single_name))
139                    .flat_map(|(name, value)| value.map(|value| (*name, value)))
140                    .map(|(name, value)| (value, Section::Derivative(name)))
141                    .map(QueryItem::from_tuple2);
142                self.base
143                    .$shared_single_name
144                    .into_iter()
145                    .map(|value| (value, Section::Base))
146                    .map(QueryItem::from_tuple2)
147                    .chain(tail)
148            })*
149            $(fn $shared_multi_no_arch_name(&self) -> impl Iterator<Item = QueryItem<'a, value::$shared_multi_no_arch_type<'a>, ()>> {
150                let tail = self
151                    .derivatives
152                    .iter()
153                    .map(|(name, derivative)| (name, &derivative.$shared_multi_no_arch_name))
154                    .flat_map(|(name, values)| values.iter().map(|value| (*name, *value)))
155                    .map(|(name, value)| (value, Section::Derivative(name)))
156                    .map(QueryItem::from_tuple2);
157                self.base
158                    .$shared_multi_no_arch_name
159                    .iter()
160                    .copied()
161                    .map(|value| (value, Section::Base))
162                    .map(QueryItem::from_tuple2)
163                    .chain(tail)
164            })*
165            $(fn $shared_multi_arch_name(&self) -> impl Iterator<
166                Item = QueryItem<'a, value::$shared_multi_arch_type<'a>, Option<value::Architecture<'a>>>,
167            > {
168                let tail = self
169                    .derivatives
170                    .iter()
171                    .map(|(name, derivative)| (name, &derivative.$shared_multi_arch_name))
172                    .flat_map(|(name, values)| {
173                        values.iter().map(|(value, architecture)| (*name, *value, *architecture))
174                    })
175                    .map(|(name, value, architecture)| (value, Section::Derivative(name), architecture))
176                    .map(QueryItem::from_tuple3);
177                self.base
178                    .$shared_multi_arch_name
179                    .iter()
180                    .copied()
181                    .map(|(value, architecture)| (value, Section::Base, architecture))
182                    .map(QueryItem::from_tuple3)
183                    .chain(tail)
184            })*
185        }
186
187        impl<'a> QueryMut<'a> for ParsedSrcinfo<'a> {
188            fn query_raw_text_mut(&mut self, field_name: FieldName) -> impl Iterator<Item = QueryRawTextItem<'a>> {
189                self.query_raw_text(field_name)
190            }
191            $(fn $base_single_name_mut(&mut self) -> Option<value::$base_single_type<'a>> { self.$base_single_name() })*
192            $(fn $base_multi_name_mut(&mut self) -> impl Iterator<Item = value::$base_multi_type<'a>> { self.$base_multi_name() })*
193            $(fn $shared_single_name_mut(&mut self) -> impl Iterator<Item = QueryItem<'a, value::$shared_single_type<'a>, ()>> { self.$shared_single_name() })*
194            $(fn $shared_multi_no_arch_name_mut(&mut self) -> impl Iterator<Item = QueryItem<'a, value::$shared_multi_no_arch_type<'a>, ()>> {
195                self.$shared_multi_no_arch_name()
196            })*
197            $(fn $shared_multi_arch_name_mut(&mut self) -> impl Iterator<
198                Item = QueryItem<'a, value::$shared_multi_arch_type<'a>, Option<value::Architecture<'a>>>,
199            > { self.$shared_multi_arch_name() })*
200        }
201
202        /// Parsed information of a `pkgbase` section.
203        #[derive(Debug, Default, Clone)]
204        pub struct ParsedSrcinfoBaseSection<'a> {
205            $($base_single_name: Option<value::$base_single_type<'a>>,)*
206            $($base_multi_name: Vec<value::$base_multi_type<'a>>,)*
207            $($shared_single_name: Option<value::$shared_single_type<'a>>,)*
208            $($shared_multi_no_arch_name: Vec<value::$shared_multi_no_arch_type<'a>>,)*
209            $($shared_multi_arch_name: Vec<(value::$shared_multi_arch_type<'a>, Option<value::Architecture<'a>>)>,)*
210        }
211
212        /// Error that occurs when a pkgbase section of `.SRCINFO` defines a unique field more than once.
213        #[derive(Debug, Display, Error, Clone, Copy)]
214        pub enum ParsedSrcinfoBaseUniqueFieldDuplicationError<'a> {
215            $(
216                #[display("Field {} is already set", FieldName::$base_single_field)]
217                $base_single_field(#[error(not(source))] value::$base_single_type<'a>),
218            )*
219            $(
220                #[display("Field {} is already set", FieldName::$shared_single_field)]
221                $shared_single_field(#[error(not(source))] value::$shared_single_type<'a>),
222            )*
223        }
224
225        impl<'a> ParsedSrcinfoBaseSection<'a> {
226            /// Add an entry to the section.
227            pub(super) fn add(
228                &mut self,
229                field: ParsedField<&'a str>,
230                value: &'a str,
231            ) -> Result<(), AddFailure<'a>> {
232                match (field.name(), field.architecture()) {
233                    (FieldName::Name, None) => {
234                        return value
235                            .pipe(value::Name)
236                            .pipe(AddFailure::MeetHeader)
237                            .pipe(Err);
238                    }
239                    (FieldName::Name, Some(_)) => return unknown_field_from_parsed(field),
240                    $((FieldName::$base_single_field, None) => {
241                        return ParsedSrcinfoBaseSection::add_value_to_option(
242                            &mut self.$base_single_name,
243                            value,
244                            value::$base_single_type::new,
245                            ParsedSrcinfoBaseUniqueFieldDuplicationError::$base_single_field,
246                        );
247                    })*
248                    $((FieldName::$base_single_field, Some(_)) => return unknown_field_from_parsed(field),)*
249                    $((FieldName::$base_multi_field, None) => {
250                        self.$base_multi_name.push(value::$base_multi_type::new(value));
251                        return Ok(());
252                    })*
253                    $((FieldName::$base_multi_field, Some(_)) => return unknown_field_from_parsed(field),)*
254                    $((FieldName::$shared_single_field, None) => {
255                        return ParsedSrcinfoBaseSection::add_value_to_option(
256                            &mut self.$shared_single_name,
257                            value,
258                            value::$shared_single_type::new,
259                            ParsedSrcinfoBaseUniqueFieldDuplicationError::$shared_single_field,
260                        );
261                    })*
262                    $((FieldName::$shared_single_field, Some(_)) => return unknown_field_from_parsed(field),)*
263                    $((FieldName::$shared_multi_no_arch_field, None) => {
264                        self.$shared_multi_no_arch_name.push(value::$shared_multi_no_arch_type::new(value));
265                        return Ok(());
266                    })*
267                    $((FieldName::$shared_multi_no_arch_field, Some(_)) => return unknown_field_from_parsed(field),)*
268                    $((FieldName::$shared_multi_arch_field, architecture) => {
269                        self.$shared_multi_arch_name.push((
270                            value::$shared_multi_arch_type::new(value),
271                            architecture.copied().map(value::Architecture),
272                        ));
273                        return Ok(());
274                    })*
275                }
276            }
277
278            /// Shrink all internal containers' capacities to fit.
279            pub fn shrink_to_fit(&mut self) {
280                $(self.$base_multi_name.shrink_to_fit();)*
281                $(self.$shared_multi_no_arch_name.shrink_to_fit();)*
282                $(self.$shared_multi_arch_name.shrink_to_fit();)*
283            }
284
285            $(pub fn $base_single_name(&self) -> Option<value::$base_single_type<'a>> { self.$base_single_name })*
286            $(pub fn $base_multi_name(&self) -> &'_ [value::$base_multi_type<'a>] { &self.$base_multi_name })*
287            $(pub fn $shared_single_name(&self) -> Option<value::$shared_single_type<'a>> { self.$shared_single_name })*
288            $(pub fn $shared_multi_no_arch_name(&self) -> &'_ [value::$shared_multi_no_arch_type<'a>] { &self.$shared_multi_no_arch_name })*
289            $(pub fn $shared_multi_arch_name(&self) -> &'_ [(
290                value::$shared_multi_arch_type<'a>,
291                Option<value::Architecture<'a>>,
292            )] { &self.$shared_multi_arch_name })*
293        }
294
295        /// Parsed information of a `pkgname` section.
296        #[derive(Debug, Default, Clone)]
297        pub struct ParsedSrcinfoDerivativeSection<'a> {
298            $($shared_single_name: Option<value::$shared_single_type<'a>>,)*
299            $($shared_multi_no_arch_name: Vec<value::$shared_multi_no_arch_type<'a>>,)*
300            $($shared_multi_arch_name: Vec<(value::$shared_multi_arch_type<'a>, Option<value::Architecture<'a>>)>,)*
301        }
302
303        /// Error that occurs when a pkgname section of `.SRCINFO` defines a unique field more than once.
304        #[derive(Debug, Display, Error, Clone, Copy)]
305        pub enum ParsedSrcinfoDerivativeUniqueFieldDuplicationError<'a> {$(
306            #[display("Field {} is already set", FieldName::$shared_single_field)]
307            $shared_single_field(#[error(not(source))] value::$shared_single_type<'a>),
308        )*}
309
310        impl<'a> ParsedSrcinfoDerivativeSection<'a> {
311            /// Shrink all internal containers' capacities to fit.
312            pub fn shrink_to_fit(&mut self) {
313                $(self.$shared_multi_no_arch_name.shrink_to_fit();)*
314                $(self.$shared_multi_arch_name.shrink_to_fit();)*
315            }
316
317            $(pub fn $shared_single_name(&self) -> Option<value::$shared_single_type<'a>> { self.$shared_single_name })*
318            $(pub fn $shared_multi_no_arch_name(&self) -> &'_ [value::$shared_multi_no_arch_type<'a>] { &self.$shared_multi_no_arch_name })*
319            $(pub fn $shared_multi_arch_name(&self) -> &'_ [(
320                value::$shared_multi_arch_type<'a>,
321                Option<value::Architecture<'a>>,
322            )] { &self.$shared_multi_arch_name })*
323        }
324
325        impl<'a, 'r> ParsedSrcinfoDerivativeSectionEntryMut<'a, 'r> {
326            /// Add an entry to the section.
327            pub(super) fn add(
328                &mut self,
329                field: ParsedField<&'a str>,
330                value: &'a str,
331            ) -> Result<(), AddFailure<'a>> {
332                match (field.name(), field.architecture()) {
333                    (FieldName::Name, None) => {
334                        return value
335                            .pipe(value::Name)
336                            .pipe(AddFailure::MeetHeader)
337                            .pipe(Err);
338                    }
339                    (FieldName::Name, Some(_)) => return unknown_field_from_parsed(field),
340                    $((FieldName::$base_single_field, _) => return unknown_field_from_parsed(field),)*
341                    $((FieldName::$base_multi_field, _) => return unknown_field_from_parsed(field),)*
342                    $((FieldName::$shared_single_field, None) => {
343                        return ParsedSrcinfoDerivativeSectionEntryMut::add_value_to_option(
344                            self.name,
345                            &mut self.data.$shared_single_name,
346                            value,
347                            value::$shared_single_type::new,
348                            ParsedSrcinfoDerivativeUniqueFieldDuplicationError::$shared_single_field,
349                        );
350                    })*
351                    $((FieldName::$shared_single_field, Some(_)) => return unknown_field_from_parsed(field),)*
352                    $((FieldName::$shared_multi_no_arch_field, None) => {
353                        self.data.$shared_multi_no_arch_name.push(value::$shared_multi_no_arch_type::new(value));
354                        return Ok(());
355                    })*
356                    $((FieldName::$shared_multi_no_arch_field, Some(_)) => return unknown_field_from_parsed(field),)*
357                    $((FieldName::$shared_multi_arch_field, architecture) => {
358                        self.data.$shared_multi_arch_name.push((
359                            value::$shared_multi_arch_type::new(value),
360                            architecture.copied().map(value::Architecture),
361                        ));
362                        return Ok(());
363                    })*
364                }
365            }
366        }
367    };
368}
369
370def_struct! {
371    base single {
372        base_name, base_name_mut = Base -> Base;
373        epoch, epoch_mut = Epoch -> Epoch;
374        release, release_mut = Release -> Release;
375        version, version_mut = Version -> UpstreamVersion;
376    }
377    base multi {
378        valid_pgp_keys, valid_pgp_keys_mut = ValidPgpKeys -> PgpKey;
379    }
380    shared single {
381        description, description_mut = Description -> Description;
382        change_log, change_log_mut = ChangeLog -> ChangeLog;
383        install_script, install_script_mut = InstallScript -> FileName;
384        url, url_mut = Url -> Url;
385    }
386    shared multi no_arch {
387        architecture, architecture_mut = Architecture -> Architecture;
388        backup, backup_mut = Backup -> FilePath;
389        groups, groups_mut = Groups -> Group;
390        license, license_mut = License -> License;
391        no_extract, no_extract_mut = NoExtract -> FileName;
392        options, options_mut = Options -> BuildOption;
393    }
394    shared multi arch {
395        /* MISC */
396        source, source_mut = Source -> Source;
397
398        /* DEPENDENCIES */
399        dependencies, dependencies_mut = Dependencies -> Dependency;
400        make_dependencies, make_dependencies_mut = MakeDependencies -> Dependency;
401        check_dependencies, check_dependencies_mut = CheckDependencies -> Dependency;
402        opt_dependencies, opt_dependencies_mut = OptionalDependencies -> DependencyAndReason;
403        provides, provides_mut = Provides -> Dependency;
404        conflicts, conflicts_mut = Conflicts -> Dependency;
405        replaces, replaces_mut = Replaces -> Dependency;
406
407        /* CHECKSUMS */
408        md5_checksums, md5_checksums_mut = Md5Checksums -> SkipOrHex128;
409        sha1_checksums, sha1_checksums_mut = Sha1Checksums -> SkipOrHex160;
410        sha224_checksums, sha224_checksums_mut = Sha224Checksums -> SkipOrHex224;
411        sha256_checksums, sha256_checksums_mut = Sha256Checksums -> SkipOrHex256;
412        sha384_checksums, sha384_checksums_mut = Sha384Checksums -> SkipOrHex384;
413        sha512_checksums, sha512_checksums_mut = Sha512Checksums -> SkipOrHex512;
414        blake2b_checksums, blake2b_checksums_mut = Blake2bChecksums -> SkipOrHex512;
415    }
416}