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