arch_pkg_text/srcinfo/query/
forgetful.rs1use super::{
2 ChecksumValue, Checksums, ChecksumsMut, Query, QueryChecksumItem, QueryMut, QueryRawTextItem,
3 Section,
4 utils::{non_blank_trimmed_lines, parse_line},
5};
6use crate::{
7 parse::{ParseWithIssues, PartialParse, PartialParseResult},
8 srcinfo::{
9 field::{FieldName, ParsedField, RawField},
10 misc::{False, ReuseAdvice},
11 },
12 value::{Architecture, Name},
13};
14use core::convert::Infallible;
15use iter_scan::IterScan;
16use pipe_trait::Pipe;
17
18#[derive(Debug, Clone, Copy)]
20pub struct ForgetfulQuerier<'a>(&'a str);
21
22impl<'a> ForgetfulQuerier<'a> {
23 pub const fn new(text: &'a str) -> Self {
25 ForgetfulQuerier(text)
26 }
27
28 fn all_known_items(
30 &self,
31 ) -> impl Iterator<Item = (Section<'a>, (ParsedField<&'a str>, &'a str))> {
32 self.0
33 .pipe(non_blank_trimmed_lines)
34 .map_while(parse_line)
35 .filter_map(known_field)
36 .filter(|(_, value)| !value.is_empty())
37 .scan_state_copy(Section::Base, scan_section)
38 }
39}
40
41impl<'a> Query<'a> for ForgetfulQuerier<'a> {
42 fn query_raw_text(&self, field_name: FieldName) -> impl Iterator<Item = QueryRawTextItem<'a>> {
43 self.all_known_items()
44 .filter(move |(_, (field, _))| *field.name() == field_name)
45 .map(|(section, (field, value))| {
46 QueryRawTextItem::from_tuple3((
47 value,
48 section,
49 field.architecture_str().map(Architecture::new),
50 ))
51 })
52 }
53}
54
55impl<'a> QueryMut<'a> for ForgetfulQuerier<'a> {
56 fn query_raw_text_mut(
57 &mut self,
58 field_name: FieldName,
59 ) -> impl Iterator<Item = QueryRawTextItem<'a>> {
60 self.query_raw_text(field_name)
61 }
62}
63
64impl<'a> Checksums<'a> for ForgetfulQuerier<'a> {
65 fn checksums(&self) -> impl Iterator<Item = QueryChecksumItem<'a>> {
66 self.all_known_items()
67 .filter_map(|(section, (field, value))| {
68 ChecksumValue::try_from_field_name(*field.name(), value)
69 .map(|value| (value, section, field.architecture_str().map(Architecture)))
70 })
71 .map(QueryChecksumItem::from_tuple3)
72 }
73}
74
75impl<'a> ChecksumsMut<'a> for ForgetfulQuerier<'a> {
76 fn checksums_mut(&mut self) -> impl Iterator<Item = QueryChecksumItem<'a>> {
77 self.checksums()
78 }
79}
80
81fn known_field<'a, Architecture, Acquaintance>(
83 (field, acquaintance): (RawField<'a>, Acquaintance),
84) -> Option<(ParsedField<Architecture>, Acquaintance)>
85where
86 &'a str: TryInto<Architecture>,
87{
88 field
89 .to_parsed::<FieldName, Architecture>()
90 .map(|field| (field, acquaintance))
91 .ok()
92}
93
94fn scan_section<'a>(
96 section: Section<'a>,
97 (field, value): (ParsedField<&'a str>, &'a str),
98) -> (Section<'a>, (ParsedField<&'a str>, &'a str)) {
99 match field.name() {
100 FieldName::Name => (Section::Derivative(Name(value)), (field, value)),
101 _ => (section, (field, value)),
102 }
103}
104
105impl ReuseAdvice for ForgetfulQuerier<'_> {
106 type ShouldReuse = False;
111}
112
113impl<'a> From<&'a str> for ForgetfulQuerier<'a> {
114 fn from(value: &'a str) -> Self {
115 ForgetfulQuerier::new(value)
116 }
117}
118
119impl<'a> PartialParse<&'a str> for ForgetfulQuerier<'a> {
120 type Error = Infallible;
121 fn partial_parse(text: &'a str) -> PartialParseResult<Self, Self::Error> {
122 ForgetfulQuerier::parse_with_issues(text, ())
123 }
124}
125
126impl<'a, HandleIssue, Error> ParseWithIssues<&'a str, HandleIssue, Error> for ForgetfulQuerier<'a> {
127 fn parse_with_issues(text: &'a str, _: HandleIssue) -> PartialParseResult<Self, Error> {
128 text.pipe(ForgetfulQuerier::new)
129 .pipe(PartialParseResult::new_complete)
130 }
131}