1use serde::{Deserialize, Serialize};
9use std::fmt;
10
11#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
31pub enum RanvierError {
32 Message(String),
34 NotFound(String),
36 Validation(String),
38 Internal(String),
40}
41
42impl RanvierError {
43 pub fn message(msg: impl Into<String>) -> Self {
45 Self::Message(msg.into())
46 }
47
48 pub fn not_found(what: impl Into<String>) -> Self {
50 Self::NotFound(what.into())
51 }
52
53 pub fn validation(msg: impl Into<String>) -> Self {
55 Self::Validation(msg.into())
56 }
57
58 pub fn internal(msg: impl Into<String>) -> Self {
60 Self::Internal(msg.into())
61 }
62}
63
64impl fmt::Display for RanvierError {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 match self {
67 RanvierError::Message(s) => write!(f, "{s}"),
68 RanvierError::NotFound(s) => write!(f, "not found: {s}"),
69 RanvierError::Validation(s) => write!(f, "validation: {s}"),
70 RanvierError::Internal(s) => write!(f, "internal: {s}"),
71 }
72 }
73}
74
75impl std::error::Error for RanvierError {}
76
77impl From<String> for RanvierError {
78 fn from(s: String) -> Self {
79 RanvierError::Message(s)
80 }
81}
82
83impl From<&str> for RanvierError {
84 fn from(s: &str) -> Self {
85 RanvierError::Message(s.to_string())
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_display() {
95 assert_eq!(RanvierError::message("oops").to_string(), "oops");
96 assert_eq!(
97 RanvierError::not_found("user 42").to_string(),
98 "not found: user 42"
99 );
100 }
101
102 #[test]
103 fn test_serde_roundtrip() {
104 let err = RanvierError::validation("bad email");
105 let json = serde_json::to_string(&err).unwrap();
106 let back: RanvierError = serde_json::from_str(&json).unwrap();
107 assert_eq!(err, back);
108 }
109
110 #[test]
111 fn test_from_string() {
112 let err: RanvierError = "something went wrong".into();
113 assert!(matches!(err, RanvierError::Message(_)));
114 }
115}