arch_pkg_text/parse/srcinfo/
checksums.rs

1use super::{ParsedSrcinfo, ParsedSrcinfoBaseSection, ParsedSrcinfoDerivativeSection};
2use crate::{
3    srcinfo::{ChecksumType, ChecksumValue, Checksums, ChecksumsMut, Query, QueryChecksumItem},
4    value,
5};
6use pipe_trait::Pipe;
7
8macro_rules! def_impl {
9    ($(
10        $checksum_variant:ident($checksum_content:ident) <- $query_method:ident;
11    )*) => {
12        /// Private [iterator](Iterator) type to be used as the underlying return types in [`Checksums`] and [`ChecksumsMut`].
13        enum ChecksumsIter<$($checksum_variant,)*> {$(
14            $checksum_variant($checksum_variant),
15        )*}
16
17        impl<'a, $($checksum_variant,)*> Iterator for ChecksumsIter<$($checksum_variant,)*>
18        where
19            $($checksum_variant: Iterator<Item = QueryChecksumItem<'a>>,)*
20        {
21            type Item = QueryChecksumItem<'a>;
22            fn next(&mut self) -> Option<Self::Item> {
23                match self {$(
24                    ChecksumsIter::$checksum_variant(iter) => iter.next(),
25                )*}
26            }
27        }
28
29        impl<'a> ParsedSrcinfo<'a> {
30            /// Query checksums from all sections of a single [`ChecksumType`].
31            fn checksums_single_type(&self, checksum_type: ChecksumType) -> impl Iterator<Item = QueryChecksumItem<'a>> + '_ {
32                match checksum_type {$(
33                    ChecksumType::$checksum_variant => {
34                        self.$query_method()
35                            .map(|item| item.map(ChecksumValue::$checksum_variant))
36                            .pipe(ChecksumsIter::$checksum_variant)
37                    }
38                )*}
39            }
40        }
41
42        impl<'a> Checksums<'a> for ParsedSrcinfo<'a> {
43            fn checksums(&self) -> impl Iterator<Item = QueryChecksumItem<'a>> {
44                ChecksumType::all_types()
45                    .flat_map(|checksum_type| self.checksums_single_type(*checksum_type))
46            }
47        }
48
49        impl<'a> ChecksumsMut<'a> for ParsedSrcinfo<'a> {
50            fn checksums_mut(&mut self) -> impl Iterator<Item = QueryChecksumItem<'a>> {
51                self.checksums()
52            }
53        }
54
55        /// Slice of list of checksums.
56        enum SectionChecksumsView<'a, 'r> {$(
57            $checksum_variant(&'r [(value::$checksum_content<'a>, Option<value::Architecture<'a>>)]),
58        )*}
59
60        /// Private [iterator](Iterator) type to be used as the underlying return types in
61        /// [`ParsedSrcinfoBaseSection::checksums`] and [`ParsedSrcinfoDerivativeSection::checksums`].
62        struct SectionChecksumsIter<'a, 'r> {
63            index: usize,
64            view: SectionChecksumsView<'a, 'r>,
65        }
66
67        impl<'a, 'r> SectionChecksumsIter<'a, 'r> {
68            /// Create a new iterator.
69            fn new(view: SectionChecksumsView<'a, 'r>) -> Self {
70                SectionChecksumsIter { index: 0, view }
71            }
72        }
73
74        impl<'a, 'r> Iterator for SectionChecksumsIter<'a, 'r> {
75            type Item = (ChecksumValue<'a>, Option<value::Architecture<'a>>);
76            fn next(&mut self) -> Option<Self::Item> {
77                let value = match &self.view {$(
78                    SectionChecksumsView::$checksum_variant(view) => {
79                        let (value, architecture) = view.get(self.index)?;
80                        (ChecksumValue::$checksum_variant(*value), *architecture)
81                    }
82                )*};
83                self.index += 1;
84                Some(value)
85            }
86        }
87
88        impl<'a> ParsedSrcinfoBaseSection<'a> {
89            /// Query checksums of a single [`ChecksumType`].
90            fn checksums_single_type(&self, checksum_type: ChecksumType) -> impl Iterator<Item = (ChecksumValue<'a>, Option<value::Architecture<'a>>)> + '_ {
91                let view = match checksum_type {$(
92                    ChecksumType::$checksum_variant => SectionChecksumsView::$checksum_variant(self.$query_method()),
93                )*};
94                SectionChecksumsIter::new(view)
95            }
96        }
97
98        impl<'a> ParsedSrcinfoDerivativeSection<'a> {
99            /// Query checksums of a single [`ChecksumType`].
100            fn checksums_single_type(&self, checksum_type: ChecksumType) -> impl Iterator<Item = (ChecksumValue<'a>, Option<value::Architecture<'a>>)> + '_ {
101                let view = match checksum_type {$(
102                    ChecksumType::$checksum_variant => SectionChecksumsView::$checksum_variant(self.$query_method()),
103                )*};
104                SectionChecksumsIter::new(view)
105            }
106        }
107    };
108}
109
110def_impl! {
111    Md5(SkipOrHex128) <- md5_checksums;
112    Sha1(SkipOrHex160) <- sha1_checksums;
113    Sha224(SkipOrHex224) <- sha224_checksums;
114    Sha256(SkipOrHex256) <- sha256_checksums;
115    Sha384(SkipOrHex384) <- sha384_checksums;
116    Sha512(SkipOrHex512) <- sha512_checksums;
117    Blake2b(SkipOrHex512) <- blake2b_checksums;
118}
119
120impl<'a> ParsedSrcinfoBaseSection<'a> {
121    /// List checksums of all [`ChecksumType`].
122    pub fn checksums(
123        &self,
124    ) -> impl Iterator<Item = (ChecksumValue<'a>, Option<value::Architecture<'a>>)> + '_ {
125        ChecksumType::all_types()
126            .flat_map(|checksum_type| self.checksums_single_type(*checksum_type))
127    }
128}
129
130impl<'a> ParsedSrcinfoDerivativeSection<'a> {
131    /// List checksums of all [`ChecksumType`].
132    pub fn checksums(
133        &self,
134    ) -> impl Iterator<Item = (ChecksumValue<'a>, Option<value::Architecture<'a>>)> + '_ {
135        ChecksumType::all_types()
136            .flat_map(|checksum_type| self.checksums_single_type(*checksum_type))
137    }
138}