arch_pkg_db/single/
insert.rs1use super::QueryDatabase;
2use arch_pkg_text::{
3 desc::{Query, QueryMut},
4 misc::desc::ShouldReuse,
5 value::{Name, ParseVersionError, Version},
6};
7use core::mem::replace;
8use derive_more::{Display, Error};
9use pipe_trait::Pipe;
10
11#[derive(Debug, Display, Clone, Copy, Error)]
13pub enum InsertError {
14 #[display("Querier could not provide a name")]
15 NoName,
16}
17
18impl<'a, Querier: ShouldReuse> QueryDatabase<'a, Querier> {
19 fn insert_with<GetName>(
23 &mut self,
24 mut querier: Querier,
25 get_name: GetName,
26 ) -> Result<Option<Querier>, InsertError>
27 where
28 GetName: FnOnce(&mut Querier) -> Option<Name<'a>>,
29 {
30 let name = get_name(&mut querier).ok_or(InsertError::NoName)?;
31 self.internal.insert(&name, querier).pipe(Ok)
32 }
33
34 pub fn insert(&mut self, querier: Querier) -> Result<Option<Querier>, InsertError>
38 where
39 Querier: Query<'a>,
40 {
41 self.insert_with(querier, |querier| querier.name())
42 }
43
44 pub fn insert_mut(&mut self, querier: Querier) -> Result<Option<Querier>, InsertError>
48 where
49 Querier: QueryMut<'a>,
50 {
51 self.insert_with(querier, Querier::name_mut)
52 }
53}
54
55#[derive(Debug, Clone, Copy)]
57pub enum InsertNewerReturn<Querier> {
58 Unoccupied,
60 Replaced(Querier),
63 Rejected(Querier),
66}
67
68#[derive(Debug, Display, Error)]
70pub enum InsertNewerError<'a> {
71 #[display("Querier could not provide a name")]
72 NoName,
73 #[display("Querier could not provide a version")]
74 NoVersion,
75 #[display("Version provided by the querier has invalid syntax: {_0}")]
76 InvalidVersion(#[error(not(source))] ParseVersionError<'a>),
77}
78
79impl<'a, Querier: ShouldReuse> QueryDatabase<'a, Querier> {
80 fn insert_newer_with<GetName, GetVersion>(
83 &mut self,
84 mut querier: Querier,
85 get_name: GetName,
86 mut get_version: GetVersion,
87 ) -> Result<InsertNewerReturn<Querier>, InsertNewerError<'a>>
88 where
89 GetName: FnOnce(&mut Querier) -> Option<Name<'a>>,
90 GetVersion: FnMut(&mut Querier) -> Option<Version<'a>>,
91 {
92 let name = get_name(&mut querier).ok_or(InsertNewerError::NoName)?;
93 let Some(existing) = self.internal.get_mut(name.as_str()) else {
94 self.internal.insert(&name, querier);
95 return Ok(InsertNewerReturn::Unoccupied);
96 };
97
98 let existing_version = existing
99 .pipe_mut(&mut get_version)
100 .ok_or(InsertNewerError::NoVersion)?
101 .parse()
102 .map_err(InsertNewerError::InvalidVersion)?;
103 let inserted_version = querier
104 .pipe_mut(&mut get_version)
105 .ok_or(InsertNewerError::NoVersion)?
106 .parse()
107 .map_err(InsertNewerError::InvalidVersion)?;
108
109 Ok(if existing_version < inserted_version {
110 InsertNewerReturn::Replaced(replace(existing, querier))
111 } else {
112 InsertNewerReturn::Rejected(querier)
113 })
114 }
115
116 pub fn insert_newer(
119 &mut self,
120 querier: Querier,
121 ) -> Result<InsertNewerReturn<Querier>, InsertNewerError<'a>>
122 where
123 Querier: Query<'a>,
124 {
125 self.insert_newer_with(
126 querier,
127 |querier| querier.name(),
128 |querier| querier.version(),
129 )
130 }
131
132 pub fn insert_newer_mut(
135 &mut self,
136 querier: Querier,
137 ) -> Result<InsertNewerReturn<Querier>, InsertNewerError<'a>>
138 where
139 Querier: QueryMut<'a>,
140 {
141 self.insert_newer_with(querier, Querier::name_mut, Querier::version_mut)
142 }
143}