diff --git a/crates/app/src/config.rs b/crates/app/src/config.rs index 4be40dff..f876371b 100644 --- a/crates/app/src/config.rs +++ b/crates/app/src/config.rs @@ -1,8 +1,11 @@ use crate::*; +use std::path::PathBuf; /// Configuration #[derive(Default, Debug)] pub struct Configuration { + /// Path of configuration entrypoint + pub path: PathBuf, /// Name of configuration pub name: Option>, /// Description of configuration @@ -14,20 +17,19 @@ pub struct Configuration { } impl Configuration { - pub fn from_file (path: &impl AsRef, _watch: bool) -> Usually { - Self::from_source(String::from_utf8(std::fs::read(path.as_ref())?)?) - } - pub fn from_source (source: impl AsRef + 'static) -> Usually { - let source: Box = source.as_ref().into(); - let source: &'static str = Box::leak(source); - let [name, info, view, keys] = Self::parse(TokenIter::from(source.as_ref()))?; + + pub fn new (path: &impl AsRef, _watch: bool) -> Usually { + let text = read_and_leak(path.as_ref())?; + let [name, info, view, keys] = Self::parse(TokenIter::from(text))?; Ok(Self { + path: path.as_ref().into(), info: info.map(Self::parse_info).flatten(), name: name.map(Self::parse_name).flatten(), view: Self::parse_view(view)?, - keys: Self::parse_keys(keys)?, + keys: Self::parse_keys(&path, keys)?, }) } + fn parse (iter: TokenIter) -> Usually<[Option;4]> { let mut name: Option = None; let mut info: Option = None; @@ -59,6 +61,7 @@ impl Configuration { } Ok([name, info, view, keys]) } + fn parse_info (mut iter: TokenIter) -> Option> { iter.next().and_then(|x|if let Value::Str(x) = x.value { Some(x.into()) @@ -66,6 +69,7 @@ impl Configuration { None }) } + fn parse_name (mut iter: TokenIter) -> Option> { iter.next().and_then(|x|if let Value::Str(x) = x.value { Some(x.into()) @@ -73,6 +77,7 @@ impl Configuration { None }) } + fn parse_view (iter: Option) -> Usually { if let Some(view) = iter { Ok(view) @@ -80,7 +85,8 @@ impl Configuration { Err(format!("missing view definition").into()) } } - fn parse_keys (iter: Option) + + fn parse_keys (base: &impl AsRef, iter: Option) -> Usually>> { if let Some(mut keys) = iter { @@ -91,15 +97,46 @@ impl Configuration { let next = exp.next(); match next { Some(Token { value: Value::Key(sym), .. }) => match sym { - "layer" => { todo!() }, - "layer-if" => { todo!() }, + "layer" => { + let next = exp.next(); + match next { + Some(Token { value: Value::Str(path), .. }) => { + map.add_layer(read_and_leak(path)?.into()); + }, + _ => return Err( + format!("(e4) unexpected non-string {next:?}").into() + ) + } + todo!() + }, + "layer-if" => { + let next = exp.next(); + match next { + Some(Token { value: Value::Sym(sym), .. }) => { + todo!() + }, + _ => return Err( + format!("(e4) unexpected non-symbol {next:?}").into() + ) + } + let next = exp.next(); + match next { + Some(Token { value: Value::Str(path), .. }) => { + todo!() + }, + _ => return Err( + format!("(e4) unexpected non-symbol {next:?}").into() + ) + } + todo!() + }, _ => return Err( format!("(e3) unexpected symbol {sym:?}").into() ) } _ => return Err( - format!("(e2) unexpected exp {:?}", next.map(|x|x.value)).into() - ) + format!("(e2) unexpected exp {:?}", next.map(|x|x.value)).into() + ) } }, t => return Err( @@ -112,4 +149,13 @@ impl Configuration { return Err(format!("missing keys definition").into()) } } + +} + +fn read_and_leak (path: impl AsRef) -> Usually<&'static str> { + let path = path.as_ref(); + let text = String::from_utf8(std::fs::read(path)?)?; + let text: Box = text.into(); + let text: &'static str = Box::leak(text); + Ok(text) } diff --git a/crates/cli/tek.rs b/crates/cli/tek.rs index 604923a9..a5990ad0 100644 --- a/crates/cli/tek.rs +++ b/crates/cli/tek.rs @@ -100,7 +100,16 @@ impl Cli { for (index, connect) in midi_tos.iter().enumerate() { let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?; midi_outs.push(port); - } + }; + let config_path = match mode { + LaunchMode::Clock => "config/config_transport.edn", + LaunchMode::Sequencer => "config/config_sequencer.edn", + LaunchMode::Groovebox => "config/config_groovebox.edn", + LaunchMode::Arranger { .. } => "config/config_arranger.edn", + LaunchMode::Sampler => "config/config_sampler.edn", + _ => todo!("{mode:?}"), + }; + let config = Configuration::new(&config_path, false)?; let mut app = Tek { jack: jack.clone(), color: ItemTheme::random(), @@ -139,14 +148,7 @@ impl Cli { }, scenes, selected: Selection::TrackClip { track: 0, scene: 0 }, - config: Configuration::from_file(match mode { - LaunchMode::Clock => &"config/config_transport.edn", - LaunchMode::Sequencer => &"config/config_sequencer.edn", - LaunchMode::Groovebox => &"config/config_groovebox.edn", - LaunchMode::Arranger { .. } => &"config/config_arranger.edn", - LaunchMode::Sampler => &"config/config_sampler.edn", - _ => todo!("{mode:?}"), - }, false)?, + config, ..Default::default() }; if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode {