1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Service provider

use std::sync::Arc;

use bytes::Bytes;
use dashmap::DashMap;
use futures::future::{ready, BoxFuture};

/// Service provider
pub trait Provider<S: Sync + Send>: Sync + Send {
    //fn name(&self) -> &'static str;
    /// Call a method of this service
    fn call(
        &self,
        session: &Arc<S>,
        service: &str,
        method: &str,
        data: Bytes,
    ) -> BoxFuture<'static, Result<Bytes, ProviderError>>;
}

/// This trait adds a service name to the service provider
/// which is used for the router.
pub trait NamedProvider<S: Sync + Send>: Provider<S> {
    /// Name of the provided service
    const NAME: &'static str;
}

/// The response type used when calling providers.
pub type Response<T> = Result<T, ProviderError>;

/// Error returned by the `Provider::call` method
#[derive(Debug)]
pub enum ProviderError {
    /// The requested service was not found.
    ServiceNotFound,
    /// The requested method was not found.
    MethodNotFound,
    /// An error occured while deserializing the request.
    DeserializerError(serde_json::Error),
    /// An error occured while serializing the response.
    SerializerError(serde_json::Error),
    /// The request did not validate
    ValidationError(validator::ValidationErrors),
    /// Something else went wrong.
    InternalError(Box<dyn std::error::Error + Sync + Send>),
    /// The server is being shut down and therefore request processing is
    /// impossible. This error rarely if ever happens and should not be
    /// generated by user code.
    Shutdown,
}

impl ProviderError {
    /// Convert error to Bytes
    pub fn to_bytes(&self) -> Bytes {
        match self {
            Self::ServiceNotFound => "ServiceNotFound",
            Self::MethodNotFound => "MethodNotFound",
            // SerializerError maps to InternalError as this is nothing
            // the consumer can do about.
            Self::SerializerError(_) => "InternalError",
            Self::DeserializerError(_) => "DeserializerError",
            Self::ValidationError(_) => "ValidationError",
            Self::InternalError(_) => "InternalError",
            // This erros should never actually be returned to the client.
            Self::Shutdown => "InternalError",
        }
        .into()
    }
}

/// The router is used to register service provider and dispatch
/// requests.
pub struct Router<S: Sync + Send> {
    services: DashMap<String, Box<dyn Provider<S>>>,
}

impl<S: Sync + Send> Router<S> {
    /// Create an empty router
    pub fn new() -> Self {
        Self {
            services: DashMap::new(),
        }
    }
    /// Add service provider to this router
    pub fn service<P>(&self, provider: P)
    where
        P: NamedProvider<S> + 'static,
    {
        self.services.insert(P::NAME.to_owned(), Box::new(provider));
    }
}

impl<S: Sync + Send> Provider<S> for Router<S> {
    fn call(
        &self,
        session: &Arc<S>,
        service: &str,
        method: &str,
        data: Bytes,
    ) -> BoxFuture<'static, Result<Bytes, ProviderError>> {
        match self.services.get(service) {
            Some(provider) => provider.call(session, service, method, data),
            None => Box::pin(ready(Err(ProviderError::ServiceNotFound))),
        }
    }
}

impl<S: Sync + Send> Default for Router<S> {
    fn default() -> Self {
        Self::new()
    }
}