arch_pkg_text/srcinfo/query/
checksums.rs1use crate::{
2 srcinfo::field::FieldName,
3 value::{self, ParseArray, SkipOrArray},
4};
5use pipe_trait::Pipe;
6
7macro_rules! def_enum {
8 ($(
9 $checksum_variant:ident($checksum_content:ident, $size:literal) = $field_variant:ident,
10 )*) => {
11 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13 pub enum ChecksumType {$(
14 $checksum_variant,
15 )*}
16
17 impl ChecksumType {
18 pub const TYPES: &[Self] = &[$(ChecksumType::$checksum_variant,)*];
20
21 pub fn all_types() -> impl Iterator<Item = &'static Self> {
23 ChecksumType::TYPES.iter()
24 }
25
26 pub const fn into_field_name(self) -> FieldName {
28 match self {$(
29 ChecksumType::$checksum_variant => FieldName::$field_variant,
30 )*}
31 }
32
33 pub const fn try_from_field_name(field_name: FieldName) -> Option<Self> {
35 match field_name {
36 $(FieldName::$field_variant => Some(ChecksumType::$checksum_variant),)*
37 _ => None,
38 }
39 }
40 }
41
42 #[derive(Debug, Clone, Copy)]
44 pub enum ChecksumValue<'a> {$(
45 $checksum_variant(value::$checksum_content<'a>),
46 )*}
47
48 impl<'a> ChecksumValue<'a> {
49 pub fn new(checksum_type: ChecksumType, raw_value: &'a str) -> Self {
51 match checksum_type {$(
52 ChecksumType::$checksum_variant => {
53 raw_value.pipe(value::$checksum_content).pipe(ChecksumValue::$checksum_variant)
54 }
55 )*}
56 }
57
58 pub(super) fn try_from_field_name(field_name: FieldName, raw_value: &'a str) -> Option<Self> {
60 let checksum_type = ChecksumType::try_from_field_name(field_name)?;
61 Some(ChecksumValue::new(checksum_type, raw_value))
62 }
63 }
64
65 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67 pub enum ChecksumArray {
68 Skip,
69 $($checksum_variant([u8; $size]),)*
70 }
71
72 impl<'a> ChecksumValue<'a> {
73 pub fn u8_array(self) -> Option<ChecksumArray> {
75 Some(match self {$(
76 ChecksumValue::$checksum_variant(hex_string) => match hex_string.u8_array()? {
77 SkipOrArray::Skip => ChecksumArray::Skip,
78 SkipOrArray::Array(array) => ChecksumArray::$checksum_variant(array),
79 }
80 )*})
81 }
82 }
83
84 impl ChecksumArray {
85 pub fn try_as_slice(&self) -> Option<&'_ [u8]> {
87 match self {
88 ChecksumArray::Skip => None,
89 $(ChecksumArray::$checksum_variant(array) => Some(array),)*
90 }
91 }
92 }
93 };
94}
95
96def_enum! {
97 Md5(SkipOrHex128, 16) = Md5Checksums,
98 Sha1(SkipOrHex160, 20) = Sha1Checksums,
99 Sha224(SkipOrHex224, 28) = Sha224Checksums,
100 Sha256(SkipOrHex256, 32) = Sha256Checksums,
101 Sha384(SkipOrHex384, 48) = Sha384Checksums,
102 Sha512(SkipOrHex512, 64) = Sha512Checksums,
103 Blake2b(SkipOrHex512, 64) = Blake2bChecksums,
104}
105
106impl From<ChecksumType> for FieldName {
107 fn from(value: ChecksumType) -> Self {
108 value.into_field_name()
109 }
110}
111
112impl TryFrom<FieldName> for ChecksumType {
113 type Error = ();
114 fn try_from(value: FieldName) -> Result<Self, Self::Error> {
115 ChecksumType::try_from_field_name(value).ok_or(())
116 }
117}
118
119impl ParseArray for ChecksumValue<'_> {
120 type Array = ChecksumArray;
121 type Error = ();
122 fn parse_array(&self) -> Result<Self::Array, Self::Error> {
123 self.u8_array().ok_or(())
124 }
125}