Skip to main content

ferrin_spec/dynamic/
realtime_model.rs

1//! Object-safe realtime model and factory.
2
3use url::Url;
4
5use super::BoxFuture;
6use super::ModelRef;
7use super::ServiceRef;
8use super::model_ref::ref_conversions;
9use crate::error::NoSuchModelError;
10use crate::error::ProviderError;
11use crate::json::JsonValue;
12use crate::realtime_model::ClientSecret;
13use crate::realtime_model::ClientSecretOptions;
14use crate::realtime_model::GetTokenOptions;
15use crate::realtime_model::RealtimeClientEvent;
16use crate::realtime_model::RealtimeFactory;
17use crate::realtime_model::RealtimeModel;
18use crate::realtime_model::RealtimeServerEvent;
19use crate::realtime_model::RealtimeSessionConfig;
20use crate::realtime_model::WebSocketConfig;
21use crate::shared::ModelId;
22use crate::shared::ProviderId;
23
24/// Object-safe counterpart of [`RealtimeModel`].
25pub trait DynRealtimeModel: Send + Sync + 'static {
26    /// See [`RealtimeModel::provider`].
27    fn provider(&self) -> &ProviderId;
28    /// See [`RealtimeModel::model_id`].
29    fn model_id(&self) -> &ModelId;
30    /// See [`RealtimeModel::do_create_client_secret`].
31    fn do_create_client_secret(
32        &self,
33        options: ClientSecretOptions,
34    ) -> BoxFuture<'_, Result<ClientSecret, ProviderError>>;
35    /// See [`RealtimeModel::websocket_config`].
36    fn websocket_config(&self, token: &str, url: &Url) -> WebSocketConfig;
37    /// See [`RealtimeModel::parse_server_event`].
38    fn parse_server_event(&self, raw: JsonValue)
39    -> Result<Vec<RealtimeServerEvent>, ProviderError>;
40    /// See [`RealtimeModel::serialize_client_event`].
41    fn serialize_client_event(
42        &self,
43        event: RealtimeClientEvent,
44    ) -> BoxFuture<'_, Result<JsonValue, ProviderError>>;
45    /// See [`RealtimeModel::build_session_config`].
46    fn build_session_config(
47        &self,
48        config: &RealtimeSessionConfig,
49    ) -> Result<JsonValue, ProviderError>;
50    /// See [`RealtimeModel::health_check_response`].
51    fn health_check_response(&self, raw: &JsonValue) -> Option<JsonValue>;
52}
53
54impl<T: RealtimeModel> DynRealtimeModel for T {
55    fn provider(&self) -> &ProviderId {
56        RealtimeModel::provider(self)
57    }
58
59    fn model_id(&self) -> &ModelId {
60        RealtimeModel::model_id(self)
61    }
62
63    fn do_create_client_secret(
64        &self,
65        options: ClientSecretOptions,
66    ) -> BoxFuture<'_, Result<ClientSecret, ProviderError>> {
67        Box::pin(RealtimeModel::do_create_client_secret(self, options))
68    }
69
70    fn websocket_config(&self, token: &str, url: &Url) -> WebSocketConfig {
71        RealtimeModel::websocket_config(self, token, url)
72    }
73
74    fn parse_server_event(
75        &self,
76        raw: JsonValue,
77    ) -> Result<Vec<RealtimeServerEvent>, ProviderError> {
78        RealtimeModel::parse_server_event(self, raw)
79    }
80
81    fn serialize_client_event(
82        &self,
83        event: RealtimeClientEvent,
84    ) -> BoxFuture<'_, Result<JsonValue, ProviderError>> {
85        Box::pin(RealtimeModel::serialize_client_event(self, event))
86    }
87
88    fn build_session_config(
89        &self,
90        config: &RealtimeSessionConfig,
91    ) -> Result<JsonValue, ProviderError> {
92        RealtimeModel::build_session_config(self, config)
93    }
94
95    fn health_check_response(&self, raw: &JsonValue) -> Option<JsonValue> {
96        RealtimeModel::health_check_response(self, raw)
97    }
98}
99
100/// Shared reference to a realtime model (or an unresolved model id).
101pub type RealtimeModelRef = ModelRef<dyn DynRealtimeModel>;
102
103ref_conversions!(RealtimeModelRef, RealtimeModel, DynRealtimeModel);
104
105/// Object-safe counterpart of [`RealtimeFactory`].
106pub trait DynRealtimeFactory: Send + Sync + 'static {
107    /// See [`RealtimeFactory::provider`].
108    fn provider(&self) -> &ProviderId;
109    /// See [`RealtimeFactory::model`].
110    fn model(&self, model_id: &str) -> Result<RealtimeModelRef, NoSuchModelError>;
111    /// See [`RealtimeFactory::get_token`].
112    fn get_token(
113        &self,
114        options: GetTokenOptions,
115    ) -> BoxFuture<'_, Result<ClientSecret, ProviderError>>;
116}
117
118impl<T: RealtimeFactory> DynRealtimeFactory for T {
119    fn provider(&self) -> &ProviderId {
120        RealtimeFactory::provider(self)
121    }
122
123    fn model(&self, model_id: &str) -> Result<RealtimeModelRef, NoSuchModelError> {
124        RealtimeFactory::model(self, model_id)
125    }
126
127    fn get_token(
128        &self,
129        options: GetTokenOptions,
130    ) -> BoxFuture<'_, Result<ClientSecret, ProviderError>> {
131        Box::pin(RealtimeFactory::get_token(self, options))
132    }
133}
134
135/// Shared reference to a realtime factory.
136pub type RealtimeFactoryRef = ServiceRef<dyn DynRealtimeFactory>;
137
138ref_conversions!(RealtimeFactoryRef, RealtimeFactory, DynRealtimeFactory);