metabase_api_rs/service/
traits.rs1use crate::core::error::Error;
6use async_trait::async_trait;
7use std::fmt::Debug;
8
9#[derive(Debug, thiserror::Error)]
11pub enum ServiceError {
12 #[error("Validation error: {0}")]
13 Validation(String),
14
15 #[error("Business rule violation: {0}")]
16 BusinessRule(String),
17
18 #[error("Not found: {0}")]
19 NotFound(String),
20
21 #[error("Unauthorized: {0}")]
22 Unauthorized(String),
23
24 #[error("Repository error: {0}")]
25 Repository(#[from] crate::repository::traits::RepositoryError),
26
27 #[error("Other error: {0}")]
28 Other(String),
29}
30
31impl From<Error> for ServiceError {
32 fn from(err: Error) -> Self {
33 match err {
34 Error::NotFound(msg) => ServiceError::NotFound(msg),
35 Error::Authentication(msg) => ServiceError::Unauthorized(msg),
36 Error::Validation(msg) => ServiceError::Validation(msg),
37 _ => ServiceError::Other(err.to_string()),
38 }
39 }
40}
41
42impl From<ServiceError> for Error {
43 fn from(err: ServiceError) -> Self {
44 match err {
45 ServiceError::NotFound(msg) => Error::NotFound(msg),
46 ServiceError::Unauthorized(msg) => Error::Authentication(msg),
47 ServiceError::Validation(msg) => Error::Validation(msg),
48 _ => Error::Unknown(err.to_string()),
49 }
50 }
51}
52
53pub type ServiceResult<T> = Result<T, ServiceError>;
55
56#[async_trait]
58pub trait Service: Send + Sync {
59 fn name(&self) -> &str;
61
62 async fn validate(&self) -> ServiceResult<()> {
64 Ok(())
65 }
66}
67
68pub struct ValidationContext {
70 errors: Vec<String>,
71}
72
73impl ValidationContext {
74 pub fn new() -> Self {
76 Self { errors: Vec::new() }
77 }
78
79 pub fn add_error(&mut self, error: impl Into<String>) {
81 self.errors.push(error.into());
82 }
83
84 pub fn is_valid(&self) -> bool {
86 self.errors.is_empty()
87 }
88
89 pub fn errors(&self) -> &[String] {
91 &self.errors
92 }
93
94 pub fn to_result(self) -> ServiceResult<()> {
96 if self.is_valid() {
97 Ok(())
98 } else {
99 Err(ServiceError::Validation(self.errors.join(", ")))
100 }
101 }
102}
103
104impl Default for ValidationContext {
105 fn default() -> Self {
106 Self::new()
107 }
108}