use std::collections::BTreeMap;
use std::fmt::{Debug, Display};
use bevy_reflect::{FromReflect, Reflect, TypePath};
use static_assertions::assert_impl_all;
#[derive(Clone, Reflect)]
#[reflect_value]
pub enum FieldError {
Missing,
TooShort {
current: u32,
min_length: u32,
max_length: u32,
unit: FieldUnit,
},
TooLong {
current: u32,
min_length: u32,
max_length: u32,
unit: FieldUnit,
},
Custom {
code: String,
description: String,
values: BTreeMap<String, String>,
},
}
impl FieldError {
pub fn error_code(&self) -> &str {
match self {
FieldError::Missing => "missing",
FieldError::TooShort {
unit: FieldUnit::Characters,
..
} => "too_short_chars",
FieldError::TooLong {
unit: FieldUnit::Characters,
..
} => "too_long_chars",
FieldError::Custom { code, .. } => code,
}
}
}
#[derive(Copy, Clone, Reflect)]
pub enum FieldUnit {
Characters,
}
impl Display for FieldUnit {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FieldUnit::Characters => write!(f, "characters"),
}
}
}
impl Debug for FieldError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
FieldError::Missing => write!(f, "The field is missing"),
FieldError::TooShort { current, min_length, max_length, unit } => write!(f, "The field is too short ({current}); it should be between {min_length} and {max_length} {unit}."),
FieldError::TooLong { current, min_length, max_length, unit } => write!(f, "The field is too long ({current}); it should be between {min_length} and {max_length} {unit}."),
FieldError::Custom {
code,
description,
values,
} => write!(f, "[{code}] {description} {values:?}"),
}
}
}
pub type FieldErrors = Vec<FieldError>;
assert_impl_all!(FieldErrors: Reflect, FromReflect, TypePath);