wip: EdnKeymap

This commit is contained in:
🪞👃🪞 2025-01-12 01:48:43 +01:00
parent 8dcf73c18c
commit 364d617d37
6 changed files with 144 additions and 135 deletions

View file

@ -1,30 +1,32 @@
use crate::*;
use EdnItem::*;
use std::marker::PhantomData;
pub trait EdnControlData<E: Input> {}
/// Renders from EDN source and context.
#[derive(Default)]
pub enum EdnControls<E: Input, T: EdnControlData<E>> {
#[default]
Inert,
_Unused(PhantomData<E>),
Ok(T, EdnItem<String>),
Err(String)
}
impl<E: Input, T: EdnControlData<E>> EdnControls<E, T> {
pub fn from_source (state: T, source: &str) -> Self {
match EdnItem::read_one(&source) {
Ok((layout, _)) => Self::Ok(state, layout),
Err(error) => Self::Err(format!("{error}"))
}
}
pub fn from_items (state: T, items: &[EdnItem<&str>]) -> Self {
Self::Ok(state, EdnItem::Exp(items.iter().map(|i|(*i).clone()).collect()))
}
}
/// Turns an EDN symbol sequence into a command enum variant.
pub trait EdnCommand<C>: Command<C> {
fn from_edn <'a> (state: &C, head: &EdnItem<&str>, tail: &'a [EdnItem<String>]) -> Self;
}
pub trait EdnInput: Input {
fn matches (&self, token: &str) -> bool;
}
pub struct EdnKeymap(pub Vec<EdnItem<String>>);
impl EdnKeymap {
pub fn command <C, D: Command<C>, E: EdnCommand<C>, I: EdnInput> (&self, state: &C, input: &I) -> Option<E> {
for item in self.0.iter() {
if let Exp(items) = item {
match items.as_slice() {
[Key(a), b, c @ ..] => if input.matches(a.as_str()) {
return Some(E::from_edn(state, &b.to_ref(), c))
},
_ => unreachable!()
}
} else {
unreachable!()
}
}
None
}
}