1use crate::Validate;
4
5#[cfg(feature = "async")]
6use crate::Resolve;
7
8#[cfg_attr(
10 feature = "async",
11 doc = "\nWith the `async` feature, also covers items implementing [Resolve](crate::Resolve)."
12)]
13#[cfg_attr(feature = "async", allow(async_fn_in_trait))]
14pub trait IteratorExt: IntoIterator {
15 fn validate_all_in_context<I>(
17 self,
18 ctx: &<Self::Item as Validate>::Context,
19 ) -> Result<I, <Self::Item as Validate>::Error>
20 where
21 Self::Item: Validate,
22 I: Extend<<Self::Item as Validate>::Output> + Default;
23
24 fn validate_all<I>(self) -> Result<I, <Self::Item as Validate>::Error>
50 where
51 Self::Item: Validate,
52 <Self::Item as Validate>::Context: From<()>,
53 I: Extend<<Self::Item as Validate>::Output> + Default;
54
55 fn partition_validated_in_context<I1, I2>(
57 self,
58 ctx: &<Self::Item as Validate>::Context,
59 ) -> (I1, I2)
60 where
61 Self::Item: Validate,
62 I1: Extend<<Self::Item as Validate>::Output> + Default,
63 I2: Extend<<Self::Item as Validate>::Error> + Default;
64
65 fn partition_validated<I1, I2>(self) -> (I1, I2)
94 where
95 Self::Item: Validate,
96 <Self::Item as Validate>::Context: From<()>,
97 I1: Extend<<Self::Item as Validate>::Output> + Default,
98 I2: Extend<<Self::Item as Validate>::Error> + Default;
99
100 #[cfg(feature = "async")]
102 async fn resolve_all_in_context<I>(
103 self,
104 ctx: &<Self::Item as Resolve>::Context,
105 ) -> Result<I, <Self::Item as Resolve>::Error>
106 where
107 Self: Sized,
108 Self::Item: Resolve,
109 I: Extend<<Self::Item as Resolve>::Output> + Default;
110
111 #[cfg(feature = "async")]
115 async fn resolve_all<I>(self) -> Result<I, <Self::Item as Resolve>::Error>
116 where
117 Self: Sized,
118 Self::Item: Resolve,
119 <Self::Item as Resolve>::Context: From<()>,
120 I: Extend<<Self::Item as Resolve>::Output> + Default;
121
122 #[cfg(feature = "async")]
124 async fn partition_resolved_in_context<I1, I2>(
125 self,
126 ctx: &<Self::Item as Resolve>::Context,
127 ) -> (I1, I2)
128 where
129 Self: Sized,
130 Self::Item: Resolve,
131 I1: Extend<<Self::Item as Resolve>::Output> + Default,
132 I2: Extend<<Self::Item as Resolve>::Error> + Default;
133
134 #[cfg(feature = "async")]
138 async fn partition_resolved<I1, I2>(self) -> (I1, I2)
139 where
140 Self: Sized,
141 Self::Item: Resolve,
142 <Self::Item as Resolve>::Context: From<()>,
143 I1: Extend<<Self::Item as Resolve>::Output> + Default,
144 I2: Extend<<Self::Item as Resolve>::Error> + Default;
145}
146
147impl<Iter: IntoIterator> IteratorExt for Iter {
148 fn validate_all_in_context<I>(
149 self,
150 ctx: &<Self::Item as Validate>::Context,
151 ) -> Result<I, <Self::Item as Validate>::Error>
152 where
153 Self::Item: Validate,
154 I: Extend<<Self::Item as Validate>::Output> + Default,
155 {
156 let mut out = I::default();
157 for item in self {
158 out.extend(Some(item.validate_in_context(ctx)?));
159 }
160 Ok(out)
161 }
162
163 fn validate_all<I>(self) -> Result<I, <Self::Item as Validate>::Error>
164 where
165 Self::Item: Validate,
166 <Self::Item as Validate>::Context: From<()>,
167 I: Extend<<Self::Item as Validate>::Output> + Default,
168 {
169 self.validate_all_in_context(&().into())
170 }
171
172 fn partition_validated_in_context<I1, I2>(
173 self,
174 ctx: &<Self::Item as Validate>::Context,
175 ) -> (I1, I2)
176 where
177 Self::Item: Validate,
178 I1: Extend<<Self::Item as Validate>::Output> + Default,
179 I2: Extend<<Self::Item as Validate>::Error> + Default,
180 {
181 let mut oks = I1::default();
182 let mut errs = I2::default();
183 for item in self {
184 match item.validate_in_context(ctx) {
185 Ok(v) => oks.extend(Some(v)),
186 Err(e) => errs.extend(Some(e)),
187 }
188 }
189 (oks, errs)
190 }
191
192 fn partition_validated<I1, I2>(self) -> (I1, I2)
193 where
194 Self::Item: Validate,
195 <Self::Item as Validate>::Context: From<()>,
196 I1: Extend<<Self::Item as Validate>::Output> + Default,
197 I2: Extend<<Self::Item as Validate>::Error> + Default,
198 {
199 self.partition_validated_in_context(&().into())
200 }
201
202 #[cfg(feature = "async")]
203 async fn resolve_all_in_context<I>(
204 self,
205 ctx: &<Self::Item as Resolve>::Context,
206 ) -> Result<I, <Self::Item as Resolve>::Error>
207 where
208 Self: Sized,
209 Self::Item: Resolve,
210 I: Extend<<Self::Item as Resolve>::Output> + Default,
211 {
212 let mut out = I::default();
213 for item in self {
214 out.extend(Some(item.resolve_in_context(ctx).await?));
215 }
216 Ok(out)
217 }
218
219 #[cfg(feature = "async")]
220 async fn resolve_all<I>(self) -> Result<I, <Self::Item as Resolve>::Error>
221 where
222 Self: Sized,
223 Self::Item: Resolve,
224 <Self::Item as Resolve>::Context: From<()>,
225 I: Extend<<Self::Item as Resolve>::Output> + Default,
226 {
227 self.resolve_all_in_context(&().into()).await
228 }
229
230 #[cfg(feature = "async")]
231 async fn partition_resolved_in_context<I1, I2>(
232 self,
233 ctx: &<Self::Item as Resolve>::Context,
234 ) -> (I1, I2)
235 where
236 Self: Sized,
237 Self::Item: Resolve,
238 I1: Extend<<Self::Item as Resolve>::Output> + Default,
239 I2: Extend<<Self::Item as Resolve>::Error> + Default,
240 {
241 let mut oks = I1::default();
242 let mut errs = I2::default();
243 for item in self {
244 match item.resolve_in_context(ctx).await {
245 Ok(v) => oks.extend(Some(v)),
246 Err(e) => errs.extend(Some(e)),
247 }
248 }
249 (oks, errs)
250 }
251
252 #[cfg(feature = "async")]
253 async fn partition_resolved<I1, I2>(self) -> (I1, I2)
254 where
255 Self: Sized,
256 Self::Item: Resolve,
257 <Self::Item as Resolve>::Context: From<()>,
258 I1: Extend<<Self::Item as Resolve>::Output> + Default,
259 I2: Extend<<Self::Item as Resolve>::Error> + Default,
260 {
261 self.partition_resolved_in_context(&().into()).await
262 }
263}