Skip to main content

modo/tenant/
traits.rs

1use std::future::Future;
2
3use crate::Result;
4
5use super::TenantId;
6
7/// Required bound on the resolved tenant type.
8///
9/// Provides the string value recorded into the `tenant_id` tracing field by
10/// [`TenantMiddleware`](super::TenantMiddleware) after a successful resolve.
11pub trait HasTenantId {
12    /// Returns the tenant's unique identifier for tracing spans.
13    fn tenant_id(&self) -> &str;
14}
15
16/// Extracts a [`TenantId`] from an HTTP request.
17///
18/// Takes `&mut Parts` so strategies like [`PathPrefixStrategy`](super::PathPrefixStrategy)
19/// can rewrite the URI.
20pub trait TenantStrategy: Send + Sync + 'static {
21    /// Extract a tenant identifier from request parts.
22    ///
23    /// # Errors
24    ///
25    /// Returns [`Error`](crate::Error) (typically 400 Bad Request) when the
26    /// identifier cannot be extracted (missing header, wrong host, etc.).
27    fn extract(&self, parts: &mut http::request::Parts) -> Result<TenantId>;
28}
29
30/// Resolves a [`TenantId`] to an app-defined tenant type.
31///
32/// Uses RPITIT so it is **not** object-safe; the resolver must be a concrete type.
33pub trait TenantResolver: Send + Sync + 'static {
34    /// The resolved tenant type.
35    type Tenant: HasTenantId + Send + Sync + Clone + 'static;
36
37    /// Look up a tenant by the extracted identifier.
38    ///
39    /// # Errors
40    ///
41    /// Returns [`Error`](crate::Error) when the tenant cannot be found or the
42    /// lookup fails (e.g., database error).
43    fn resolve(&self, id: &TenantId) -> impl Future<Output = Result<Self::Tenant>> + Send;
44}