valust_utils/
stream.rs

1//! Utilities for working with streams, like `vec`.
2//!
3//! ## Functions overview
4//!
5//! - `vec`:
6//!     - validator: [`all_vec`], [`try_vec`]
7//!     - transformer: [`map_vec`], [`try_map_vec`]
8//! - `HashSet`:
9//!     - validator: [`all_set`], [`try_set`]
10//!     - transformer: Not yet.
11
12use std::collections::{BTreeMap, HashMap, HashSet};
13
14/// Checks if all elements in the [`Vec`] satisfy the predicate.
15///
16/// ```rust
17/// # use valust_utils::stream::all_vec;
18/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
19/// # use valust_derive::Valust;
20/// #
21/// #[derive(Debug, Valust)]
22/// struct All {
23///     #[valid(func(all_vec(|&x| x > 1)))]
24///     data: Vec<u8>
25/// }
26///
27/// let all = Raw::<All> { data: vec![1, 2, 3] };
28/// let val = All::validate(all);
29/// assert!(val.is_err());
30/// println!("{}", val.unwrap_err().full_stringify());
31/// ```
32pub fn all_vec<I>(predicate: fn(&I) -> bool) -> impl Fn(&Vec<I>) -> bool {
33    move |i| i.iter().all(predicate)
34}
35
36/// Checks if all elements in the [`Vec`] satisfy the predicate (fallible ones accepted).
37///
38/// ```rust
39/// # use valust_utils::stream::try_vec;
40/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
41/// # use valust_derive::Valust;
42/// #
43/// #[derive(Debug, Valust)]
44/// struct All {
45///     #[valid(func(try(try_vec(|x: &String| x.parse::<i32>().map(|u| u > 1)))))]
46///     data: Vec<String>
47/// }
48///
49/// let all = Raw::<All> { data: vec!["1".to_owned(), "2".to_owned(), "3".to_owned()] };
50/// let val = All::validate(all);
51/// assert!(val.is_err());
52/// println!("{}", val.unwrap_err().full_stringify());
53/// ```
54pub fn try_vec<I, E>(
55    predicate: fn(&I) -> Result<bool, E>,
56) -> impl Fn(&Vec<I>) -> Result<bool, E> {
57    move |i| {
58        i.iter()
59            .find_map(|i| match predicate(i) {
60                Ok(false) => Some(Ok(false)),
61                Err(e) => Some(Err(e)),
62                _ => None,
63            })
64            .unwrap_or(Ok(true))
65    }
66}
67
68/// Convert all elements in the [`Vec`] to a new type.
69///
70/// ```rust
71/// # use valust_utils::stream::map_vec;
72/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
73/// # use valust_derive::Valust;
74/// #
75/// #[derive(Debug, Valust)]
76/// struct Map {
77///     #[trans(func(Vec<String> => map_vec(|x: String| x.trim().to_string())))]
78///     items: Vec<String>
79/// }
80///
81/// let map = Raw::<Map> { items: vec![" 1 ".to_string(), "2".to_string()] };
82/// let val = Map::validate(map);
83/// assert_eq!(vec!["1".to_string(), "2".to_string()], val.unwrap().items);
84/// ```
85pub fn map_vec<I, O>(op: fn(I) -> O) -> impl Fn(Vec<I>) -> Vec<O> {
86    move |i| i.into_iter().map(op).collect()
87}
88
89/// Checks if all elements in the [`Vec`] satisfy the predicate (fallible ones accepted).
90///
91/// ```rust
92/// # use valust_utils::stream::try_map_vec;
93/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
94/// # use valust_derive::Valust;
95/// #
96/// #[derive(Debug, Valust)]
97/// struct All {
98///     #[trans(func(Vec<String> => try(try_map_vec(|x: String| x.parse::<i32>()))))]
99///     data: Vec<i32>
100/// }
101///
102/// let all = Raw::<All> { data: vec!["1".to_owned(), "2".to_owned(), "3".to_owned()] };
103/// let val = All::validate(all);
104/// assert!(val.is_ok());
105/// assert_eq!(vec![1, 2, 3], val.unwrap().data);
106/// ```
107pub fn try_map_vec<I, O, E>(
108    predicate: fn(I) -> Result<O, E>,
109) -> impl Fn(Vec<I>) -> Result<Vec<O>, E> {
110    move |i| i.into_iter().map(predicate).collect()
111}
112
113/// Checks if all elements in the [`HashSet`] satisfy the predicate.
114///
115/// ```rust
116/// # use std::collections::HashSet;
117/// # use valust_utils::stream::all_set;
118/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
119/// # use valust_derive::Valust;
120/// #
121/// #[derive(Debug, Valust)]
122/// struct All {
123///     #[valid(func(all_set(|&x| x > 1)))]
124///     data: HashSet<u8>
125/// }
126///
127/// let all = Raw::<All> { data: vec![1, 2, 3].into_iter().collect() };
128/// let val = All::validate(all);
129/// assert!(val.is_err());
130/// println!("{}", val.unwrap_err().full_stringify());
131/// ```
132pub fn all_set<I>(predicate: fn(&I) -> bool) -> impl Fn(&HashSet<I>) -> bool {
133    move |i| i.iter().all(predicate)
134}
135
136/// Checks if all elements in the [`HashSet`] satisfy the predicate (fallible ones accepted).
137///
138/// ```rust
139/// # use std::collections::HashSet;
140/// # use valust_utils::stream::try_set;
141/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
142/// # use valust_derive::Valust;
143/// #
144/// #[derive(Debug, Valust)]
145/// struct All {
146///     #[valid(func(try(try_set(|x: &String| x.parse::<i32>().map(|u| u > 1)))))]
147///     data: HashSet<String>
148/// }
149///
150/// let all = Raw::<All> { data: vec!["1".to_owned(), "2".to_owned(), "3".to_owned()].into_iter().collect() };
151/// let val = All::validate(all);
152/// assert!(val.is_err());
153/// println!("{}", val.unwrap_err().full_stringify());
154/// ```
155pub fn try_set<I, E>(
156    predicate: fn(&I) -> Result<bool, E>,
157) -> impl Fn(&HashSet<I>) -> Result<bool, E> {
158    move |i| {
159        i.iter()
160            .find_map(|i| match predicate(i) {
161                Ok(false) => Some(Ok(false)),
162                Err(e) => Some(Err(e)),
163                _ => None,
164            })
165            .unwrap_or(Ok(true))
166    }
167}
168
169/// Checks if all entries in the [`HashMap`] satisfy the predicate.
170///
171/// ```rust
172/// # use std::collections::HashMap;
173/// # use valust_utils::stream::all_map;
174/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
175/// # use valust_derive::Valust;
176/// #
177/// #[derive(Debug, Valust)]
178/// struct All {
179///     #[valid(func(all_map(|&k, &v| k > 1 && v > 1)))]
180///     data: HashMap<u8, u8>
181/// }
182///
183/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
184/// let val = All::validate(all);
185/// assert!(val.is_err());
186/// println!("{}", val.unwrap_err().full_stringify());
187/// ```
188pub fn all_map<K, V>(predicate: fn(&K, &V) -> bool) -> impl Fn(&HashMap<K, V>) -> bool {
189    move |i| i.iter().all(|(k, v)| predicate(k, v))
190}
191
192/// Checks if all entries in the [`HashMap`] satisfy the predicate (fallible ones accepted).
193///
194/// ```rust
195/// # use std::collections::HashMap;
196/// # use valust_utils::stream::try_map;
197/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
198/// # use valust_derive::Valust;
199/// #
200/// #[derive(Debug, Valust)]
201/// struct All {
202///     #[valid(func(try(try_map(|k: &String, v: &String| k.parse::<i32>().map(|u| u > 1 && v.parse::<i32>().unwrap() > 1)))))]
203///     data: HashMap<String, String>
204/// }
205///
206/// let all = Raw::<All> { data: vec![("1".to_owned(), "2".to_owned()), ("2".to_owned(), "3".to_owned()), ("3".to_owned(), "4".to_owned())].into_iter().collect() };
207/// let val = All::validate(all);
208/// assert!(val.is_err());
209/// println!("{}", val.unwrap_err().full_stringify());
210/// ```
211pub fn try_map<K, V, E>(
212    predicate: fn(&K, &V) -> Result<bool, E>,
213) -> impl Fn(&HashMap<K, V>) -> Result<bool, E> {
214    move |i| {
215        i.iter()
216            .find_map(|(k, v)| match predicate(k, v) {
217                Ok(false) => Some(Ok(false)),
218                Err(e) => Some(Err(e)),
219                _ => None,
220            })
221            .unwrap_or(Ok(true))
222    }
223}
224
225/// Checks if all keys in the [`HashMap`] satisfy the predicate.
226///
227/// ```rust
228/// # use std::collections::HashMap;
229/// # use valust_utils::stream::all_map_keys;
230/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
231/// # use valust_derive::Valust;
232/// #
233/// #[derive(Debug, Valust)]
234/// struct All {
235///     #[valid(func(all_map_keys(|&k| k > 1)))]
236///     data: HashMap<u8, u8>
237/// }
238///
239/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
240/// let val = All::validate(all);
241/// assert!(val.is_err());
242/// println!("{}", val.unwrap_err().full_stringify());
243/// ```
244pub fn all_map_keys<K, V>(
245    predicate: fn(&K) -> bool,
246) -> impl Fn(&HashMap<K, V>) -> bool {
247    move |i| i.keys().all(predicate)
248}
249/// Checks if all keys in the [`HashMap`] satisfy the predicate (fallible ones accepted).
250///
251/// ```rust
252/// # use std::collections::HashMap;
253/// # use valust_utils::stream::try_all_map_keys;
254/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
255/// # use valust_derive::Valust;
256/// #
257/// #[derive(Debug, Valust)]
258/// struct All {
259///     #[valid(func(try(try_all_map_keys(|k: &String| k.parse::<i32>().map(|u| u > 1)))))]
260///     data: HashMap<String, u8>
261/// }
262///
263/// let all = Raw::<All> { data: vec![("1".to_owned(), 2), ("2".to_owned(), 3), ("3".to_owned(), 4)].into_iter().collect() };
264/// let val = All::validate(all);
265/// assert!(val.is_err());
266/// println!("{}", val.unwrap_err().full_stringify());
267/// ```
268pub fn try_all_map_keys<K, V, E>(
269    predicate: fn(&K) -> Result<bool, E>,
270) -> impl Fn(&HashMap<K, V>) -> Result<bool, E> {
271    move |i| {
272        i.keys()
273            .find_map(|k| match predicate(k) {
274                Ok(false) => Some(Ok(false)),
275                Err(e) => Some(Err(e)),
276                _ => None,
277            })
278            .unwrap_or(Ok(true))
279    }
280}
281
282/// Checks if all values in the [`HashMap`] satisfy the predicate.
283///
284/// ```rust
285/// # use std::collections::HashMap;
286/// # use valust_utils::stream::all_map_values;
287/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
288/// # use valust_derive::Valust;
289/// #
290/// #[derive(Debug, Valust)]
291/// struct All {
292///     #[valid(func(all_map_values(|&v| v > 3)))]
293///     data: HashMap<u8, u8>
294/// }
295///
296/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
297/// let val = All::validate(all);
298/// assert!(val.is_err());
299/// println!("{}", val.unwrap_err().full_stringify());
300/// ```
301pub fn all_map_values<K, V>(
302    predicate: fn(&V) -> bool,
303) -> impl Fn(&HashMap<K, V>) -> bool {
304    move |i| i.values().all(predicate)
305}
306
307/// Checks if all values in the [`HashMap`] satisfy the predicate (fallible ones accepted).
308///
309/// ```rust
310/// # use std::collections::HashMap;
311/// # use valust_utils::stream::try_all_map_values;
312/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
313/// # use valust_derive::Valust;
314/// #
315/// #[derive(Debug, Valust)]
316/// struct All {
317///     #[valid(func(try(try_all_map_values(|v: &String| v.parse::<i32>().map(|u| u > 3)))))]
318///     data: HashMap<u8, String>
319/// }
320///
321/// let all = Raw::<All> { data: vec![(1, "2".to_owned()), (2, "3".to_owned()), (3, "4".to_owned())].into_iter().collect() };
322/// let val = All::validate(all);
323/// assert!(val.is_err());
324/// println!("{}", val.unwrap_err().full_stringify());
325/// ```
326pub fn try_all_map_values<K, V, E>(
327    predicate: fn(&V) -> Result<bool, E>,
328) -> impl Fn(&HashMap<K, V>) -> Result<bool, E> {
329    move |i| {
330        i.values()
331            .find_map(|v| match predicate(v) {
332                Ok(false) => Some(Ok(false)),
333                Err(e) => Some(Err(e)),
334                _ => None,
335            })
336            .unwrap_or(Ok(true))
337    }
338}
339
340/// Checks if all entries in the [`BTreeMap`] satisfy the predicate.
341///
342/// ```rust
343/// # use std::collections::BTreeMap;
344/// # use valust_utils::stream::all_btree_map;
345/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
346/// # use valust_derive::Valust;
347/// #
348/// #[derive(Debug, Valust)]
349/// struct All {
350///     #[valid(func(all_btree_map(|&k, &v| k > 1 && v > 1)))]
351///     data: BTreeMap<u8, u8>
352/// }
353///
354/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
355/// let val = All::validate(all);
356/// assert!(val.is_err());
357/// println!("{}", val.unwrap_err().full_stringify());
358/// ```
359pub fn all_btree_map<K, V>(
360    predicate: fn(&K, &V) -> bool,
361) -> impl Fn(&BTreeMap<K, V>) -> bool {
362    move |i| i.iter().all(|(k, v)| predicate(k, v))
363}
364
365/// Checks if all entries in the [`BTreeMap`] satisfy the predicate (fallible ones accepted).
366///
367/// ```rust
368/// # use std::collections::BTreeMap;
369/// # use valust_utils::stream::try_btree_map;
370/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
371/// # use valust_derive::Valust;
372/// #
373/// #[derive(Debug, Valust)]
374/// struct All {
375///     #[valid(func(try(try_btree_map(|k: &String, v: &String| k.parse::<i32>().map(|u| u > 1 && v.parse::<i32>().unwrap() > 1)))))]
376///     data: BTreeMap<String, String>
377/// }
378///
379/// let all = Raw::<All> { data: vec![("1".to_owned(), "2".to_owned()), ("2".to_owned(), "3".to_owned()), ("3".to_owned(), "4".to_owned())].into_iter().collect() };
380/// let val = All::validate(all);
381/// assert!(val.is_err());
382/// println!("{}", val.unwrap_err().full_stringify());
383/// ```
384pub fn try_btree_map<K, V, E>(
385    predicate: fn(&K, &V) -> Result<bool, E>,
386) -> impl Fn(&BTreeMap<K, V>) -> Result<bool, E> {
387    move |i| {
388        i.iter()
389            .find_map(|(k, v)| match predicate(k, v) {
390                Ok(false) => Some(Ok(false)),
391                Err(e) => Some(Err(e)),
392                _ => None,
393            })
394            .unwrap_or(Ok(true))
395    }
396}
397
398/// Checks if all keys in the [`BTreeMap`] satisfy the predicate.
399///
400/// ```rust
401/// # use std::collections::BTreeMap;
402/// # use valust_utils::stream::all_btree_map_keys;
403/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
404/// # use valust_derive::Valust;
405/// #
406/// #[derive(Debug, Valust)]
407/// struct All {
408///     #[valid(func(all_btree_map_keys(|&k| k > 1)))]
409///     data: BTreeMap<u8, u8>
410/// }
411///
412/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
413/// let val = All::validate(all);
414/// assert!(val.is_err());
415/// println!("{}", val.unwrap_err().full_stringify());
416/// ```
417pub fn all_btree_map_keys<K, V>(
418    predicate: fn(&K) -> bool,
419) -> impl Fn(&BTreeMap<K, V>) -> bool {
420    move |i| i.keys().all(predicate)
421}
422
423/// Checks if all values in the [`BTreeMap`] satisfy the predicate.
424///
425/// ```rust
426/// # use std::collections::BTreeMap;
427/// # use valust_utils::stream::all_btree_map_values;
428/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
429/// # use valust_derive::Valust;
430/// #
431/// #[derive(Debug, Valust)]
432/// struct All {
433///     #[valid(func(all_btree_map_values(|&v| v > 3)))]
434///     data: BTreeMap<u8, u8>
435/// }
436///
437/// let all = Raw::<All> { data: vec![(1, 2), (2, 3), (3, 4)].into_iter().collect() };
438/// let val = All::validate(all);
439/// assert!(val.is_err());
440/// println!("{}", val.unwrap_err().full_stringify());
441/// ```
442pub fn all_btree_map_values<K, V>(
443    predicate: fn(&V) -> bool,
444) -> impl Fn(&BTreeMap<K, V>) -> bool {
445    move |i| i.values().all(predicate)
446}
447
448/// Checks if all keys in the [`BTreeMap`] satisfy the predicate (fallible ones accepted).
449///
450/// ```rust
451/// # use std::collections::BTreeMap;
452/// # use valust_utils::stream::try_btree_map_keys;
453/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
454/// # use valust_derive::Valust;
455/// #
456/// #[derive(Debug, Valust)]
457/// struct All {
458///     #[valid(func(try(try_btree_map_keys(|k: &String| k.parse::<i32>().map(|u| u > 1)))))]
459///     data: BTreeMap<String, u8>
460/// }
461///
462/// let all = Raw::<All> { data: vec![("1".to_owned(), 2), ("2".to_owned(), 3), ("3".to_owned(), 4)].into_iter().collect() };
463/// let val = All::validate(all);
464/// assert!(val.is_err());
465/// println!("{}", val.unwrap_err().full_stringify());
466/// ```
467pub fn try_btree_map_keys<K, V, E>(
468    predicate: fn(&K) -> Result<bool, E>,
469) -> impl Fn(&BTreeMap<K, V>) -> Result<bool, E> {
470    move |i| {
471        i.keys()
472            .find_map(|k| match predicate(k) {
473                Ok(false) => Some(Ok(false)),
474                Err(e) => Some(Err(e)),
475                _ => None,
476            })
477            .unwrap_or(Ok(true))
478    }
479}
480
481/// Checks if all values in the [`BTreeMap`] satisfy the predicate (fallible ones accepted).
482///
483/// ```rust
484/// # use std::collections::BTreeMap;
485/// # use valust_utils::stream::try_btree_map_values;
486/// # use valust::{Validate, Raw, error::display::ErrorDisplay};
487/// # use valust_derive::Valust;
488/// #
489/// #[derive(Debug, Valust)]
490/// struct All {
491///     #[valid(func(try(try_btree_map_values(|v: &String| v.parse::<i32>().map(|u| u > 3)))))]
492///     data: BTreeMap<u8, String>
493/// }
494///
495/// let all = Raw::<All> { data: vec![(1, "2".to_owned()), (2, "3".to_owned()), (3, "4".to_owned())].into_iter().collect() };
496/// let val = All::validate(all);
497/// assert!(val.is_err());
498/// println!("{}", val.unwrap_err().full_stringify());
499/// ```
500pub fn try_btree_map_values<K, V, E>(
501    predicate: fn(&V) -> Result<bool, E>,
502) -> impl Fn(&BTreeMap<K, V>) -> Result<bool, E> {
503    move |i| {
504        i.values()
505            .find_map(|v| match predicate(v) {
506                Ok(false) => Some(Ok(false)),
507                Err(e) => Some(Err(e)),
508                _ => None,
509            })
510            .unwrap_or(Ok(true))
511    }
512}