this one at least compiles

This commit is contained in:
🪞👃🪞 2025-07-19 07:55:56 +03:00
parent a145e332de
commit 291b917970
7 changed files with 416 additions and 198 deletions

View file

@ -4,24 +4,64 @@ use crate::*;
/// Each contained layer defines a mapping from input event to command invocation
/// over a given state. Furthermore, each layer may have an associated cond,
/// so that only certain layers are active at a given time depending on state.
#[derive(Debug)] pub struct InputMap<I, D: Dsl>(
/// Map of input event (key combination) to
///
/// When a key is pressed, the bindings for it are checked in sequence.
/// When the first non-conditional or true conditional binding is executed,
/// that binding's value is returned.
#[derive(Debug)] pub struct EventMap<E, D: Dsl>(
/// Map of each event (e.g. key combination) to
/// all command expressions bound to it by
/// all loaded input layers.
pub BTreeMap<I, Vec<InputBinding<D>>>
pub EventBindings<E, D>
);
impl<I, D: Dsl> Default for InputMap<I, D> {
fn default () -> Self {
Self(Default::default())
}
}
#[derive(Debug, Default)] pub struct InputBinding<D: Dsl> {
type EventBindings<E, D> = BTreeMap<E, Vec<Binding<D>>>;
/// An input binding.
#[derive(Debug, Default)] pub struct Binding<D: Dsl> {
condition: Option<D>,
command: D,
description: Option<Arc<str>>,
source: Option<Arc<PathBuf>>,
}
impl<'s, I: Debug + Ord, D: Dsl + From<Cst<'s>>> InputMap<I, D> {
impl<E, D: Dsl> Default for EventMap<E, D> {
fn default () -> Self {
Self(Default::default())
}
}
impl<E: Ord + Debug + From<Arc<str>> + Clone> EventMap<E, Ast> {
/// Create input layer collection from DSL.
pub fn new (dsl: Ast) -> Usually<Self> {
use Val::*;
let mut input_map: EventBindings<E, Ast> = Default::default();
match dsl.exp_head() {
Str(path) => {
let path = PathBuf::from(path.as_ref() as &str);
for (key, val) in Self::from_path(&path)?.0.into_iter() {
todo!("import {path:?} {key:?} {val:?}");
let key: E = key.into();
if !input_map.contains_key(&key) {
input_map.insert(key, vec![]);
}
}
},
Sym(s) => {
let key: Arc<str> = s.as_ref().into();
let key: E = key.into();
if !input_map.contains_key(&key) {
input_map.insert(key.clone(), vec![]);
}
todo!("binding {s:?} {:?}", dsl.exp_tail());
},
Key(k) if k.as_ref() == "if" => {
todo!("conditional binding {:?}", dsl.exp_tail());
},
_ => return Err(format!("invalid form in keymap: {dsl:?}").into())
}
Ok(Self(input_map))
}
/// Create input layer collection from string.
pub fn from_source (source: &str) -> Usually<Self> {
Self::new(Ast::from(source))
}
/// Create input layer collection from path to text file.
pub fn from_path <P: Debug + AsRef<Path>> (path: P) -> Usually<Self> {
if !exists(path.as_ref())? {
@ -29,41 +69,9 @@ impl<'s, I: Debug + Ord, D: Dsl + From<Cst<'s>>> InputMap<I, D> {
}
Self::from_source(read_and_leak(path)?)
}
/// Create input layer collection from string.
pub fn from_source (source: &'s str) -> Usually<Self> {
Self::from_dsl(D::from(Cst(CstConstIter(source))))
}
/// Create input layer collection from DSL.
pub fn from_dsl (dsl: D) -> Usually<Self> {
use Val::*;
let mut input_map: BTreeMap<I, Vec<InputBinding<D>>> = Default::default();
match dsl.exp_head() {
Str(path) => {
let path = PathBuf::from(path.as_ref());
for (key, val) in InputMap::<I, D>::from_path(&path)?.0.into_iter() {
todo!("import {path:?} {key:?} {val:?}");
if !input_map.contains_key(&key) {
input_map.insert(key, vec![]);
}
}
},
Sym(sym) => {
//let key: I = sym.into();
//if !input_map.contains_key(&key) {
//input_map.insert(key, vec![]);
//}
todo!("binding {sym:?} {:?}", dsl.exp_tail());
},
Key(s) if s.as_ref() == "if" => {
todo!("conditional binding {:?}", dsl.exp_tail());
},
_ => return Err(format!("invalid form in keymap: {dsl:?}").into())
}
Ok(Self(input_map))
}
/// Evaluate the active layers for a given state,
/// returning the command to be executed, if any.
pub fn handle <S, O> (&self, state: &mut S, input: I) -> Perhaps<O> where
pub fn handle <S, O> (&self, state: &mut S, event: Ast) -> Perhaps<O> where
S: DslInto<bool> + DslInto<O>,
O: Command<S>
{
@ -76,7 +84,7 @@ impl<'s, I: Debug + Ord, D: Dsl + From<Cst<'s>>> InputMap<I, D> {
//}
//if matches
//&& let Some(exp) = bind.val().exp_head()
//&& input.dsl_into(exp, ||format!("InputMap: input.eval(binding) failed").into())?
//&& input.dsl_into(exp, ||format!("EventMap: input.eval(binding) failed").into())?
//&& let Some(command) = state.try_dsl_into(exp)? {
//return Ok(Some(command))
//}
@ -112,7 +120,7 @@ impl<'s, I: Debug + Ord, D: Dsl + From<Cst<'s>>> InputMap<I, D> {
//let mut keys = iter.unwrap();
//let mut map = InputMap::default();
//let mut map = EventMap::default();
//while let Some(token) = keys.next() {
//if let Value::Exp(_, mut exp) = token.value {
//let next = exp.next();