1use serde::Serialize;
2use std::fmt::{self, Display};
3
4#[derive(Debug, Serialize)]
5pub struct ValidationError {
6 pub code: String,
7 pub message: String, }
9impl fmt::Display for ValidationError {
10 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11 write!(f, "[{}] {}", self.code, self.message)
12 }
13}
14impl From<ValidationError> for String {
15 fn from(err: ValidationError) -> Self {
16 format!("[{}] {}", err.code, err.message)
17 }
18}
19
20pub fn validate_field<T>(
32 field_name: &str,
33 value: Option<T>,
34 min: Option<T>,
35 max: Option<T>,
36 error_code_prefix: &str,
37) -> Result<(), ValidationError>
38where
39 T: PartialOrd + Display + Copy,
40{
41 let val = value.ok_or(ValidationError {
42 code: format!("{}.{}.missing", error_code_prefix, field_name),
43 message: format!("{} must be provided.", field_name),
44 })?;
45
46 if let Some(min_val) = min {
47 if val < min_val {
48 return Err(ValidationError {
49 code: format!("{}.{}.too_small.{}", error_code_prefix, field_name, min_val),
50 message: format!(
51 "{} must be greater than or equal to {}.",
52 field_name, min_val
53 ),
54 });
55 }
56 }
57
58 if let Some(max_val) = max {
59 if val > max_val {
60 return Err(ValidationError {
61 code: format!("{}.{}.too_large.{}", error_code_prefix, field_name, max_val),
62 message: format!("{} must be less than or equal to {}.", field_name, max_val),
63 });
64 }
65 }
66
67 Ok(())
68}