Skip to main content

omnia_sdk/
api.rs

1//! # API
2//!
3//! The api module provides the entry point to the public API. Requests are routed
4//! to the appropriate handler for processing, returning a response that can
5//! be serialized to a JSON object or directly to HTTP.
6//!
7//! ## Example Usage
8//!
9//! ```rust,ignore
10//! use omnia_sdk::{Body, Client, Headers};
11//!
12//! // Create a client (typestate builder)
13//! let client = Client::new("alice").provider(provider);
14//!
15//! // Simple request without headers
16//! let response = client.request(my_request).await?;
17//!
18//! // Request with headers
19//! let response = client.request(my_request).headers(my_headers).await?;
20//! ```
21
22mod into_http;
23mod reply;
24mod request;
25
26use std::fmt::Debug;
27use std::sync::Arc;
28
29pub use self::into_http::*;
30pub use self::reply::*;
31pub use self::request::*;
32
33/// Provider trait for request handlers.
34pub trait Provider: Send + Sync {}
35impl<T> Provider for T where T: Send + Sync {}
36
37/// Build an API client to execute the request.
38///
39/// The client is the main entry point for making API requests. It holds
40/// the provider configuration and provides methods to create the request
41/// router.
42#[derive(Clone, Debug)]
43pub struct Client<P> {
44    /// The owning tenant/namespace.
45    owner: Arc<str>,
46
47    /// The provider to use while handling of the request.
48    provider: Arc<P>,
49}
50
51impl Client<NoProvider> {
52    /// Start building a new `Client` by setting the owner.
53    #[must_use]
54    pub fn new(owner: impl Into<String>) -> Self {
55        Self {
56            owner: Arc::<str>::from(owner.into()),
57            provider: Arc::new(NoProvider),
58        }
59    }
60
61    /// Finish building the client by providing the provider implementation.
62    #[must_use]
63    pub fn provider<P: Provider>(self, provider: P) -> Client<P> {
64        Client {
65            owner: self.owner,
66            provider: Arc::new(provider),
67        }
68    }
69}
70
71impl<P: Provider> Client<P> {
72    /// Create a new [`RequestHandler`] with no headers.
73    pub fn request<R: Handler<P>>(
74        &self, request: R,
75    ) -> RequestHandler<RequestSet<R, P>, OwnerSet<'_>, ProviderSet<'_, P>> {
76        RequestHandler::from_client(self, request)
77    }
78}
79
80/// The `Body` trait is used to restrict the types able to implement
81/// request body. It is implemented by all `xxxRequest` types.
82pub trait Body: Debug + Send + Sync {}
83impl<T> Body for T where T: Debug + Send + Sync {}