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}