1use crate::attribute::{
2 MetaListCustomMessage, MetaListFieldValidation, MetaListStructValidation,
3 MetaNameValueCustomMessage, MetaNameValueFieldValidation, MetaNameValueStructValidation,
4 MetaPathCustomMessage, MetaPathFieldValidation, MetaPathStructValidation,
5};
6use itertools::Itertools;
7use proc_macro2::TokenStream;
8use quote::quote;
9use syn::spanned::Spanned;
10
11pub fn object_errors_tokens() -> TokenStream {
12 quote!(::serde_valid::validation::Errors::Object(
13 ::serde_valid::validation::ObjectErrors::new(
14 __rule_vec_errors,
15 __property_vec_errors_map
16 .into_iter()
17 .map(|(field, errors)| {
18 let mut __field_items_errors = vec![];
19 let mut __field_properties_errors = None;
20 let mut __field_errors: ::serde_valid::validation::VecErrors = errors
21 .into_iter()
22 .filter_map(|error| match error {
23 ::serde_valid::validation::Error::Items(__array_errors) => {
24 __field_items_errors.push(__array_errors);
25 None
26 }
27 ::serde_valid::validation::Error::Properties(__object_errors) => {
28 __field_properties_errors = Some(__object_errors);
29 None
30 }
31 _ => Some(error),
32 })
33 .collect();
34
35 if let Some(__object_errors) = __field_properties_errors {
36 __field_errors.extend(__object_errors.errors);
37
38 (
39 field,
40 ::serde_valid::validation::Errors::Object(
41 ::serde_valid::validation::ObjectErrors::new(
42 __field_errors,
43 __object_errors.properties,
44 ),
45 ),
46 )
47 } else if !__field_items_errors.is_empty() {
48 let __array_errors = __field_items_errors
49 .into_iter()
50 .reduce(|a, b| a.merge(b))
51 .unwrap();
52 __field_errors.extend(__array_errors.errors);
53
54 (
55 field,
56 ::serde_valid::validation::Errors::Array(
57 ::serde_valid::validation::error::ArrayErrors::new(
58 __field_errors,
59 __array_errors.items,
60 ),
61 ),
62 )
63 } else {
64 (
65 field,
66 ::serde_valid::validation::Errors::NewType(__field_errors),
67 )
68 }
69 })
70 .collect()
71 )
72 ))
73}
74
75pub fn array_errors_tokens() -> TokenStream {
76 quote!(::serde_valid::validation::Errors::Array(
77 ::serde_valid::validation::error::ArrayErrors::new(
78 __rule_vec_errors,
79 __item_vec_errors_map
80 .into_iter()
81 .map(|(index, errors)| {
82 let mut __field_items_errors = vec![];
83 let mut __field_properties_errors = None;
84 let mut __field_errors: ::serde_valid::validation::VecErrors = errors
85 .into_iter()
86 .filter_map(|error| match error {
87 ::serde_valid::validation::Error::Items(__array_errors) => {
88 __field_items_errors.push(__array_errors);
89 None
90 }
91 ::serde_valid::validation::Error::Properties(__object_errors) => {
92 __field_properties_errors = Some(__object_errors);
93 None
94 }
95 _ => Some(error),
96 })
97 .collect();
98
99 if let Some(__object_errors) = __field_properties_errors {
100 __field_errors.extend(__object_errors.errors);
101
102 (
103 index,
104 ::serde_valid::validation::Errors::Object(
105 ::serde_valid::validation::ObjectErrors::new(
106 __field_errors,
107 __object_errors.properties,
108 ),
109 ),
110 )
111 } else if !__field_items_errors.is_empty() {
112 let __array_errors = __field_items_errors
113 .into_iter()
114 .reduce(|a, b| a.merge(b))
115 .unwrap();
116 __field_errors.extend(__array_errors.errors);
117
118 (
119 index,
120 ::serde_valid::validation::Errors::Array(
121 ::serde_valid::validation::error::ArrayErrors::new(
122 __field_errors,
123 __array_errors.items,
124 ),
125 ),
126 )
127 } else {
128 (
129 index,
130 ::serde_valid::validation::Errors::NewType(__field_errors),
131 )
132 }
133 })
134 .collect()
135 )
136 ))
137}
138
139pub fn new_type_errors_tokens() -> TokenStream {
140 quote!(::serde_valid::validation::Errors::NewType(
141 __rule_vec_errors
142 .into_iter()
143 .chain(
144 __item_vec_errors_map
145 .remove(&0)
146 .unwrap_or(vec![])
147 .into_iter()
148 )
149 .collect()
150 ))
151}
152
153#[derive(Debug)]
154pub struct Error(syn::Error);
155
156impl Error {
157 fn new<Message: Into<String>>(span: proc_macro2::Span, message: Message) -> Self {
158 Self(syn::Error::new(span, message.into()))
159 }
160
161 #[allow(dead_code)]
162 pub fn macro_debug<Message: Into<String>>(span: proc_macro2::Span, message: Message) -> Self {
163 Error::new(span, message)
164 }
165
166 pub fn unit_struct_not_supported(input: &syn::DeriveInput) -> Self {
167 Self::new(
168 input.span(),
169 "#[derive(Validate)] does not support Unit Struct.",
170 )
171 }
172
173 pub fn union_not_supported(input: &syn::DeriveInput) -> Self {
174 Self::new(input.span(), "#[derive(Validate)] does not support Union.")
175 }
176
177 pub fn validate_meta_name_value_not_supported(name_value: &syn::MetaNameValue) -> Self {
178 Self::new(name_value.span(), "#[validate = ???] not supported.")
179 }
180
181 pub fn meta_path_validation_need_value(path: &syn::Path, validation_type: &str) -> Self {
182 Self::new(
183 path.span(),
184 format!("#[validate({validation_type}(???))] needs validation path."),
185 )
186 }
187
188 pub fn meta_path_custom_message_need_value(
189 path: &syn::Path,
190 custom_message_type: &str,
191 ) -> Self {
192 Self::new(
193 path.span(),
194 format!("#[validate(..., {custom_message_type}(???))] needs custom message path."),
195 )
196 }
197
198 pub fn meta_list_validation_need_value(path: &syn::Path, validation_type: &str) -> Self {
199 Self::new(
200 path.span(),
201 format!("#[validate({validation_type}(???, ...))] needs validation list."),
202 )
203 }
204
205 pub fn meta_list_custom_message_need_value(
206 path: &syn::Path,
207 custom_message_type: &str,
208 ) -> Self {
209 Self::new(
210 path.span(),
211 format!("#[validate(..., {custom_message_type}(???, ...))] needs custom message list."),
212 )
213 }
214
215 pub fn meta_name_value_validation_need_value(path: &syn::Path, validation_type: &str) -> Self {
216 Self::new(
217 path.span(),
218 format!("#[validate({validation_type} = ???)] needs validation value."),
219 )
220 }
221
222 pub fn meta_name_value_custom_message_need_value(
223 path: &syn::Path,
224 validation_type: &str,
225 ) -> Self {
226 Self::new(
227 path.span(),
228 format!("#[validate(..., {validation_type} = ???)] needs custom message value."),
229 )
230 }
231
232 pub fn validate_attribute_parse_error(attribute: &syn::Attribute, error: &syn::Error) -> Self {
233 Self::new(
234 attribute.span(),
235 format!("#[validate] parse error: {error}"),
236 )
237 }
238
239 pub fn field_validation_type_required(attribute: &syn::Attribute) -> Self {
240 let filterd_candidates: Vec<&str> = (MetaPathFieldValidation::iter().map(|x| x.name()))
241 .chain(MetaListFieldValidation::iter().map(|x| x.name()))
242 .chain(MetaNameValueFieldValidation::iter().map(|x| x.name()))
243 .collect::<Vec<_>>();
244
245 Self::new(
246 attribute.meta.span(),
247 format!("#[validate(???)] needs validation type. Is it one of the following?\n{filterd_candidates:#?}"),
248 )
249 }
250
251 pub fn field_validation_type_unknown(path: &syn::Path, unknown: &str) -> Self {
252 let candidates = &(MetaPathFieldValidation::iter().map(|x| x.name()))
253 .chain(MetaListFieldValidation::iter().map(|x| x.name()))
254 .chain(MetaNameValueFieldValidation::iter().map(|x| x.name()))
255 .unique()
256 .sorted()
257 .collect::<Vec<_>>();
258
259 let filterd_candidates =
260 did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec());
261
262 Self::new(
263 path.span(),
264 format!("`{unknown}` is unknown validation type. Is it one of the following?\n{filterd_candidates:#?}"),
265 )
266 }
267
268 pub fn struct_validation_type_required(attribute: &syn::Attribute) -> Self {
269 let filterd_candidates: Vec<&str> = (MetaPathStructValidation::iter().map(|x| x.name()))
270 .chain(MetaListStructValidation::iter().map(|x| x.name()))
271 .chain(MetaNameValueStructValidation::iter().map(|x| x.name()))
272 .collect::<Vec<_>>();
273
274 Self::new(
275 attribute.meta.span(),
276 format!("#[validate(???)] needs validation type. Is it one of the following?\n{filterd_candidates:#?}"),
277 )
278 }
279
280 pub fn struct_validation_type_unknown(path: &syn::Path, unknown: &str) -> Self {
281 let candidates = &(MetaPathStructValidation::iter().map(|x| x.name()))
282 .chain(MetaListStructValidation::iter().map(|x| x.name()))
283 .chain(MetaNameValueStructValidation::iter().map(|x| x.name()))
284 .collect::<Vec<_>>();
285
286 let filterd_candidates =
287 did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec());
288
289 Self::new(
290 path.span(),
291 format!("`{unknown}` is unknown validation type. Is it one of the following?\n{filterd_candidates:#?}"),
292 )
293 }
294
295 pub fn unknown_custom_message_type(path: &syn::Path, unknown: &str) -> Self {
296 let candidates = &(MetaPathCustomMessage::iter().map(|x| x.name()))
297 .chain(MetaListCustomMessage::iter().map(|x| x.name()))
298 .chain(MetaNameValueCustomMessage::iter().map(|x| x.name()))
299 .unique()
300 .sorted()
301 .collect::<Vec<_>>();
302
303 let filterd_candidates =
304 did_you_mean(unknown, candidates).unwrap_or_else(|| candidates.to_vec());
305
306 Self::new(
307 path.span(),
308 format!("`{unknown}` is unkown error message type. Is it one of the following?\n{filterd_candidates:#?}"),
309 )
310 }
311
312 pub fn validate_enumerate_need_array(path: impl Spanned) -> Self {
313 Self::new(
314 path.span(),
315 "#[validate(enumerate = ???)] needs literal array only.",
316 )
317 }
318
319 pub fn validate_custom_meta_list_need_function_or_closure(span: impl Spanned) -> Self {
320 Self::new(
321 span.span(),
322 "#[validate(custom(???))] needs function or closure.",
323 )
324 }
325
326 pub fn validate_custom_tail_error(nested: &crate::types::NestedMeta) -> Self {
327 Self::new(
328 nested.span(),
329 "#[validate(custom(???))] supports only 1 item.",
330 )
331 }
332
333 pub fn validate_custom_meta_name_value_need_function_or_closure(span: impl Spanned) -> Self {
334 Self::new(
335 span.span(),
336 "#[validate(custom = ???)] needs function or closure.",
337 )
338 }
339
340 pub fn custom_message_parse_error(ident: &syn::Ident, error: &syn::Error) -> Self {
341 Self::new(
342 ident.span(),
343 format!("#[validate(..., {ident})] parse error: {error}"),
344 )
345 }
346
347 pub fn message_fn_meta_name_value_needs_function_or_closure(
348 meta_name_value: &syn::MetaNameValue,
349 ) -> Self {
350 Self::new(
351 meta_name_value.span(),
352 "#[validate(..., message_fn = ???)] needs function or closure.",
353 )
354 }
355
356 #[cfg(feature = "fluent")]
357 pub fn fluent_need_item(message_type: &MetaListCustomMessage, path: &syn::Path) -> Self {
358 Self::new(
359 path.span(),
360 format!("`{}` needs items.", message_type.name()),
361 )
362 }
363
364 #[cfg(feature = "fluent")]
365 pub fn fluent_allow_key(
366 message_type: &MetaListCustomMessage,
367 nested_meta: &crate::types::NestedMeta,
368 ) -> Self {
369 Self::new(
370 nested_meta.span(),
371 format!(
372 "#[validate(..., {}(???, ...))] allows only fluent key str",
373 message_type.name()
374 ),
375 )
376 }
377
378 #[cfg(feature = "fluent")]
379 pub fn fluent_allow_args(
380 message_type: &MetaListCustomMessage,
381 nested_meta: &crate::types::NestedMeta,
382 ) -> Self {
383 Self::new(
384 nested_meta.span(),
385 format!(
386 "#[validate(..., {}(..., ???))] allows only fluent args key value.",
387 message_type.name()
388 ),
389 )
390 }
391
392 #[cfg(feature = "fluent")]
393 pub fn l10n_need_fn_call(expr: &syn::Expr) -> Self {
394 Self::new(
395 expr.span(),
396 "#[validate(..., message_l10n = ???)] needs fn calling.".to_string(),
397 )
398 }
399
400 #[cfg(feature = "fluent")]
401 pub fn l10n_fn_name_not_allow(fn_name: &syn::Expr) -> Self {
402 Self::new(
403 fn_name.span(),
404 "#[validate(..., message_l10n = ???(...))] allows only \"fluent\".".to_string(),
405 )
406 }
407
408 #[cfg(feature = "fluent")]
409 pub fn fluent_id_must_be_str_lit(expr: &syn::Expr) -> Self {
410 Self::new(
411 expr.span(),
412 "#[validate(..., message_l10n = fluent(???, ...))] allow only string literal of the fluent id.",
413 )
414 }
415
416 #[cfg(feature = "fluent")]
417 pub fn fluent_id_not_found(paren: &syn::token::Paren) -> Self {
418 Self::new(
419 paren.span.span(),
420 "#[validate(..., message_l10n = fluent(???))] need the fluent id.",
421 )
422 }
423
424 #[cfg(feature = "fluent")]
425 pub fn fluent_allow_arg(expr: &syn::Expr) -> Self {
426 Self::new(
427 expr.span(),
428 "#[validate(..., message_l10n = fluent(..., ???))] allows only \"key=value\" of the fluent arg."
429 .to_string(),
430 )
431 }
432
433 pub fn literal_only(span: impl Spanned) -> Self {
434 Self::new(span.span(), "Allow literal only.")
435 }
436
437 pub fn numeric_literal_only(lit: &syn::Lit) -> Self {
438 Self::new(lit.span(), "Allow numeric literal only.")
439 }
440
441 pub fn str_literal_only(lit: &syn::Lit) -> Self {
442 Self::new(lit.span(), "Allow str literal only.")
443 }
444
445 pub fn too_many_list_items(nested_meta: &syn::Meta) -> Self {
446 Self::new(nested_meta.span(), "Too many list items.")
447 }
448
449 pub fn to_compile_error(&self) -> TokenStream {
450 self.0.to_compile_error()
451 }
452
453 pub fn validate_custom_does_not_support_custom_message(meta: &syn::Meta) -> Self {
454 Self::new(
455 meta.span(),
456 "#[validate(custon(...), ???)] does not support custom error message.",
457 )
458 }
459}
460
461fn did_you_mean<'a, T, I>(unknown: &'a str, candidates: I) -> Option<Vec<&'a str>>
462where
463 T: AsRef<str> + 'a,
464 I: IntoIterator<Item = &'a T>,
465{
466 let mut filterd = candidates
467 .into_iter()
468 .map(|candidate| {
469 (
470 ::strsim::jaro_winkler(unknown, candidate.as_ref()),
471 candidate.as_ref(),
472 )
473 })
474 .filter(|(confidence, _)| *confidence > 0.8)
475 .collect::<Vec<_>>();
476
477 if filterd.is_empty() {
478 None
479 } else {
480 filterd.sort_by(|a, b| b.0.partial_cmp(&a.0).unwrap_or(std::cmp::Ordering::Equal));
481 Some(
482 filterd
483 .into_iter()
484 .map(|(_, candidate)| candidate)
485 .collect(),
486 )
487 }
488}
489
490pub type Errors = Vec<Error>;
491
492pub fn to_compile_errors(errors: Errors) -> TokenStream {
493 let compile_errors = errors.iter().map(Error::to_compile_error);
494 quote!(#(#compile_errors)*)
495}