1use super::{MultiQueryDatabase, WithVersion};
2use crate::{
3 misc::{Attached, AttachedUtils, IntoAttached},
4 value::RepositoryName,
5};
6use arch_pkg_text::{
7 desc::{Query, QueryMut, misc::ShouldReuse},
8 value::{Name, ParseVersionError, ParsedVersion, Version},
9};
10use core::mem::replace;
11use derive_more::{Display, Error};
12use pipe_trait::Pipe;
13
14#[derive(Debug, Display, Clone, Error)]
16pub enum InsertError<'a> {
17 #[display("Querier does not provide a name")]
18 NoName,
19 #[display("Querier does not provide a version")]
20 NoVersion,
21 #[display("Version provided by the querier has invalid syntax: {_0}")]
22 ParseVersion(#[error(not(source))] ParseVersionError<'a>),
23}
24
25impl<'a, Querier: ShouldReuse> MultiQueryDatabase<'a, Querier> {
26 fn insert_with<GetName, GetVersion>(
33 &mut self,
34 repository: RepositoryName<'a>,
35 mut querier: Querier,
36 get_name: GetName,
37 get_version: GetVersion,
38 ) -> Result<Option<WithVersion<'a, Querier>>, InsertError<'a>>
39 where
40 GetName: FnOnce(&mut Querier) -> Option<Name<'a>>,
41 GetVersion: FnOnce(&mut Querier) -> Option<Version<'a>>,
42 {
43 let name = get_name(&mut querier).ok_or(InsertError::NoName)?;
44 let version = querier
45 .pipe_mut(get_version)
46 .ok_or(InsertError::NoVersion)?
47 .parse()
48 .map_err(InsertError::ParseVersion)?;
49 self.internal
50 .entry(&name)
51 .or_default()
52 .internal
53 .insert(&repository, querier.into_attached(version))
54 .pipe(Ok)
55 }
56
57 pub fn insert(
64 &mut self,
65 repository: RepositoryName<'a>,
66 querier: Querier,
67 ) -> Result<Option<WithVersion<'a, Querier>>, InsertError<'a>>
68 where
69 Querier: Query<'a>,
70 {
71 self.insert_with(
72 repository,
73 querier,
74 |querier| querier.name(),
75 |querier| querier.version(),
76 )
77 }
78
79 pub fn insert_mut(
86 &mut self,
87 repository: RepositoryName<'a>,
88 querier: Querier,
89 ) -> Result<Option<WithVersion<'a, Querier>>, InsertError<'a>>
90 where
91 Querier: QueryMut<'a>,
92 {
93 self.insert_with(repository, querier, Querier::name_mut, Querier::version_mut)
94 }
95}
96
97#[derive(Debug, Clone, Copy)]
99pub enum InsertNewerReturn<'a, Querier> {
100 Unoccupied,
102 Replaced(Attached<Querier, ParsedVersion<'a>>),
105 Rejected(Attached<Querier, ParsedVersion<'a>>),
108}
109
110impl<'a, Querier: ShouldReuse> MultiQueryDatabase<'a, Querier> {
111 fn insert_newer_with<GetName, GetVersion>(
114 &mut self,
115 repository: RepositoryName<'a>,
116 mut querier: Querier,
117 get_name: GetName,
118 get_version: GetVersion,
119 ) -> Result<InsertNewerReturn<'a, Querier>, InsertError<'a>>
120 where
121 GetName: FnOnce(&mut Querier) -> Option<Name<'a>>,
122 GetVersion: FnOnce(&mut Querier) -> Option<Version<'a>>,
123 {
124 let name = get_name(&mut querier).ok_or(InsertError::NoName)?;
125 let inserted_version = querier
126 .pipe_mut(get_version)
127 .ok_or(InsertError::NoVersion)?
128 .parse()
129 .map_err(InsertError::ParseVersion)?;
130
131 let inserted = querier.into_attached(inserted_version);
132
133 let multi_querier = self.internal.entry(&name).or_default();
134
135 let Some(existing) = multi_querier.internal.get_mut(repository.as_str()) else {
136 multi_querier.internal.insert(&repository, inserted);
137 return Ok(InsertNewerReturn::Unoccupied);
138 };
139
140 let existing_version = existing.attachment();
141 Ok(if existing_version < &inserted_version {
142 InsertNewerReturn::Replaced(replace(existing, inserted))
143 } else {
144 InsertNewerReturn::Rejected(inserted)
145 })
146 }
147
148 pub fn insert_newer(
151 &mut self,
152 repository: RepositoryName<'a>,
153 querier: Querier,
154 ) -> Result<InsertNewerReturn<'a, Querier>, InsertError<'a>>
155 where
156 Querier: Query<'a>,
157 {
158 self.insert_newer_with(
159 repository,
160 querier,
161 |querier| querier.name(),
162 |querier| querier.version(),
163 )
164 }
165
166 pub fn insert_newer_mut(
169 &mut self,
170 repository: RepositoryName<'a>,
171 querier: Querier,
172 ) -> Result<InsertNewerReturn<'a, Querier>, InsertError<'a>>
173 where
174 Querier: QueryMut<'a>,
175 {
176 self.insert_newer_with(repository, querier, Querier::name_mut, Querier::version_mut)
177 }
178}