//! Project file format. //! //! This module `impl`s the `from_edn`, `load_edn`, etc. methods //! of structs that are defined in other modules. See: //! //! * [App::from_edn] //! * [App::load_edn] //! * [App::load_edn_one] //! * [Scene::load_edn] //! * [Track::load_edn] //! * [Phrase::load_edn] //! * [Sampler::load_edn] //! * [Sample::load_edn] //! * [LV2Plugin::load_edn] use crate::*; impl App { pub fn from_edn (src: &str) -> Usually { let mut app = Self::new()?; app.load_edn(src)?; Ok(app) } pub fn load_edn (&mut self, mut src: &str) -> Usually<&mut Self> { loop { match read(src) { Ok((edn, rest)) => { self.load_edn_one(edn)?; if rest.len() > 0 { src = rest; } else { break } }, Err(EdnError { ptr: None, .. }) => { break }, Err(e) => { panic!("{e:?}"); }, } } Ok(self) } fn load_edn_one <'e> (&mut self, edn: Edn<'e>) -> Usually<()> { match edn { Edn::List(items) => { match items.get(0) { Some(Edn::Symbol("bpm")) => { match items.get(1) { Some(Edn::Int(b)) => self.transport.timebase.set_bpm(*b as f64), Some(Edn::Double(b)) => self.transport.timebase.set_bpm(f64::from(*b)), _ => panic!("unspecified bpm") } }, Some(Edn::Symbol("scene")) => { tek_sequencer::Scene::from_edn(&items[1..])?; }, Some(Edn::Symbol("track")) => { tek_mixer::Track::from_edn(&items[1..])?; }, Some(Edn::Symbol("midi-in")) => { self.midi_ins = items[1..].iter().map(|x|match x { Edn::Str(n) => n.to_string(), _ => panic!("unexpected midi-in") }).collect::>(); }, Some(Edn::Symbol("audio-out")) => { let client = self.client(); self.audio_outs = items[1..].iter().map(|x|match x { Edn::Str(n) => n.to_string(), _ => panic!("unexpected midi-in") }).collect::>() .iter() .map(|name|client .ports(Some(name), None, PortFlags::empty()) .get(0) .map(|name|client.port_by_name(name))) .flatten() .filter_map(|x|x) .map(Arc::new) .collect(); }, _ => panic!("unexpected edn: {:?}", items.get(0)) } }, _ => { panic!("unexpected edn: {edn:?}"); } } Ok(()) } }