Skip to main content

sim_lib_stream_host/
midi_provider.rs

1//! Modeled MIDI device provider for the shared device catalog.
2
3use sim_kernel::{Error, Result, Symbol};
4
5use crate::eval_site::{DeviceProvider, StreamEvalSite};
6use crate::placement::{DeviceRecord, Placement};
7
8/// Deterministic MIDI provider used by default validation.
9pub struct ModeledMidiProvider {
10    ports: Vec<DeviceRecord>,
11}
12
13impl Default for ModeledMidiProvider {
14    fn default() -> Self {
15        Self {
16            ports: vec![
17                DeviceRecord::modeled_midi_input("midi/model/in-0", "Modeled MIDI Input 0"),
18                DeviceRecord::modeled_midi_output("midi/model/out-0", "Modeled MIDI Output 0"),
19            ],
20        }
21    }
22}
23
24impl DeviceProvider for ModeledMidiProvider {
25    fn enumerate(&self) -> Result<Vec<DeviceRecord>> {
26        Ok(self.ports.clone())
27    }
28
29    fn open(&self, id: &Symbol) -> Result<Box<dyn StreamEvalSite>> {
30        let record = self
31            .ports
32            .iter()
33            .find(|record| &record.id == id)
34            .ok_or_else(|| Error::Eval(format!("ModeledMidiProvider: unknown id '{id}'")))?
35            .clone();
36        Ok(Box::new(ModeledMidiEvalSite { record }))
37    }
38}
39
40struct ModeledMidiEvalSite {
41    record: DeviceRecord,
42}
43
44impl StreamEvalSite for ModeledMidiEvalSite {
45    fn placement(&self) -> &Placement {
46        &self.record.placement
47    }
48
49    fn device_record(&self) -> &DeviceRecord {
50        &self.record
51    }
52
53    fn close(self: Box<Self>) -> Result<()> {
54        Ok(())
55    }
56}