-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HList madness #12
base: master
Are you sure you want to change the base?
HList madness #12
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
My thoughts: if we remove the lifetime parameters on command structs as per my comment below, it should be possible to cache the root Command
. With this done, we should implement some sort of acceleration structure (the current implementation does a linear search on all commands).
Still some issues left, one of the bigger one being F: for<'a> Func<
<<<(&'a mut C,) as Tuple>::HList as Combine<<P::Extract as Tuple>::HList>>::Output as HList>::Tuple
>, Such that we can use literal("foo").and(param()).exec(|ctx, n: i32| *ctx += n); |
Damn ugly tubofish... for some reason it cannot figure out where let root = literal("hello")
.and(literal("world"))
.exec::<_, (_,)>(|n: &mut i32| *n = 42);
let mut n = 45;
if let Some((command,)) = root.parse(&mut "hello world".into()) {
command.call((&mut n,));
}
assert_eq!(n, 42);
let command = root.parse(&mut "bar".into());
assert!(command.is_none()); One way of getting around this, is not to have |
Alternatively, we can use a mapping, that maps "Self::Extracted -> T" let root = literal("hello")
.and(literal("world"))
.and(param())
.map(|a: i32| move |n: &mut i32| *n += a);
let mut n = 45;
if let Some((command,)) = root.parse(&mut "hello world -3".into()) {
command(&mut n)
} Async commands could be handled as let root = literal("foo")
.and(param())
.map(|a: i32| move |n: i32| async move { n + a });
if let Some((command,)) = root.parse(&mut "foo 10".into()) {
let res = smol::run(command(0));
assert_eq!(res, 10)
} We cant use |
There's still a few issue remaining.
Error handling and suggestionsOne way of handling suggestions is to "parse" the input and suggest have the errors contain the suggestions. This, however, would require some special handling Alternatively to the using error handling as suggestions, we could have a Guards / ProvidersIt would be nice to have some sort of guards and or providers. literal("tp").then(param()).map(|pos: Position| move |state: State, _: Permission<{"tp"}>| { ... });
literal("tp").then(param()).map(|pos: Position| move permission("tp", |state: State| { ... }));
literal("tp").then(param()).guard(permission("tp")).map(|pos: Position| move |state: State| { ... }); |
Currently, it works, but the parse tree has to be recreated each time, which is not ideal.
Still, some work left, need some way to track the depth and give an appropriate error message accordingly.
Might want swap
fn
out forFunc
and do someCombine
such that the closure signature is a bit cleaner.