sim_lib_stream_device/
modeled.rs1use sim_kernel::Symbol;
4
5use crate::{DeviceCaps, DeviceSample};
6
7pub trait ModeledSource {
12 type Sample: DeviceSample;
14
15 fn at(&self, index: u64) -> Self::Sample;
17}
18
19pub fn seq_is_monotone<S: ModeledSource>(source: &S, start: u64, count: usize) -> bool {
21 let mut previous = None;
22 for offset in 0..count {
23 let Some(index) = start.checked_add(offset as u64) else {
24 return false;
25 };
26 let seq = source.at(index).seq();
27 if previous.is_some_and(|previous| previous > seq) {
28 return false;
29 }
30 previous = Some(seq);
31 }
32 true
33}
34
35#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct ModeledDeviceCapsSource {
38 device: Symbol,
39 streams: Vec<Symbol>,
40 inputs: Vec<Symbol>,
41 outputs: Vec<Symbol>,
42 seq_base: u64,
43}
44
45impl ModeledDeviceCapsSource {
46 pub fn new(
48 device: Symbol,
49 streams: Vec<Symbol>,
50 inputs: Vec<Symbol>,
51 outputs: Vec<Symbol>,
52 ) -> Self {
53 Self {
54 device,
55 streams,
56 inputs,
57 outputs,
58 seq_base: 0,
59 }
60 }
61
62 pub fn with_seq_base(mut self, seq_base: u64) -> Self {
64 self.seq_base = seq_base;
65 self
66 }
67
68 pub fn demo() -> Self {
70 Self::new(
71 Symbol::qualified("device", "modeled-edge"),
72 vec![
73 Symbol::qualified("device/stream", "battery"),
74 Symbol::qualified("device/stream", "motion"),
75 ],
76 vec![Symbol::qualified("device/input", "button")],
77 vec![
78 Symbol::qualified("device/output", "screen"),
79 Symbol::qualified("device/output", "haptic"),
80 ],
81 )
82 }
83}
84
85impl ModeledSource for ModeledDeviceCapsSource {
86 type Sample = DeviceCaps;
87
88 fn at(&self, index: u64) -> Self::Sample {
89 DeviceCaps::new(
90 self.seq_base.saturating_add(index),
91 self.device.clone(),
92 self.streams.clone(),
93 self.inputs.clone(),
94 self.outputs.clone(),
95 )
96 }
97}