systemprompt_traits/
context.rs1use async_trait::async_trait;
9use std::sync::Arc;
10
11use crate::analytics::{AnalyticsProvider, FingerprintProvider};
12use crate::auth::UserProvider;
13
14pub trait AppContext: Send + Sync {
15 fn config(&self) -> Arc<dyn ConfigProvider>;
16 fn database_handle(&self) -> Arc<dyn DatabaseHandle>;
17 fn analytics_provider(&self) -> Option<Arc<dyn AnalyticsProvider>>;
18 fn fingerprint_provider(&self) -> Option<Arc<dyn FingerprintProvider>>;
19 fn user_provider(&self) -> Option<Arc<dyn UserProvider>>;
20}
21
22pub trait InjectContextHeaders {
23 fn inject_headers(&self, headers: &mut http::HeaderMap);
24}
25
26pub type ContextPropagationResult<T> = Result<T, ContextPropagationError>;
27
28#[derive(Debug, thiserror::Error)]
29#[non_exhaustive]
30pub enum ContextPropagationError {
31 #[error("missing header: {0}")]
32 MissingHeader(String),
33
34 #[error("invalid header {name}: {message}")]
35 InvalidHeader { name: String, message: String },
36
37 #[error("invalid context: {0}")]
38 Invalid(String),
39}
40
41pub trait ContextPropagation {
42 fn from_headers(headers: &http::HeaderMap) -> ContextPropagationResult<Self>
43 where
44 Self: Sized;
45
46 fn to_headers(&self) -> http::HeaderMap;
47}
48
49pub trait ConfigProvider: Send + Sync {
50 fn get(&self, key: &str) -> Option<String>;
51 fn database_url(&self) -> &str;
52 fn database_write_url(&self) -> Option<&str> {
53 None
54 }
55 fn system_path(&self) -> &str;
56 fn api_port(&self) -> u16;
57 fn as_any(&self) -> &dyn std::any::Any;
58}
59
60pub trait ModuleRegistry: Send + Sync {
61 fn get_module(&self, name: &str) -> Option<Arc<dyn Module>>;
62 fn list_modules(&self) -> Vec<String>;
63}
64
65pub trait DatabaseHandle: Send + Sync {
66 fn is_connected(&self) -> bool;
67 fn as_any(&self) -> &dyn std::any::Any;
68}
69
70#[async_trait]
71pub trait Module: Send + Sync {
72 fn name(&self) -> &str;
73 fn version(&self) -> &str;
74 fn display_name(&self) -> &str;
75 async fn initialize(&self) -> Result<(), Box<dyn std::error::Error>>;
76}
77
78#[cfg(feature = "web")]
79#[async_trait]
80pub trait ApiModule: Module {
81 fn router(&self, ctx: Arc<dyn AppContext>) -> axum::Router;
82}