sim_lib_view_daw/
param.rs1use sim_kernel::{Error, Expr, Result, Symbol};
9use sim_lib_intent::{field, intent_kind_of};
10
11pub fn apply_set_param(params: &Expr, intent: &Expr) -> Result<Expr> {
14 expect_kind(intent, "set-param")?;
15 let param = match field(intent, "param") {
16 Some(Expr::Symbol(symbol)) => symbol.clone(),
17 _ => {
18 return Err(Error::HostError(
19 "set-param 'param' must be a symbol".to_owned(),
20 ));
21 }
22 };
23 let value = field(intent, "value")
24 .cloned()
25 .ok_or_else(|| Error::HostError("set-param is missing a 'value'".to_owned()))?;
26 Ok(set_key(params, ¶m, value))
27}
28
29pub fn apply_scrub(transport: &Expr, intent: &Expr) -> Result<Expr> {
32 expect_kind(intent, "scrub")?;
33 let at = field(intent, "at")
34 .cloned()
35 .ok_or_else(|| Error::HostError("scrub is missing an 'at'".to_owned()))?;
36 Ok(set_key(transport, &Symbol::new("position"), at))
37}
38
39fn expect_kind(intent: &Expr, kind: &str) -> Result<()> {
40 match intent_kind_of(intent) {
41 Some(symbol) if symbol.name.as_ref() == kind => Ok(()),
42 _ => Err(Error::HostError(format!("expected an intent/{kind}"))),
43 }
44}
45
46fn set_key(map: &Expr, key: &Symbol, value: Expr) -> Expr {
47 let mut entries = match map {
48 Expr::Map(entries) => entries.clone(),
49 _ => Vec::new(),
50 };
51 let matches = |entry_key: &Expr| matches!(entry_key, Expr::Symbol(symbol) if symbol == key);
52 if let Some(slot) = entries.iter_mut().find(|(entry_key, _)| matches(entry_key)) {
53 slot.1 = value;
54 } else {
55 entries.push((Expr::Symbol(key.clone()), value));
56 }
57 Expr::Map(entries)
58}