1use std::sync::Arc;
2
3use serde::{Deserialize, Serialize};
4use spacegate_kernel::{
5 service::{
6 http_gateway::Gateway,
7 http_route::{HttpBackend, HttpRoute, HttpRouteRule},
8 },
9 BoxError,
10};
11
12use crate::instance::{drop_trace, DropMarkerSet, DropTracer, PluginInstance};
13
14#[derive(Debug, Clone, Hash, PartialEq, Eq)]
15pub enum MountPointIndex {
16 Gateway { gateway: Arc<str> },
17 HttpRoute { gateway: Arc<str>, route: Arc<str> },
18 HttpRouteRule { gateway: Arc<str>, route: Arc<str>, rule: usize },
19 HttpBackend { gateway: Arc<str>, route: Arc<str>, rule: usize, backend: usize },
20}
21
22impl MountPointIndex {
23 pub fn gateway(&self) -> &str {
24 match self {
25 MountPointIndex::Gateway { gateway } => gateway.as_ref(),
26 MountPointIndex::HttpRoute { gateway, .. } => gateway.as_ref(),
27 MountPointIndex::HttpRouteRule { gateway, .. } => gateway.as_ref(),
28 MountPointIndex::HttpBackend { gateway, .. } => gateway.as_ref(),
29 }
30 }
31}
32impl Serialize for MountPointIndex {
33 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
34 where
35 S: serde::Serializer,
36 {
37 match self {
38 MountPointIndex::Gateway { gateway } => MountPointIndexSerde::Gateway { gateway: gateway.as_ref() }.serialize(serializer),
39 MountPointIndex::HttpRoute { gateway, route } => MountPointIndexSerde::HttpRoute {
40 gateway: gateway.as_ref(),
41 route: route.as_ref(),
42 }
43 .serialize(serializer),
44 MountPointIndex::HttpRouteRule { gateway, route, rule } => MountPointIndexSerde::HttpRouteRule {
45 gateway: gateway.as_ref(),
46 route: route.as_ref(),
47 rule: *rule,
48 }
49 .serialize(serializer),
50 MountPointIndex::HttpBackend { gateway, route, rule, backend } => MountPointIndexSerde::HttpBackend {
51 gateway: gateway.as_ref(),
52 route: route.as_ref(),
53 rule: *rule,
54 backend: *backend,
55 }
56 .serialize(serializer),
57 }
58 }
59}
60
61impl<'de> Deserialize<'de> for MountPointIndex {
62 fn deserialize<D>(deserializer: D) -> Result<MountPointIndex, D::Error>
63 where
64 D: serde::Deserializer<'de>,
65 {
66 let index = MountPointIndexSerde::deserialize(deserializer)?;
67 match index {
68 MountPointIndexSerde::Gateway { gateway } => Ok(MountPointIndex::Gateway { gateway: gateway.into() }),
69 MountPointIndexSerde::HttpRoute { gateway, route } => Ok(MountPointIndex::HttpRoute {
70 gateway: gateway.into(),
71 route: route.into(),
72 }),
73 MountPointIndexSerde::HttpRouteRule { gateway, route, rule } => Ok(MountPointIndex::HttpRouteRule {
74 gateway: gateway.into(),
75 route: route.into(),
76 rule,
77 }),
78 MountPointIndexSerde::HttpBackend { gateway, route, rule, backend } => Ok(MountPointIndex::HttpBackend {
79 gateway: gateway.into(),
80 route: route.into(),
81 rule,
82 backend,
83 }),
84 }
85 }
86}
87
88#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
89pub enum MountPointIndexSerde<'a> {
90 Gateway { gateway: &'a str },
91 HttpRoute { gateway: &'a str, route: &'a str },
92 HttpRouteRule { gateway: &'a str, route: &'a str, rule: usize },
93 HttpBackend { gateway: &'a str, route: &'a str, rule: usize, backend: usize },
94}
95
96pub trait MountPoint {
97 fn mount(&mut self, instance: &mut PluginInstance) -> Result<DropTracer, BoxError>;
98}
99
100impl MountPoint for Gateway {
101 fn mount(&mut self, instance: &mut PluginInstance) -> Result<DropTracer, BoxError> {
102 let (tracer, marker) = drop_trace();
103 self.http_plugins.push(instance.make());
104 let set = self.ext.get_or_insert_default::<DropMarkerSet>();
105 set.inner.insert(marker);
106 Ok(tracer)
107 }
108}
109
110impl MountPoint for HttpRoute {
111 fn mount(&mut self, instance: &mut PluginInstance) -> Result<DropTracer, BoxError> {
112 let (tracer, marker) = drop_trace();
113 self.plugins.push(instance.make());
114 let set = self.ext.get_or_insert_default::<DropMarkerSet>();
115 set.inner.insert(marker);
116 Ok(tracer)
117 }
118}
119
120impl MountPoint for HttpRouteRule {
121 fn mount(&mut self, instance: &mut PluginInstance) -> Result<DropTracer, BoxError> {
122 let (tracer, marker) = drop_trace();
123 self.plugins.push(instance.make());
124 let set = self.ext.get_or_insert_default::<DropMarkerSet>();
125 set.inner.insert(marker);
126 Ok(tracer)
127 }
128}
129
130impl MountPoint for HttpBackend {
131 fn mount(&mut self, instance: &mut PluginInstance) -> Result<DropTracer, BoxError> {
132 let (tracer, marker) = drop_trace();
133 self.plugins.push(instance.make());
134 let set = self.ext.get_or_insert_default::<DropMarkerSet>();
135 set.inner.insert(marker);
136 Ok(tracer)
137 }
138}