1use alloc::collections::{BTreeMap, BTreeSet};
2use alloc::format;
3use alloc::vec::Vec;
4use core::convert::Infallible;
5use core::error::Error;
6use core::fmt::Debug;
7
8use super::{MapField, OptionalField, RepeatedField};
9use crate::{ConversionError, ConversionResultExt, Verify, VerifyWith, unwrap_infallible};
10
11impl<S: Verify<Error = Infallible>> OptionalField<S> {
12 pub fn verify_infallible(self) -> Option<S::Verified> {
15 self.map(|value| unwrap_infallible(value.verify()))
16 }
17}
18
19impl<S: Verify<Error = Infallible>> RepeatedField<S> {
20 pub fn verify_infallible(self) -> Vec<S::Verified> {
36 self.map(|value| unwrap_infallible(value.verify()))
37 }
38}
39
40impl<K: Ord, S: Verify<Error = Infallible>> MapField<BTreeMap<K, S>> {
41 pub fn verify_infallible(self) -> BTreeMap<K, S::Verified> {
44 self.map(|value| unwrap_infallible(value.verify()))
45 }
46}
47
48#[cfg(feature = "std")]
49impl<K: Eq + core::hash::Hash, S: Verify<Error = Infallible>>
50 MapField<std::collections::HashMap<K, S>>
51{
52 pub fn verify_infallible(self) -> std::collections::HashMap<K, S::Verified> {
55 self.map(|value| unwrap_infallible(value.verify()))
56 }
57}
58
59impl<S: Verify> Verify for OptionalField<S> {
60 type Verified = Option<S::Verified>;
61 type Error = ConversionError;
62
63 fn verify(self) -> Result<Self::Verified, Self::Error> {
64 self.try_map(Verify::verify)
65 }
66}
67
68impl<S: VerifyWith<C>, C> VerifyWith<C> for OptionalField<S> {
69 type Verified = Option<S::Verified>;
70 type Error = ConversionError;
71
72 fn verify_with(self, context: C) -> Result<Self::Verified, Self::Error> {
73 self.try_map(|value| value.verify_with(context))
74 }
75}
76
77impl<S: Verify> Verify for RepeatedField<S> {
78 type Verified = Vec<S::Verified>;
79 type Error = ConversionError;
80
81 fn verify(self) -> Result<Self::Verified, Self::Error> {
82 self.try_map(Verify::verify)
83 }
84}
85
86impl<S: VerifyWith<C>, C: Clone> VerifyWith<C> for RepeatedField<S> {
87 type Verified = Vec<S::Verified>;
88 type Error = ConversionError;
89
90 fn verify_with(self, context: C) -> Result<Self::Verified, Self::Error> {
91 self.try_map(|value| value.verify_with(context.clone()))
92 }
93}
94
95impl<K: Ord + Debug, S: Verify> Verify for MapField<BTreeMap<K, S>> {
96 type Verified = BTreeMap<K, S::Verified>;
97 type Error = ConversionError;
98
99 fn verify(self) -> Result<Self::Verified, Self::Error> {
100 self.try_map(Verify::verify)
101 }
102}
103
104impl<K: Ord + Debug, S: VerifyWith<C>, C: Clone> VerifyWith<C> for MapField<BTreeMap<K, S>> {
105 type Verified = BTreeMap<K, S::Verified>;
106 type Error = ConversionError;
107
108 fn verify_with(self, context: C) -> Result<Self::Verified, Self::Error> {
109 self.try_map(|value| value.verify_with(context.clone()))
110 }
111}
112
113#[cfg(feature = "std")]
114impl<K: Eq + core::hash::Hash + Debug, S: Verify> Verify
115 for MapField<std::collections::HashMap<K, S>>
116{
117 type Verified = std::collections::HashMap<K, S::Verified>;
118 type Error = ConversionError;
119
120 fn verify(self) -> Result<Self::Verified, Self::Error> {
121 self.try_map(Verify::verify)
122 }
123}
124
125#[cfg(feature = "std")]
126impl<K: Eq + core::hash::Hash + Debug, S: VerifyWith<C>, C: Clone> VerifyWith<C>
127 for MapField<std::collections::HashMap<K, S>>
128{
129 type Verified = std::collections::HashMap<K, S::Verified>;
130 type Error = ConversionError;
131
132 fn verify_with(self, context: C) -> Result<Self::Verified, Self::Error> {
133 self.try_map(|value| value.verify_with(context.clone()))
134 }
135}
136
137#[derive(Clone, Copy, Debug, PartialEq, Eq)]
142pub enum DuplicatePolicy {
143 Reject,
145 KeepFirst,
147}
148
149impl<S> RepeatedField<S> {
150 pub fn verify_into_btree_set(
172 self,
173 duplicates: DuplicatePolicy,
174 ) -> Result<BTreeSet<S::Verified>, ConversionError>
175 where
176 S: Verify,
177 S::Verified: Ord,
178 {
179 let mut values = BTreeSet::new();
180 self.verify_set(duplicates, Verify::verify, |value| values.insert(value))?;
181 Ok(values)
182 }
183
184 pub fn verify_into_btree_set_with<C>(
187 self,
188 context: C,
189 duplicates: DuplicatePolicy,
190 ) -> Result<BTreeSet<S::Verified>, ConversionError>
191 where
192 S: VerifyWith<C>,
193 S::Verified: Ord,
194 C: Clone,
195 {
196 let mut values = BTreeSet::new();
197 self.verify_set(
198 duplicates,
199 |value| value.verify_with(context.clone()),
200 |value| values.insert(value),
201 )?;
202 Ok(values)
203 }
204
205 #[cfg(feature = "std")]
209 pub fn verify_into_hash_set(
210 self,
211 duplicates: DuplicatePolicy,
212 ) -> Result<std::collections::HashSet<S::Verified>, ConversionError>
213 where
214 S: Verify,
215 S::Verified: Eq + core::hash::Hash,
216 {
217 let mut values = std::collections::HashSet::new();
218 self.verify_set(duplicates, Verify::verify, |value| values.insert(value))?;
219 Ok(values)
220 }
221
222 #[cfg(feature = "std")]
225 pub fn verify_into_hash_set_with<C>(
226 self,
227 context: C,
228 duplicates: DuplicatePolicy,
229 ) -> Result<std::collections::HashSet<S::Verified>, ConversionError>
230 where
231 S: VerifyWith<C>,
232 S::Verified: Eq + core::hash::Hash,
233 C: Clone,
234 {
235 let mut values = std::collections::HashSet::new();
236 self.verify_set(
237 duplicates,
238 |value| value.verify_with(context.clone()),
239 |value| values.insert(value),
240 )?;
241 Ok(values)
242 }
243
244 fn verify_set<T, E: Error + Send + Sync + 'static>(
245 self,
246 duplicates: DuplicatePolicy,
247 mut verify: impl FnMut(S) -> Result<T, E>,
248 mut insert: impl FnMut(T) -> bool,
249 ) -> Result<(), ConversionError> {
250 for (index, value) in self.values.into_iter().enumerate() {
251 let value = verify(value).with_context(|| format!("{}[{index}]", self.name))?;
252 if !insert(value) && duplicates == DuplicatePolicy::Reject {
253 return Err(ConversionError::message("duplicate verified value")
254 .context(format!("{}[{index}]", self.name)));
255 }
256 }
257 Ok(())
258 }
259}