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