Skip to main content

sim_lib_stream_host/
inventory.rs

1//! Host device and port inventory records.
2
3use sim_kernel::{Expr, Symbol};
4use sim_lib_stream_core::StreamMedia;
5
6use crate::model::{HostDeviceSpec, HostDirection};
7
8/// Devices and ports reported by a backend enumeration.
9#[derive(Clone, Debug, PartialEq, Eq)]
10pub struct HostDeviceInventory {
11    backend: Symbol,
12    devices: Vec<HostDeviceSpec>,
13    ports: Vec<HostPortSpec>,
14}
15
16/// Addressable host port owned by an enumerated device.
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub struct HostPortSpec {
19    id: Symbol,
20    device: Symbol,
21    backend: Symbol,
22    media: StreamMedia,
23    direction: HostDirection,
24}
25
26impl HostDeviceInventory {
27    /// Creates an empty inventory owned by `backend`.
28    pub fn new(backend: Symbol) -> Self {
29        Self {
30            backend,
31            devices: Vec::new(),
32            ports: Vec::new(),
33        }
34    }
35
36    /// Replaces the enumerated devices.
37    pub fn with_devices(mut self, devices: Vec<HostDeviceSpec>) -> Self {
38        self.devices = devices;
39        self
40    }
41
42    /// Replaces the enumerated ports.
43    pub fn with_ports(mut self, ports: Vec<HostPortSpec>) -> Self {
44        self.ports = ports;
45        self
46    }
47
48    /// Returns the owning backend symbol.
49    pub fn backend(&self) -> &Symbol {
50        &self.backend
51    }
52
53    /// Returns the enumerated devices.
54    pub fn devices(&self) -> &[HostDeviceSpec] {
55        &self.devices
56    }
57
58    /// Returns the enumerated ports.
59    pub fn ports(&self) -> &[HostPortSpec] {
60        &self.ports
61    }
62
63    /// Builds browse card expressions for every device and port.
64    pub fn card_exprs(&self) -> Vec<Expr> {
65        self.devices
66            .iter()
67            .map(HostDeviceSpec::card_expr)
68            .chain(self.ports.iter().map(HostPortSpec::card_expr))
69            .collect()
70    }
71}
72
73impl HostPortSpec {
74    /// Builds a port spec identifying `id` on `device` under `backend`.
75    pub fn new(
76        id: Symbol,
77        device: Symbol,
78        backend: Symbol,
79        media: StreamMedia,
80        direction: HostDirection,
81    ) -> Self {
82        Self {
83            id,
84            device,
85            backend,
86            media,
87            direction,
88        }
89    }
90
91    /// Returns the port identifier symbol.
92    pub fn id(&self) -> &Symbol {
93        &self.id
94    }
95
96    /// Returns the owning device symbol.
97    pub fn device(&self) -> &Symbol {
98        &self.device
99    }
100
101    /// Returns the owning backend symbol.
102    pub fn backend(&self) -> &Symbol {
103        &self.backend
104    }
105
106    /// Returns the port media.
107    pub fn media(&self) -> StreamMedia {
108        self.media
109    }
110
111    /// Returns the port direction.
112    pub fn direction(&self) -> HostDirection {
113        self.direction
114    }
115
116    /// Builds the browse card expression for this port.
117    pub fn card_expr(&self) -> Expr {
118        Expr::Map(vec![
119            (
120                Expr::Symbol(Symbol::new("subject")),
121                Expr::Symbol(self.id.clone()),
122            ),
123            (
124                Expr::Symbol(Symbol::new("kind")),
125                Expr::Symbol(Symbol::qualified("stream", "host-port")),
126            ),
127            (
128                Expr::Symbol(Symbol::new("device")),
129                Expr::Symbol(self.device.clone()),
130            ),
131            (
132                Expr::Symbol(Symbol::new("backend")),
133                Expr::Symbol(self.backend.clone()),
134            ),
135            (
136                Expr::Symbol(Symbol::new("media")),
137                Expr::Symbol(self.media.symbol()),
138            ),
139            (
140                Expr::Symbol(Symbol::new("direction")),
141                Expr::Symbol(self.direction.symbol()),
142            ),
143        ])
144    }
145}