hyperstack_server/view/
spec.rs

1use crate::websocket::frame::Mode;
2
3// # View System Architecture
4//
5// The view system uses hierarchical View IDs instead of simple entity names,
6// enabling sophisticated filtering and organization:
7//
8// ## View ID Structure
9// - Basic views: `EntityName/mode` (e.g., `SettlementGame/list`, `SettlementGame/state`)
10// - Filtered views: `EntityName/mode/filter1/filter2/...` (e.g., `SettlementGame/list/active/large`)
11//
12// ## Subscription Model
13// Clients subscribe using the full view ID:
14// ```json
15// {
16//   "view": "SettlementGame/list/active/large"
17// }
18// ```
19//
20// ## Future Filter Examples
21// - `SettlementGame/list/active/large` - Active games with large bets
22// - `SettlementGame/list/user/123` - Games for specific user
23// - `SettlementGame/list/recent` - Recently created games only
24
25#[derive(Clone, Debug)]
26pub struct ViewSpec {
27    pub id: String,
28    pub export: String,
29    pub mode: Mode,
30    pub projection: Projection,
31    pub filters: Filters,
32    pub delivery: Delivery,
33}
34
35#[derive(Clone, Debug, Default)]
36pub struct Projection {
37    pub fields: Option<Vec<String>>,
38}
39
40impl Projection {
41    pub fn all() -> Self {
42        Self { fields: None }
43    }
44
45    pub fn apply(&self, mut data: serde_json::Value) -> serde_json::Value {
46        if let Some(ref field_list) = self.fields {
47            if let Some(obj) = data.as_object_mut() {
48                obj.retain(|k, _| field_list.contains(&k.to_string()));
49            }
50        }
51        data
52    }
53}
54
55#[derive(Clone, Debug, Default)]
56pub struct Filters {
57    pub keys: Option<Vec<String>>,
58}
59
60impl Filters {
61    pub fn all() -> Self {
62        Self { keys: None }
63    }
64
65    pub fn matches(&self, key: &str) -> bool {
66        match &self.keys {
67            None => true,
68            Some(keys) => keys.iter().any(|k| k == key),
69        }
70    }
71}
72
73#[derive(Clone, Debug, Default)]
74pub struct Delivery {
75    pub coalesce_ms: Option<u64>,
76}