relay_knowledge/domain/
error.rs1use std::{error::Error, fmt};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct DomainError {
6 pub field: &'static str,
7 pub message: String,
8}
9
10impl DomainError {
11 pub fn invalid(field: &'static str, message: impl Into<String>) -> Self {
13 Self {
14 field,
15 message: message.into(),
16 }
17 }
18}
19
20impl fmt::Display for DomainError {
21 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22 write!(formatter, "{}: {}", self.field, self.message)
23 }
24}
25
26impl Error for DomainError {}
27
28pub(crate) fn required_text(
29 field: &'static str,
30 value: impl Into<String>,
31) -> Result<String, DomainError> {
32 let text = value.into();
33 let trimmed = text.trim();
34 if trimmed.is_empty() {
35 return Err(DomainError::invalid(field, "must not be empty"));
36 }
37
38 Ok(trimmed.to_owned())
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 #[test]
46 fn displays_field_and_message() {
47 let error = DomainError::invalid("field", "failed");
48
49 assert_eq!(error.to_string(), "field: failed");
50 }
51}