garde/rules/length/
chars.rs

1//! Implemented by string-like types for which we can retrieve the number of [Unicode Scalar Values](https://www.unicode.org/glossary/#unicode_scalar_value).
2//!
3//! See also: [`chars` on `str`](https://doc.rust-lang.org/std/primitive.str.html#method.chars).
4
5use crate::error::Error;
6
7pub fn apply<T: Chars>(v: &T, (min, max): (usize, usize)) -> Result<(), Error> {
8    v.validate_num_chars(min, max)
9}
10
11pub trait Chars {
12    fn validate_num_chars(&self, min: usize, max: usize) -> Result<(), Error>;
13}
14
15impl<T: HasChars> Chars for T {
16    fn validate_num_chars(&self, min: usize, max: usize) -> Result<(), Error> {
17        super::check_len(self.num_chars(), min, max)
18    }
19}
20
21impl<T: Chars> Chars for Option<T> {
22    fn validate_num_chars(&self, min: usize, max: usize) -> Result<(), Error> {
23        match self {
24            Some(v) => v.validate_num_chars(min, max),
25            None => Ok(()),
26        }
27    }
28}
29
30pub trait HasChars {
31    fn num_chars(&self) -> usize;
32}
33
34macro_rules! impl_via_chars {
35    ($(in <$lifetime:lifetime>)? $T:ty) => {
36        impl<$($lifetime)?> HasChars for $T {
37            fn num_chars(&self) -> usize {
38                self.chars().count()
39            }
40        }
41    };
42}
43
44impl_via_chars!(std::string::String);
45impl_via_chars!(in<'a> &'a std::string::String);
46impl_via_chars!(in<'a> &'a str);
47impl_via_chars!(in<'a> std::borrow::Cow<'a, str>);
48impl_via_chars!(std::rc::Rc<str>);
49impl_via_chars!(std::sync::Arc<str>);
50impl_via_chars!(std::boxed::Box<str>);
51
52macro_rules! impl_via_len {
53    ($(in<$lifetime:lifetime>)? $T:ty) => {
54        impl<$($lifetime)?> HasChars for $T {
55            fn num_chars(&self) -> usize {
56                self.len()
57            }
58        }
59    };
60}
61
62impl_via_len!(in<'a> &'a [char]);
63impl_via_len!(std::sync::Arc<[char]>);
64impl_via_len!(std::rc::Rc<[char]>);
65impl_via_len!(std::boxed::Box<[char]>);
66impl_via_len!(std::vec::Vec<char>);