Skip to main content

rust_rfc7807/
validation.rs

1use serde::{Deserialize, Serialize};
2
3/// A single field-level validation error.
4///
5/// Used within the `"errors"` extension key to report multiple validation
6/// failures in a structured format suitable for frontend form binding.
7///
8/// # Example
9///
10/// ```
11/// use rust_rfc7807::ValidationItem;
12///
13/// let item = ValidationItem::new("email", "must be a valid email address")
14///     .code("INVALID_EMAIL");
15///
16/// let json = serde_json::to_value(&item).unwrap();
17/// assert_eq!(json["field"], "email");
18/// assert_eq!(json["code"], "INVALID_EMAIL");
19/// ```
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
21pub struct ValidationItem {
22    /// The field path that failed validation (e.g., `"email"` or `"address.zip"`).
23    pub field: String,
24    /// A human-readable description of the validation failure.
25    pub message: String,
26    /// An optional machine-readable error code for this specific validation failure.
27    #[serde(skip_serializing_if = "Option::is_none")]
28    pub code: Option<String>,
29}
30
31impl ValidationItem {
32    /// Create a new validation item for the given field and message.
33    pub fn new(field: impl Into<String>, message: impl Into<String>) -> Self {
34        Self {
35            field: field.into(),
36            message: message.into(),
37            code: None,
38        }
39    }
40
41    /// Set an error code for this validation item.
42    pub fn code(mut self, code: impl Into<String>) -> Self {
43        self.code = Some(code.into());
44        self
45    }
46}