camel_component_http/
registry.rs1use std::collections::HashMap;
2use std::path::PathBuf;
3use std::sync::Arc;
4
5use camel_component_api::CamelError;
6use tokio::sync::{RwLock, mpsc};
7use tower_http::services::ServeDir;
8
9use crate::RequestEnvelope;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum MountMode {
15 Static,
16 Spa,
17}
18
19#[allow(dead_code)]
20pub struct StaticMount {
21 pub mount_path: String,
22 pub mode: MountMode,
23 pub dir: PathBuf,
24 pub cache_control: String,
25 pub error_pages: HashMap<u16, PathBuf>,
26 pub serve_dir: ServeDir,
27}
28
29impl std::fmt::Debug for StaticMount {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 f.debug_struct("StaticMount")
32 .field("mount_path", &self.mount_path)
33 .field("mode", &self.mode)
34 .field("dir", &self.dir)
35 .field("cache_control", &self.cache_control)
36 .field("error_pages", &self.error_pages)
37 .finish_non_exhaustive()
38 }
39}
40
41pub(crate) struct HttpRouteRegistryInner {
42 pub api_routes: HashMap<String, mpsc::Sender<RequestEnvelope>>,
43 pub mounts: Vec<StaticMount>,
44}
45
46impl std::fmt::Debug for HttpRouteRegistryInner {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 f.debug_struct("HttpRouteRegistryInner")
49 .field("api_routes", &self.api_routes.keys())
50 .field("mounts", &self.mounts.len())
51 .finish()
52 }
53}
54
55#[derive(Clone)]
56pub struct HttpRouteRegistry {
57 pub(crate) inner: Arc<RwLock<HttpRouteRegistryInner>>,
58}
59
60impl std::fmt::Debug for HttpRouteRegistry {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 f.debug_struct("HttpRouteRegistry").finish_non_exhaustive()
63 }
64}
65
66impl Default for HttpRouteRegistry {
67 fn default() -> Self {
68 Self::new()
69 }
70}
71
72impl HttpRouteRegistry {
73 pub fn new() -> Self {
74 Self {
75 inner: Arc::new(RwLock::new(HttpRouteRegistryInner {
76 api_routes: HashMap::new(),
77 mounts: Vec::new(),
78 })),
79 }
80 }
81
82 pub async fn register_api_route(&self, path: String, sender: mpsc::Sender<RequestEnvelope>) {
83 let mut inner = self.inner.write().await;
84 inner.api_routes.insert(path, sender);
85 }
86
87 pub async fn unregister_api_route(&self, path: &str) {
88 let mut inner = self.inner.write().await;
89 inner.api_routes.remove(path);
90 }
91
92 #[allow(dead_code)]
100 pub async fn register_static_mount(&self, mount: StaticMount) -> Result<(), CamelError> {
101 let mut inner = self.inner.write().await;
102 if inner
103 .mounts
104 .iter()
105 .any(|m| m.mount_path == mount.mount_path)
106 {
107 return Err(CamelError::Config(format!(
108 "duplicate static mount path '{}' on this port",
109 mount.mount_path
110 )));
111 }
112 inner.mounts.push(mount);
113 Ok(())
114 }
115
116 #[allow(dead_code)]
118 pub async fn unregister_static_mount(&self, mount_path: &str) {
119 let mut inner = self.inner.write().await;
120 inner.mounts.retain(|m| m.mount_path != mount_path);
121 }
122}