systemprompt_models/profile/gateway/
state.rs1use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use systemprompt_identifiers::RouteId;
10
11use super::config::{GatewayConfig, GatewayConfigSpec};
12
13#[derive(Debug, Clone)]
14pub enum GatewayState {
15 Spec(GatewayConfigSpec),
16 Resolved(GatewayConfig),
17}
18
19impl GatewayState {
20 #[must_use]
25 pub fn resolved(&self) -> Option<&GatewayConfig> {
26 match self {
27 Self::Resolved(c) => Some(c),
28 Self::Spec(_) => {
29 tracing::error!(
30 "gateway state is still Spec at runtime read; GatewayConfigSpec::resolve was \
31 never called — treating gateway as absent"
32 );
33 None
34 },
35 }
36 }
37
38 #[must_use]
39 pub const fn as_spec_mut(&mut self) -> Option<&mut GatewayConfigSpec> {
40 match self {
41 Self::Spec(s) => Some(s),
42 Self::Resolved(_) => None,
43 }
44 }
45
46 pub fn into_spec(self) -> GatewayConfigSpec {
47 match self {
48 Self::Spec(s) => s,
49 Self::Resolved(c) => c.to_spec(),
50 }
51 }
52
53 #[must_use]
58 pub fn resolved_route_ids(&self) -> Vec<RouteId> {
59 let mut spec = self.clone().into_spec();
60 spec.routes
61 .iter_mut()
62 .map(|route| {
63 route.ensure_id();
64 route.id.clone()
65 })
66 .collect()
67 }
68}
69
70impl<'de> Deserialize<'de> for GatewayState {
71 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
72 where
73 D: Deserializer<'de>,
74 {
75 GatewayConfigSpec::deserialize(deserializer).map(Self::Spec)
76 }
77}
78
79impl Serialize for GatewayState {
80 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81 where
82 S: Serializer,
83 {
84 match self {
85 Self::Spec(s) => s.serialize(serializer),
86 Self::Resolved(c) => c.to_spec().serialize(serializer),
87 }
88 }
89}
90
91impl schemars::JsonSchema for GatewayState {
92 fn schema_name() -> std::borrow::Cow<'static, str> {
93 GatewayConfigSpec::schema_name()
94 }
95
96 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
97 GatewayConfigSpec::json_schema(generator)
98 }
99}