Skip to main content

seam_server/
server.rs

1/* src/server/core/rust/src/server.rs */
2
3use std::collections::BTreeMap;
4
5use crate::build_loader::RpcHashMap;
6use crate::channel::{ChannelDef, ChannelMeta};
7use crate::page::{I18nConfig, PageDef};
8use crate::procedure::{ProcedureDef, SubscriptionDef};
9use crate::resolve::ResolveStrategy;
10
11/// Framework-agnostic parts extracted from `SeamServer`.
12/// Adapter crates consume this to build framework-specific routers.
13pub struct SeamParts {
14  pub procedures: Vec<ProcedureDef>,
15  pub subscriptions: Vec<SubscriptionDef>,
16  pub pages: Vec<PageDef>,
17  pub rpc_hash_map: Option<RpcHashMap>,
18  pub i18n_config: Option<I18nConfig>,
19  pub strategies: Vec<Box<dyn ResolveStrategy>>,
20  pub channel_metas: BTreeMap<String, ChannelMeta>,
21}
22
23impl SeamParts {
24  pub fn has_url_prefix(&self) -> bool {
25    self.strategies.iter().any(|s| s.kind() == "url_prefix")
26  }
27}
28
29pub struct SeamServer {
30  procedures: Vec<ProcedureDef>,
31  subscriptions: Vec<SubscriptionDef>,
32  channels: Vec<ChannelDef>,
33  pages: Vec<PageDef>,
34  rpc_hash_map: Option<RpcHashMap>,
35  i18n_config: Option<I18nConfig>,
36  strategies: Vec<Box<dyn ResolveStrategy>>,
37}
38
39impl SeamServer {
40  pub fn new() -> Self {
41    Self {
42      procedures: Vec::new(),
43      subscriptions: Vec::new(),
44      channels: Vec::new(),
45      pages: Vec::new(),
46      rpc_hash_map: None,
47      i18n_config: None,
48      strategies: Vec::new(),
49    }
50  }
51
52  pub fn procedure(mut self, proc: ProcedureDef) -> Self {
53    self.procedures.push(proc);
54    self
55  }
56
57  pub fn subscription(mut self, sub: SubscriptionDef) -> Self {
58    self.subscriptions.push(sub);
59    self
60  }
61
62  pub fn channel(mut self, channel: ChannelDef) -> Self {
63    self.channels.push(channel);
64    self
65  }
66
67  pub fn page(mut self, page: PageDef) -> Self {
68    self.pages.push(page);
69    self
70  }
71
72  pub fn rpc_hash_map(mut self, map: RpcHashMap) -> Self {
73    self.rpc_hash_map = Some(map);
74    self
75  }
76
77  pub fn i18n_config(mut self, config: I18nConfig) -> Self {
78    self.i18n_config = Some(config);
79    self
80  }
81
82  pub fn resolve_strategies(mut self, strategies: Vec<Box<dyn ResolveStrategy>>) -> Self {
83    self.strategies = strategies;
84    self
85  }
86
87  /// Consume the builder, returning framework-agnostic parts for an adapter.
88  /// Channels are expanded into their Level 0 primitives (commands + subscriptions).
89  pub fn into_parts(self) -> SeamParts {
90    let mut procedures = self.procedures;
91    let mut subscriptions = self.subscriptions;
92    let mut channel_metas = BTreeMap::new();
93
94    for channel in self.channels {
95      let name = channel.name.clone();
96      let (procs, subs, meta) = channel.expand();
97      procedures.extend(procs);
98      subscriptions.extend(subs);
99      channel_metas.insert(name, meta);
100    }
101
102    SeamParts {
103      procedures,
104      subscriptions,
105      pages: self.pages,
106      rpc_hash_map: self.rpc_hash_map,
107      i18n_config: self.i18n_config,
108      strategies: self.strategies,
109      channel_metas,
110    }
111  }
112}
113
114impl Default for SeamServer {
115  fn default() -> Self {
116    Self::new()
117  }
118}