1use crate::{Err, GString, GStringError, Validator};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
9pub struct NotValidatedGString<
10 V: Validator,
11 const MIN: usize,
12 const MAX: usize,
13 const ASCII_ONLY: bool,
14>(GString<V, MIN, MAX, ASCII_ONLY>);
15
16impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
17 NotValidatedGString<V, MIN, MAX, ASCII_ONLY>
18{
19 #[inline(always)]
20 pub fn validate(self) -> Result<GString<V, MIN, MAX, ASCII_ONLY>, GStringError<V::Err>> {
21 V::validate(&self.0).map_err(GStringError::Validation)?;
22 Ok(self.0)
23 }
24}
25
26macro_rules! errpanic {
27 ($expr:expr) => {
28 match $expr {
29 Ok(v) => v,
30 Err(Err::TooShort(_)) => {
31 panic!("minimum length below MIN")
32 }
33 Err(Err::TooLong(_)) => {
34 panic!("maximum length exceeds MAX")
35 }
36 Err(Err::NotAscii) => {
37 panic!("only ASCII characters are allowed")
38 }
39 }
40 };
41}
42
43impl<V: Validator, const MIN: usize, const MAX: usize, const ASCII_ONLY: bool>
44 GString<V, MIN, MAX, ASCII_ONLY>
45{
46 #[doc(hidden)]
47 pub const fn __new(s: &str) -> NotValidatedGString<V, MIN, MAX, ASCII_ONLY> {
48 let ret = errpanic!(Self::stack_allocate(s));
49 errpanic!(ret.check_bounds());
50 errpanic!(ret.check_ascii());
51 NotValidatedGString(ret)
52 }
53}
54
55#[macro_export]
73macro_rules! gstring {
74 ($s:literal) => {
75 gstring!(
76 $s,
77 $crate::NoValidation,
78 { $crate::DEFAULT_MIN },
79 { $crate::DEFAULT_MAX },
80 { $crate::DEFAULT_ASCII_ONLY }
81 )
82 };
83 ($s:literal, $validator:ty) => {
84 gstring!(
85 $s,
86 $validator,
87 { $crate::DEFAULT_MIN },
88 { $crate::DEFAULT_MAX },
89 { $crate::DEFAULT_ASCII_ONLY }
90 )
91 };
92 ($s:literal, $validator:ty, $min:expr) => {
93 gstring!($s, $validator, $min, { $crate::DEFAULT_MAX }, {
94 $crate::DEFAULT_ASCII_ONLY
95 })
96 };
97 ($s:literal, $validator:ty, $min:expr, $max:expr) => {
98 gstring!($s, $validator, $min, $max, { $crate::DEFAULT_ASCII_ONLY })
99 };
100 ($s:literal, $validator:ty, $min:expr, $max:expr, $ascii_only:expr) => {{
101 const RET: $crate::NotValidatedGString<$validator, $min, $max, $ascii_only> =
102 $crate::GString::<$validator, $min, $max, $ascii_only>::__new($s);
103 RET
104 }};
105}
106
107#[macro_export]
120macro_rules! gformat {
121 ($fmt:expr $(, $args:expr)* ) => {
125 gformat!(
126 $fmt $(, $args)* ;
127 $crate::NoValidation,
128 { $crate::DEFAULT_MIN },
129 { $crate::DEFAULT_MAX },
130 { $crate::DEFAULT_ASCII_ONLY }
131 )
132 };
133
134 ($fmt:expr $(, $args:expr)* ; $validator:ty) => {
138 gformat!(
139 $fmt $(, $args)* ;
140 $validator,
141 { $crate::DEFAULT_MIN },
142 { $crate::DEFAULT_MAX },
143 { $crate::DEFAULT_ASCII_ONLY }
144 )
145 };
146
147 ($fmt:expr $(, $args:expr)* ; $validator:ty, $min:expr) => {
151 gformat!(
152 $fmt $(, $args)* ;
153 $validator,
154 $min,
155 { $crate::DEFAULT_MAX },
156 { $crate::DEFAULT_ASCII_ONLY }
157 )
158 };
159
160 ($fmt:expr $(, $args:expr)* ; $validator:ty, $min:expr, $max:expr) => {
164 gformat!(
165 $fmt $(, $args)* ;
166 $validator,
167 $min,
168 $max,
169 { $crate::DEFAULT_ASCII_ONLY }
170 )
171 };
172
173 (
177 $fmt:expr $(, $args:expr)* ;
178 $validator:ty,
179 $min:expr,
180 $max:expr,
181 $ascii_only:expr
182 ) => {{
183 #[cfg(feature = "alloc")]
184 {
185 let s = format!($fmt $(, $args)*);
186
187 $crate::GString::<
188 $validator,
189 $min,
190 $max,
191 $ascii_only
192 >::try_new(&s)
193 }
194
195 #[cfg(not(feature = "alloc"))]
196 compile_error!(
197 "gformat! requires the `alloc` feature"
198 );
199 }};
200}