Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion validator/src/display_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ impl fmt::Display for ValidationError {
if let Some(msg) = self.message.as_ref() {
write!(fmt, "{}", msg)
} else {
write!(fmt, "Validation error: {} [{:?}]", self.code, self.params)
write!(fmt, "Validation error: {} [{}]", self.code, self.params)
}
}
}
Expand Down
74 changes: 72 additions & 2 deletions validator/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ use serde_json::{to_value, Value};
pub struct ValidationError {
pub code: Cow<'static, str>,
pub message: Option<Cow<'static, str>>,
pub params: HashMap<Cow<'static, str>, Value>,
pub params: ValidationErrorParams,
}

impl ValidationError {
pub fn new(code: &'static str) -> ValidationError {
ValidationError { code: Cow::from(code), message: None, params: HashMap::new() }
ValidationError { code: Cow::from(code), message: None, params: Default::default() }
}

pub fn add_param<T: Serialize>(&mut self, name: Cow<'static, str>, val: &T) {
Expand Down Expand Up @@ -206,3 +206,73 @@ impl std::error::Error for ValidationErrors {
None
}
}

#[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct ValidationErrorParams(HashMap<Cow<'static, str>, Value>);

impl std::fmt::Display for ValidationErrorParams {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = if f.alternate() {
serde_json::to_string_pretty(&self.0)
} else {
serde_json::to_string(&self.0)
}.map_err(|_| std::fmt::Error)?;
f.write_str(&s);
Comment thread
mscofield0 marked this conversation as resolved.
Outdated
}
}

impl std::ops::Deref for ValidationErrorParams {
type Target = HashMap<Cow<'static, str>, Value>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl std::ops::DerefMut for ValidationErrorParams {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_params_display_empty() {
let params = ValidationErrorParams::default();
assert_eq!(format!("{}", params), "{}");
}

#[test]
fn test_params_display_with_values() {
let mut params = ValidationErrorParams::default();
params.insert(Cow::Borrowed("min"), serde_json::json!(5));
assert_eq!(format!("{}", params), r#"{"min":5}"#);
}

#[test]
fn test_params_display_alternate() {
let mut params = ValidationErrorParams::default();
params.insert(Cow::Borrowed("min"), serde_json::json!(5));
let pretty = format!("{:#}", params);
assert!(pretty.contains('\n'), "alternate format should be pretty-printed");
assert!(pretty.contains("\"min\": 5"));
}

#[test]
fn test_params_deref() {
let mut params = ValidationErrorParams::default();
params.insert(Cow::Borrowed("key"), serde_json::json!("value"));
assert_eq!(params.len(), 1);
assert!(params.contains_key("key"));
}

#[test]
fn test_params_deref_mut() {
let mut params = ValidationErrorParams::default();
params.insert(Cow::Borrowed("key"), serde_json::json!(42));
assert_eq!(params.get("key"), Some(&serde_json::json!(42)));
}
}
11 changes: 11 additions & 0 deletions validator/tests/display.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
#[test]
fn test_validation_error_display_without_message() {
use std::borrow::Cow;
use validator::ValidationError;

let mut err = ValidationError::new("length");
err.add_param(Cow::Borrowed("min"), &1);
let display = format!("{}", err);
assert_eq!(display, r#"Validation error: length [{"min":1}]"#);
}

#[cfg(feature = "derive")]
mod tests {
use validator::Validate;
Expand Down