Skip to main content

sim_lib_stream_host/
capability.rs

1//! Host backend capability metadata and browse card helpers.
2
3use sim_kernel::{Expr, Symbol};
4
5/// Capability advertised by a host backend.
6///
7/// Each variant names one host-integration feature a backend may support, such
8/// as a media direction, hotplug/reconnect handling, or the deterministic fake
9/// transport used during validation.
10///
11/// # Examples
12///
13/// ```
14/// use sim_lib_stream_host::HostBackendCapability;
15///
16/// let symbol = HostBackendCapability::Duplex.symbol();
17/// assert_eq!(symbol.as_qualified_str(), "stream/host-capability/duplex");
18/// ```
19#[derive(Clone, Copy, Debug, PartialEq, Eq)]
20pub enum HostBackendCapability {
21    /// Backend can capture audio from a host input device.
22    AudioInput,
23    /// Backend can render audio to a host output device.
24    AudioOutput,
25    /// Backend can receive MIDI from a host input port.
26    MidiInput,
27    /// Backend can send MIDI to a host output port.
28    MidiOutput,
29    /// Backend can drive a single full-duplex (input and output) device.
30    Duplex,
31    /// Backend reports device arrival and removal at runtime.
32    Hotplug,
33    /// Backend can re-establish a dropped device or peer connection.
34    Reconnect,
35    /// Backend can enumerate and plan without opening hardware streams.
36    Offline,
37    /// Backend is a deterministic fake used for validation rather than hardware.
38    Fake,
39}
40
41impl HostBackendCapability {
42    /// Returns the stable qualified symbol naming this capability.
43    pub fn symbol(self) -> Symbol {
44        match self {
45            Self::AudioInput => Symbol::qualified("stream/host-capability", "audio-input"),
46            Self::AudioOutput => Symbol::qualified("stream/host-capability", "audio-output"),
47            Self::MidiInput => Symbol::qualified("stream/host-capability", "midi-input"),
48            Self::MidiOutput => Symbol::qualified("stream/host-capability", "midi-output"),
49            Self::Duplex => Symbol::qualified("stream/host-capability", "duplex"),
50            Self::Hotplug => Symbol::qualified("stream/host-capability", "hotplug"),
51            Self::Reconnect => Symbol::qualified("stream/host-capability", "reconnect"),
52            Self::Offline => Symbol::qualified("stream/host-capability", "offline"),
53            Self::Fake => Symbol::qualified("stream/host-capability", "fake"),
54        }
55    }
56}
57
58/// Emits a browse card for a missing backend capability.
59pub fn missing_capability_card_expr(backend: &Symbol, capability: HostBackendCapability) -> Expr {
60    Expr::Map(vec![
61        (
62            Expr::Symbol(Symbol::new("subject")),
63            Expr::Symbol(backend.clone()),
64        ),
65        (
66            Expr::Symbol(Symbol::new("kind")),
67            Expr::Symbol(Symbol::qualified("stream", "host-missing-capability")),
68        ),
69        (
70            Expr::Symbol(Symbol::new("capability")),
71            Expr::Symbol(capability.symbol()),
72        ),
73    ])
74}