mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2025-12-06 11:46:42 +01:00
This commit is contained in:
parent
21832453d9
commit
17506726cb
36 changed files with 280 additions and 271 deletions
2
Justfile
2
Justfile
|
|
@ -1,6 +1,8 @@
|
||||||
covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'"
|
covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'"
|
||||||
grcov-binary := "--binary-path ./target/coverage/deps/"
|
grcov-binary := "--binary-path ./target/coverage/deps/"
|
||||||
grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
||||||
|
bacon:
|
||||||
|
{{covfig}} bacon -s
|
||||||
cov:
|
cov:
|
||||||
{{covfig}} time cargo test -j4 --workspace --profile coverage
|
{{covfig}} time cargo test -j4 --workspace --profile coverage
|
||||||
rm -rf target/coverage/html || true
|
rm -rf target/coverage/html || true
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@ use crate::*;
|
||||||
/// CST stores strings as source references and expressions as new [SourceIter] instances.
|
/// CST stores strings as source references and expressions as new [SourceIter] instances.
|
||||||
pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>;
|
pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>;
|
||||||
|
|
||||||
|
/// Token sharing memory with source reference.
|
||||||
|
#[derive(Debug, Copy, Clone, Default, PartialEq)]
|
||||||
|
pub struct CstToken<'source>(pub CstValue<'source>, pub CstMeta<'source>);
|
||||||
|
|
||||||
/// Reference to the source slice.
|
/// Reference to the source slice.
|
||||||
#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct CstMeta<'source> {
|
#[derive(Debug, Copy, Clone, Default, PartialEq)] pub struct CstMeta<'source> {
|
||||||
pub source: &'source str,
|
pub source: &'source str,
|
||||||
|
|
@ -10,10 +14,6 @@ pub type CstValue<'source> = Value<&'source str, SourceIter<'source>>;
|
||||||
pub length: usize,
|
pub length: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Token sharing memory with source reference.
|
|
||||||
#[derive(Debug, Copy, Clone, Default, PartialEq)]
|
|
||||||
pub struct CstToken<'source>(pub CstValue<'source>, pub CstMeta<'source>);
|
|
||||||
|
|
||||||
impl<'source> CstToken<'source> {
|
impl<'source> CstToken<'source> {
|
||||||
pub const fn new (
|
pub const fn new (
|
||||||
source: &'source str, start: usize, length: usize, value: CstValue<'source>
|
source: &'source str, start: usize, length: usize, value: CstValue<'source>
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,32 @@ pub trait DslIter {
|
||||||
fn rest (self) -> Vec<Self::Token>;
|
fn rest (self) -> Vec<Self::Token>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq)]
|
/// Implement the const iterator pattern.
|
||||||
pub struct AstIter(std::collections::VecDeque<Ast>);
|
#[macro_export] macro_rules! const_iter {
|
||||||
|
($(<$l:lifetime>)?|$self:ident: $Struct:ty| => $Item:ty => $expr:expr) => {
|
||||||
impl DslIter for AstIter {
|
impl$(<$l>)? Iterator for $Struct {
|
||||||
type Token = Ast;
|
type Item = $Item;
|
||||||
fn peek (&self) -> Option<Ast> {
|
fn next (&mut $self) -> Option<$Item> { $expr }
|
||||||
self.0.get(0).cloned()
|
|
||||||
}
|
}
|
||||||
fn next (&mut self) -> Option<Ast> {
|
impl$(<$l>)? ConstIntoIter for $Struct {
|
||||||
self.0.pop_front()
|
type Kind = IsIteratorKind;
|
||||||
|
type Item = $Item;
|
||||||
|
type IntoIter = Self;
|
||||||
}
|
}
|
||||||
fn rest (self) -> Vec<Ast> {
|
|
||||||
self.0.into()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source> From<SourceIter<'source>> for AstIter {
|
/// Owns a reference to the source text.
|
||||||
fn from (source: SourceIter<'source>) -> Self {
|
/// [SourceConstIter::next] emits subsequent pairs of:
|
||||||
Self(source.map(Into::into).collect())
|
/// * a [CstToken] and
|
||||||
|
/// * the source text remaining
|
||||||
|
/// * [ ] TODO: maybe [SourceConstIter::next] should wrap the remaining source in `Self` ?
|
||||||
|
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
||||||
|
pub struct SourceConstIter<'source>(pub &'source str);
|
||||||
|
|
||||||
|
impl<'source> From<SourceConstIter<'source>> for SourceIter<'source> {
|
||||||
|
fn from (source: SourceConstIter<'source>) -> Self{
|
||||||
|
Self(source)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,35 +78,6 @@ impl<'source> Into<Vec<Ast>> for SourceIter<'source> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implement the const iterator pattern.
|
|
||||||
#[macro_export] macro_rules! const_iter {
|
|
||||||
($(<$l:lifetime>)?|$self:ident: $Struct:ty| => $Item:ty => $expr:expr) => {
|
|
||||||
impl$(<$l>)? Iterator for $Struct {
|
|
||||||
type Item = $Item;
|
|
||||||
fn next (&mut $self) -> Option<$Item> { $expr }
|
|
||||||
}
|
|
||||||
impl$(<$l>)? ConstIntoIter for $Struct {
|
|
||||||
type Kind = IsIteratorKind;
|
|
||||||
type Item = $Item;
|
|
||||||
type IntoIter = Self;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Owns a reference to the source text.
|
|
||||||
/// [SourceConstIter::next] emits subsequent pairs of:
|
|
||||||
/// * a [CstToken] and
|
|
||||||
/// * the source text remaining
|
|
||||||
/// * [ ] TODO: maybe [SourceConstIter::next] should wrap the remaining source in `Self` ?
|
|
||||||
#[derive(Copy, Clone, Debug, Default, PartialEq)]
|
|
||||||
pub struct SourceConstIter<'source>(pub &'source str);
|
|
||||||
|
|
||||||
impl<'source> From<SourceConstIter<'source>> for SourceIter<'source> {
|
|
||||||
fn from (source: SourceConstIter<'source>) -> Self{
|
|
||||||
Self(source)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'source> From<&'source str> for SourceConstIter<'source> {
|
impl<'source> From<&'source str> for SourceConstIter<'source> {
|
||||||
fn from (source: &'source str) -> Self{
|
fn from (source: &'source str) -> Self{
|
||||||
Self::new(source)
|
Self::new(source)
|
||||||
|
|
@ -128,3 +106,25 @@ impl<'source> SourceConstIter<'source> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const_iter!(<'source>|self: SourceConstIter<'source>| => CstToken<'source> => self.next_mut().map(|(result, _)|result));
|
const_iter!(<'source>|self: SourceConstIter<'source>| => CstToken<'source> => self.next_mut().map(|(result, _)|result));
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default, PartialEq)]
|
||||||
|
pub struct AstIter(std::collections::VecDeque<Ast>);
|
||||||
|
|
||||||
|
impl DslIter for AstIter {
|
||||||
|
type Token = Ast;
|
||||||
|
fn peek (&self) -> Option<Ast> {
|
||||||
|
self.0.get(0).cloned()
|
||||||
|
}
|
||||||
|
fn next (&mut self) -> Option<Ast> {
|
||||||
|
self.0.pop_front()
|
||||||
|
}
|
||||||
|
fn rest (self) -> Vec<Ast> {
|
||||||
|
self.0.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source> From<SourceIter<'source>> for AstIter {
|
||||||
|
fn from (source: SourceIter<'source>) -> Self {
|
||||||
|
Self(source.map(Into::into).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
#[cfg(test)] mod test_token_iter {
|
#[cfg(test)] mod test_token_iter {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
//use proptest::prelude::*;
|
//use proptest::prelude::*;
|
||||||
#[test] fn test_iters () {
|
#[test] fn test_iters () {
|
||||||
let mut iter = crate::SourceIter::new(&":foo :bar");
|
let mut iter = crate::SourceIter::new(&":foo :bar");
|
||||||
let _ = iter.next();
|
let _ = iter.next();
|
||||||
let mut iter = crate::TokenIter::new(&":foo :bar");
|
|
||||||
let _ = iter.next();
|
|
||||||
}
|
}
|
||||||
#[test] const fn test_const_iters () {
|
#[test] const fn test_const_iters () {
|
||||||
let mut iter = crate::SourceIter::new(&":foo :bar");
|
let iter = crate::SourceConstIter::new(&":foo :bar");
|
||||||
let _ = iter.next();
|
let _ = iter.next();
|
||||||
}
|
}
|
||||||
#[test] fn test_num () {
|
#[test] fn test_num () {
|
||||||
let digit = to_digit('0');
|
let _digit = to_digit('0');
|
||||||
let digit = to_digit('x');
|
let _digit = to_digit('x');
|
||||||
let number = to_number(&"123");
|
let _number = to_number(&"123");
|
||||||
let number = to_number(&"12asdf3");
|
let _number = to_number(&"12asdf3");
|
||||||
}
|
}
|
||||||
//proptest! {
|
//proptest! {
|
||||||
//#[test] fn proptest_source_iter (
|
//#[test] fn proptest_source_iter (
|
||||||
|
|
@ -33,67 +33,54 @@
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)] mod test_token_prop {
|
//#[cfg(test)] mod test_token_prop {
|
||||||
use proptest::prelude::*;
|
//use crate::{CstToken, CstMeta, Value::*};
|
||||||
proptest! {
|
//use proptest::prelude::*;
|
||||||
#[test] fn test_token_prop (
|
//proptest! {
|
||||||
source in "\\PC*",
|
//#[test] fn test_token_prop (
|
||||||
start in usize::MIN..usize::MAX,
|
//source in "\\PC*",
|
||||||
length in usize::MIN..usize::MAX,
|
//start in usize::MIN..usize::MAX,
|
||||||
) {
|
//length in usize::MIN..usize::MAX,
|
||||||
let token = crate::Token {
|
//) {
|
||||||
source: &source,
|
//let token = CstToken(Nil, CstMeta { source: &source, start, length });
|
||||||
start,
|
//let _ = token.slice();
|
||||||
length,
|
//}
|
||||||
value: crate::Value::Nil
|
//}
|
||||||
};
|
//}
|
||||||
let _ = token.slice();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
#[cfg(test)] #[test] fn test_token () -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
use crate::Value::*;
|
||||||
let source = ":f00";
|
let source = ":f00";
|
||||||
let mut token = Token { source, start: 0, length: 1, value: Sym(":") };
|
let mut token = CstToken(Sym(":"), CstMeta { source, start: 0, length: 1 });
|
||||||
token = token.grow_sym();
|
token = token.grow_sym();
|
||||||
assert_eq!(token, Token { source, start: 0, length: 2, value: Sym(":f") });
|
assert_eq!(token, CstToken(Sym(":f"), CstMeta { source, start: 0, length: 2, }));
|
||||||
token = token.grow_sym();
|
token = token.grow_sym();
|
||||||
assert_eq!(token, Token { source, start: 0, length: 3, value: Sym(":f0") });
|
assert_eq!(token, CstToken(Sym(":f0"), CstMeta { source, start: 0, length: 3, }));
|
||||||
token = token.grow_sym();
|
token = token.grow_sym();
|
||||||
assert_eq!(token, Token { source, start: 0, length: 4, value: Sym(":f00") });
|
assert_eq!(token, CstToken(Sym(":f00"), CstMeta { source, start: 0, length: 4, }));
|
||||||
|
|
||||||
let src = "";
|
assert_eq!(None,
|
||||||
assert_eq!(None, SourceIter(src).next());
|
SourceIter::new("").next());
|
||||||
|
assert_eq!(None,
|
||||||
let src = " \n \r \t ";
|
SourceIter::new(" \n \r \t ").next());
|
||||||
assert_eq!(None, SourceIter(src).next());
|
assert_eq!(&Num(7),
|
||||||
|
SourceIter::new("7").next().unwrap().0.value());
|
||||||
let src = "7";
|
assert_eq!(&Num(100),
|
||||||
assert_eq!(Num(7), SourceIter(src).next().unwrap().0.value);
|
SourceIter::new(" 100 ").next().unwrap().0.value());
|
||||||
|
assert_eq!(&Err(Unexpected('a')),
|
||||||
let src = " 100 ";
|
SourceIter::new(" 9a ").next().unwrap().0.value());
|
||||||
assert_eq!(Num(100), SourceIter(src).next().unwrap().0.value);
|
assert_eq!(&Sym(":123foo"),
|
||||||
|
SourceIter::new(" :123foo ").next().unwrap().0.value());
|
||||||
let src = " 9a ";
|
assert_eq!(&Sym("@bar456"),
|
||||||
assert_eq!(Err(Unexpected('a')), SourceIter(src).next().unwrap().0.value);
|
SourceIter::new(" \r\r\r\n\n\n@bar456\t\t\t\t\t\t").next().unwrap().0.value());
|
||||||
|
assert_eq!(&Key("foo123"),
|
||||||
let src = " :123foo ";
|
SourceIter::new("foo123").next().unwrap().0.value());
|
||||||
assert_eq!(Sym(":123foo"), SourceIter(src).next().unwrap().0.value);
|
assert_eq!(&Key("foo/bar"),
|
||||||
|
SourceIter::new("foo/bar").next().unwrap().0.value());
|
||||||
let src = " \r\r\r\n\n\n@bar456\t\t\t\t\t\t";
|
assert_eq!(&Str("foo/bar"),
|
||||||
assert_eq!(Sym("@bar456"), SourceIter(src).next().unwrap().0.value);
|
SourceIter::new("\"foo/bar\"").next().unwrap().0.value());
|
||||||
|
assert_eq!(&Str("foo/bar"),
|
||||||
let src = "foo123";
|
SourceIter::new(" \"foo/bar\" ").next().unwrap().0.value());
|
||||||
assert_eq!(Key("foo123"), SourceIter(src).next().unwrap().0.value);
|
|
||||||
|
|
||||||
let src = "foo/bar";
|
|
||||||
assert_eq!(Key("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
|
||||||
|
|
||||||
let src = "\"foo/bar\"";
|
|
||||||
assert_eq!(Str("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
|
||||||
|
|
||||||
let src = " \"foo/bar\" ";
|
|
||||||
assert_eq!(Str("foo/bar"), SourceIter(src).next().unwrap().0.value);
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -108,7 +95,7 @@
|
||||||
//let mut expr = view.peek();
|
//let mut expr = view.peek();
|
||||||
//assert_eq!(view.0.0, source);
|
//assert_eq!(view.0.0, source);
|
||||||
//assert_eq!(expr, Some(Token {
|
//assert_eq!(expr, Some(Token {
|
||||||
//source, start: 0, length: source.len() - 1, value: Exp(0, SourceIter(&source[1..]))
|
//source, start: 0, length: source.len() - 1, value: Exp(0, SourceIter::new(&source[1..]))
|
||||||
//}));
|
//}));
|
||||||
////panic!("{view:?}");
|
////panic!("{view:?}");
|
||||||
////panic!("{:#?}", expr);
|
////panic!("{:#?}", expr);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,6 @@ mod input_handle; pub use self::input_handle::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(test, feature = "dsl"))] #[test] fn test_dsl_keymap () -> Usually<()> {
|
#[cfg(all(test, feature = "dsl"))] #[test] fn test_dsl_keymap () -> Usually<()> {
|
||||||
let keymap = SourceIter::new("");
|
let _keymap = SourceIter::new("");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,3 +16,4 @@ mod ops; pub use self::ops::*;
|
||||||
mod output; pub use self::output::*;
|
mod output; pub use self::output::*;
|
||||||
|
|
||||||
#[cfg(test)] mod test;
|
#[cfg(test)] mod test;
|
||||||
|
#[cfg(test)] pub use proptest_derive::Arbitrary;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::*;
|
use crate::{*, Direction::*};
|
||||||
use proptest_derive::Arbitrary;
|
//use proptest_derive::Arbitrary;
|
||||||
use proptest::{prelude::*, option::of};
|
use proptest::{prelude::*, option::of};
|
||||||
|
|
||||||
proptest! {
|
proptest! {
|
||||||
|
|
@ -86,7 +86,7 @@ macro_rules! test_op_transform {
|
||||||
if let Some(op) = match (op_x, op_y) {
|
if let Some(op) = match (op_x, op_y) {
|
||||||
(Some(x), Some(y)) => Some($Op::xy(x, y, content)),
|
(Some(x), Some(y)) => Some($Op::xy(x, y, content)),
|
||||||
(Some(x), None) => Some($Op::x(x, content)),
|
(Some(x), None) => Some($Op::x(x, content)),
|
||||||
(Some(y), None) => Some($Op::y(y, content)),
|
(None, Some(y)) => Some($Op::y(y, content)),
|
||||||
_ => None
|
_ => None
|
||||||
} {
|
} {
|
||||||
assert_eq!(Content::layout(&op, [x, y, w, h]),
|
assert_eq!(Content::layout(&op, [x, y, w, h]),
|
||||||
|
|
@ -142,7 +142,7 @@ proptest! {
|
||||||
fn area_mut (&mut self) -> &mut [u16;4] {
|
fn area_mut (&mut self) -> &mut [u16;4] {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
fn place (&mut self, _: [u16;4], _: &impl Render<TestOutput>) {
|
fn place <T: Render<Self> + ?Sized> (&mut self, _: [u16;4], _: &T) {
|
||||||
()
|
()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,9 +162,9 @@ proptest! {
|
||||||
#[test] fn test_iter_map () {
|
#[test] fn test_iter_map () {
|
||||||
struct Foo;
|
struct Foo;
|
||||||
impl<T: Output> Content<T> for Foo {}
|
impl<T: Output> Content<T> for Foo {}
|
||||||
fn make_map <T: Output, U: Content<T> + Send + Sync> (data: &Vec<U>) -> impl Content<T> {
|
fn _make_map <T: Output, U: Content<T> + Send + Sync> (data: &Vec<U>) -> impl Content<T> {
|
||||||
Map::new(||data.iter(), |foo, index|{})
|
Map::new(||data.iter(), |_foo, _index|{})
|
||||||
}
|
}
|
||||||
let data = vec![Foo, Foo, Foo];
|
let _data = vec![Foo, Foo, Foo];
|
||||||
//let map = make_map(&data);
|
//let map = make_map(&data);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ pub(crate) fn write_quote_to (out: &mut TokenStream2, quote: TokenStream2) {
|
||||||
assert_eq!(x.output, output);
|
assert_eq!(x.output, output);
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
let x: crate::proc_view::ViewImpl = pq! {
|
let _x: crate::proc_view::ViewImpl = pq! {
|
||||||
impl Foo {
|
impl Foo {
|
||||||
/// docstring1
|
/// docstring1
|
||||||
#[tengri::view(":view1")] #[bar] fn a_view () {}
|
#[tengri::view(":view1")] #[bar] fn a_view () {}
|
||||||
|
|
@ -86,7 +86,7 @@ pub(crate) fn write_quote_to (out: &mut TokenStream2, quote: TokenStream2) {
|
||||||
#[baz] fn is_not_view () {}
|
#[baz] fn is_not_view () {}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let expected_target: Ident = pq! { Foo };
|
let _expected_target: Ident = pq! { Foo };
|
||||||
//assert_eq!(x.target, expected_target);
|
//assert_eq!(x.target, expected_target);
|
||||||
//assert_eq!(x.items.len(), 2);
|
//assert_eq!(x.items.len(), 2);
|
||||||
//assert_eq!(x.items[0].item, pq! {
|
//assert_eq!(x.items[0].item, pq! {
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ impl ToTokens for CommandDef {
|
||||||
let mut out = TokenStream2::new();
|
let mut out = TokenStream2::new();
|
||||||
for (arg, _ty) in arm.args() {
|
for (arg, _ty) in arm.args() {
|
||||||
write_quote_to(&mut out, quote! {
|
write_quote_to(&mut out, quote! {
|
||||||
#arg: Take::take_or_fail(self, words)?,
|
#arg: Dsl::try_provide(self, words)?,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
|
|
@ -149,8 +149,8 @@ impl ToTokens for CommandDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Generated by [tengri_proc::command].
|
/// Generated by [tengri_proc::command].
|
||||||
impl ::tengri::dsl::Take<#state> for #command_enum {
|
impl ::tengri::dsl::Dsl<#state> for #command_enum {
|
||||||
fn take (state: &#state, mut words: ::tengri::dsl::Cst) -> Perhaps<Self> {
|
fn try_provide (state: &#state, mut words: ::tengri::dsl::Ast) -> Perhaps<Self> {
|
||||||
let mut words = words.clone();
|
let mut words = words.clone();
|
||||||
let token = words.next();
|
let token = words.next();
|
||||||
todo!()//Ok(match token { #(#matchers)* _ => None })
|
todo!()//Ok(match token { #(#matchers)* _ => None })
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,8 @@ impl ToTokens for ExposeImpl {
|
||||||
});
|
});
|
||||||
write_quote_to(out, quote! {
|
write_quote_to(out, quote! {
|
||||||
/// Generated by [tengri_proc::expose].
|
/// Generated by [tengri_proc::expose].
|
||||||
impl ::tengri::dsl::Take<#state> for #t {
|
impl ::tengri::dsl::Dsl<#state> for #t {
|
||||||
fn take (state: &#state, mut words: ::tengri::dsl::Cst) -> Perhaps<Self> {
|
fn try_provide (state: &#state, mut words: ::tengri::dsl::Ast) -> Perhaps<Self> {
|
||||||
Ok(Some(match words.next().map(|x|x.value) {
|
Ok(Some(match words.next().map(|x|x.value) {
|
||||||
#predefined
|
#predefined
|
||||||
#(#values)*
|
#(#values)*
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ impl ToTokens for ViewDef {
|
||||||
// that operate over constants and symbols.
|
// that operate over constants and symbols.
|
||||||
let builtin = builtins_with_boxes_output(quote! { #output }).map(|builtin|quote! {
|
let builtin = builtins_with_boxes_output(quote! { #output }).map(|builtin|quote! {
|
||||||
::tengri::dsl::Value::Exp(_, expr) => return Ok(Some(
|
::tengri::dsl::Value::Exp(_, expr) => return Ok(Some(
|
||||||
#builtin::take_or_fail(state, expr, ||"failed to load builtin")?.boxed()
|
#builtin::try_provide(state, expr, ||"failed to load builtin")?.boxed()
|
||||||
)),
|
)),
|
||||||
});
|
});
|
||||||
// Symbols are handled by user-taked functions
|
// Symbols are handled by user-taked functions
|
||||||
|
|
@ -63,11 +63,8 @@ impl ToTokens for ViewDef {
|
||||||
/// Makes [#self_ty] able to construct the [Render]able
|
/// Makes [#self_ty] able to construct the [Render]able
|
||||||
/// which might correspond to a given [TokenStream],
|
/// which might correspond to a given [TokenStream],
|
||||||
/// while taking [#self_ty]'s state into consideration.
|
/// while taking [#self_ty]'s state into consideration.
|
||||||
impl<'source, 'state: 'source>
|
impl<'state> ::tengri::dsl::Dsl<Box<dyn Render<#output> + 'state>> for #self_ty {
|
||||||
Take<'state, 'source, #self_ty>
|
fn try_provide (state: &'state #self_ty, mut words: ::tengri::dsl::Ast) -> Perhaps<Box<dyn Render<#output> + 'state>> {
|
||||||
for Box<dyn Render<#output> + 'state>
|
|
||||||
{
|
|
||||||
fn take (state: &'state #self_ty, mut words: Cst<'source>) -> Perhaps<Self> {
|
|
||||||
Ok(if let Some(::tengri::dsl::Token { value, .. }) = words.peek() {
|
Ok(if let Some(::tengri::dsl::Token { value, .. }) = words.peek() {
|
||||||
match value { #(#builtin)* #(#exposed)* _ => None }
|
match value { #(#builtin)* #(#exposed)* _ => None }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -5,96 +5,4 @@ pub use ::tengri_core::*;
|
||||||
#[cfg(feature="tui")] pub use ::tengri_tui as tui;
|
#[cfg(feature="tui")] pub use ::tengri_tui as tui;
|
||||||
|
|
||||||
#[cfg(test)] extern crate tengri_proc;
|
#[cfg(test)] extern crate tengri_proc;
|
||||||
#[cfg(test)] #[test] fn test_subcommand () -> Usually<()> {
|
#[cfg(test)] mod test;
|
||||||
use crate::input::{Command, InputMap, KeyMap, Handle, handle};
|
|
||||||
use crate::dsl::TokenIter;
|
|
||||||
use crate::tui::TuiIn;
|
|
||||||
use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState};
|
|
||||||
//use crate::input::*;
|
|
||||||
//use crate::dsl::*;
|
|
||||||
struct Test {
|
|
||||||
keys: InputMap<'static, Test, TestCommand, TuiIn, TokenIter<'static>>
|
|
||||||
}
|
|
||||||
handle!(TuiIn: |self: Test, input|if let Some(command) = self.keys.command(self, input) {
|
|
||||||
Ok(Some(true))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
});
|
|
||||||
#[tengri_proc::command(Test)] impl TestCommand {
|
|
||||||
fn do_thing (state: &mut Test) -> Perhaps<Self> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
fn do_thing_arg (state: &mut Test, arg: usize) -> Perhaps<Self> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps<Self> {
|
|
||||||
Ok(command.execute(state)?.map(|command|Self::DoSub { command }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[tengri_proc::command(Test)] impl TestSubcommand {
|
|
||||||
fn do_other_thing (state: &mut Test) -> Perhaps<Self> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
fn do_other_thing_arg (state: &mut Test, arg: usize) -> Perhaps<Self> {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut test = Test {
|
|
||||||
keys: InputMap::new("
|
|
||||||
(@a do-thing)
|
|
||||||
(@b do-thing-arg 0)
|
|
||||||
(@c do-sub do-other-thing)
|
|
||||||
(@d do-sub do-other-thing-arg 0)
|
|
||||||
".into())
|
|
||||||
};
|
|
||||||
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
code: KeyCode::Char('a'),
|
|
||||||
modifiers: KeyModifiers::NONE,
|
|
||||||
state: KeyEventState::NONE,
|
|
||||||
})))?);
|
|
||||||
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
code: KeyCode::Char('b'),
|
|
||||||
modifiers: KeyModifiers::NONE,
|
|
||||||
state: KeyEventState::NONE,
|
|
||||||
})))?);
|
|
||||||
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
code: KeyCode::Char('c'),
|
|
||||||
modifiers: KeyModifiers::NONE,
|
|
||||||
state: KeyEventState::NONE,
|
|
||||||
})))?);
|
|
||||||
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
code: KeyCode::Char('d'),
|
|
||||||
modifiers: KeyModifiers::NONE,
|
|
||||||
state: KeyEventState::NONE,
|
|
||||||
})))?);
|
|
||||||
assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
|
||||||
kind: KeyEventKind::Press,
|
|
||||||
code: KeyCode::Char('z'),
|
|
||||||
modifiers: KeyModifiers::NONE,
|
|
||||||
state: KeyEventState::NONE,
|
|
||||||
})))?);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME:
|
|
||||||
//#[cfg(test)] #[test] fn test_dsl_context () {
|
|
||||||
//use crate::dsl::{Dsl, Value};
|
|
||||||
|
|
||||||
//struct Test;
|
|
||||||
//#[tengri_proc::expose]
|
|
||||||
//impl Test {
|
|
||||||
//fn some_bool (&self) -> bool {
|
|
||||||
//true
|
|
||||||
//}
|
|
||||||
//}
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Sym(":false")), Some(false));
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Sym(":true")), Some(true));
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Sym(":some-bool")), Some(true));
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Sym(":missing-bool")), None);
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Num(0)), Some(false));
|
|
||||||
//assert_eq!(Dsl::get(&Test, &Value::Num(1)), Some(true));
|
|
||||||
//}
|
|
||||||
|
|
|
||||||
97
tengri/src/test.rs
Normal file
97
tengri/src/test.rs
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
#[test] fn test_subcommand () -> Usually<()> {
|
||||||
|
use crate::input::{Command, Handle, handle};
|
||||||
|
//use crate::dsl::TokenIter;
|
||||||
|
use crate::tui::TuiIn;
|
||||||
|
use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers, KeyEventKind, KeyEventState};
|
||||||
|
//use crate::input::*;
|
||||||
|
//use crate::dsl::*;
|
||||||
|
struct Test {
|
||||||
|
//keys: InputMap<'static, Test, TestCommand, TuiIn, TokenIter<'static>>
|
||||||
|
}
|
||||||
|
handle!(TuiIn: |self: Test, input|if let Some(command) = self.keys.command(self, input) {
|
||||||
|
Ok(Some(true))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
});
|
||||||
|
#[tengri_proc::command(Test)]
|
||||||
|
impl TestCommand {
|
||||||
|
fn do_thing (_state: &mut Test) -> Perhaps<Self> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
fn do_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
fn do_sub (state: &mut Test, command: TestSubcommand) -> Perhaps<Self> {
|
||||||
|
Ok(command.execute(state)?.map(|command|Self::DoSub { command }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[tengri_proc::command(Test)]
|
||||||
|
impl TestSubcommand {
|
||||||
|
fn do_other_thing (_state: &mut Test) -> Perhaps<Self> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
fn do_other_thing_arg (_state: &mut Test, _arg: usize) -> Perhaps<Self> {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut test = Test {
|
||||||
|
keys: InputMap::new("
|
||||||
|
(@a do-thing)
|
||||||
|
(@b do-thing-arg 0)
|
||||||
|
(@c do-sub do-other-thing)
|
||||||
|
(@d do-sub do-other-thing-arg 0)
|
||||||
|
".into())
|
||||||
|
};
|
||||||
|
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
code: KeyCode::Char('a'),
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
state: KeyEventState::NONE,
|
||||||
|
})))?);
|
||||||
|
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
code: KeyCode::Char('b'),
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
state: KeyEventState::NONE,
|
||||||
|
})))?);
|
||||||
|
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
code: KeyCode::Char('c'),
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
state: KeyEventState::NONE,
|
||||||
|
})))?);
|
||||||
|
assert_eq!(Some(true), test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
code: KeyCode::Char('d'),
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
state: KeyEventState::NONE,
|
||||||
|
})))?);
|
||||||
|
assert_eq!(None, test.handle(&TuiIn(Default::default(), Event::Key(KeyEvent {
|
||||||
|
kind: KeyEventKind::Press,
|
||||||
|
code: KeyCode::Char('z'),
|
||||||
|
modifiers: KeyModifiers::NONE,
|
||||||
|
state: KeyEventState::NONE,
|
||||||
|
})))?);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME:
|
||||||
|
//#[cfg(test)] #[test] fn test_dsl_context () {
|
||||||
|
//use crate::dsl::{Dsl, Value};
|
||||||
|
|
||||||
|
//struct Test;
|
||||||
|
//#[tengri_proc::expose]
|
||||||
|
//impl Test {
|
||||||
|
//fn some_bool (&self) -> bool {
|
||||||
|
//true
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Sym(":false")), Some(false));
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Sym(":true")), Some(true));
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Sym(":some-bool")), Some(true));
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Sym(":missing-bool")), None);
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Num(0)), Some(false));
|
||||||
|
//assert_eq!(Dsl::get(&Test, &Value::Num(1)), Some(true));
|
||||||
|
//}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use tengri::{self, Usually, Perhaps, input::*, output::*, tui::*, dsl::*};
|
use tengri::{self, Usually, Perhaps, input::*, output::*, tui::*, dsl::*};
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use crossterm::event::{*, KeyCode::*};
|
//use crossterm::event::{*, KeyCode::*};
|
||||||
use crate::ratatui::style::Color;
|
use crate::ratatui::style::Color;
|
||||||
|
|
||||||
fn main () -> Usually<()> {
|
fn main () -> Usually<()> {
|
||||||
|
|
@ -13,23 +13,23 @@ fn main () -> Usually<()> {
|
||||||
|
|
||||||
const KEYMAP: &str = "(@left prev) (@right next)";
|
const KEYMAP: &str = "(@left prev) (@right next)";
|
||||||
const EXAMPLES: &'static [&'static str] = &[
|
const EXAMPLES: &'static [&'static str] = &[
|
||||||
include_str!("edn01.edn"),
|
include_str!("edn/edn01.edn"),
|
||||||
include_str!("edn02.edn"),
|
include_str!("edn/edn02.edn"),
|
||||||
include_str!("edn03.edn"),
|
include_str!("edn/edn03.edn"),
|
||||||
include_str!("edn04.edn"),
|
include_str!("edn/edn04.edn"),
|
||||||
include_str!("edn05.edn"),
|
include_str!("edn/edn05.edn"),
|
||||||
include_str!("edn06.edn"),
|
include_str!("edn/edn06.edn"),
|
||||||
include_str!("edn07.edn"),
|
include_str!("edn/edn07.edn"),
|
||||||
include_str!("edn08.edn"),
|
include_str!("edn/edn08.edn"),
|
||||||
include_str!("edn09.edn"),
|
include_str!("edn/edn09.edn"),
|
||||||
include_str!("edn10.edn"),
|
include_str!("edn/edn10.edn"),
|
||||||
include_str!("edn11.edn"),
|
include_str!("edn/edn11.edn"),
|
||||||
include_str!("edn12.edn"),
|
include_str!("edn/edn12.edn"),
|
||||||
//include_str!("edn13.edn"),
|
//include_str!("edn/edn13.edn"),
|
||||||
include_str!("edn14.edn"),
|
include_str!("edn/edn14.edn"),
|
||||||
include_str!("edn15.edn"),
|
include_str!("edn/edn15.edn"),
|
||||||
include_str!("edn16.edn"),
|
include_str!("edn/edn16.edn"),
|
||||||
include_str!("edn17.edn"),
|
include_str!("edn/edn17.edn"),
|
||||||
];
|
];
|
||||||
|
|
||||||
handle!(TuiIn: |self: Example, input|{
|
handle!(TuiIn: |self: Example, input|{
|
||||||
|
|
@ -63,7 +63,7 @@ impl ExampleCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
view!(TuiOut: |self: Example|{
|
content!(TuiOut: |self: Example|{
|
||||||
let index = self.0 + 1;
|
let index = self.0 + 1;
|
||||||
let wh = self.1.wh();
|
let wh = self.1.wh();
|
||||||
let src = EXAMPLES.get(self.0).unwrap_or(&"");
|
let src = EXAMPLES.get(self.0).unwrap_or(&"");
|
||||||
|
|
@ -72,12 +72,29 @@ view!(TuiOut: |self: Example|{
|
||||||
let code = Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", src))));
|
let code = Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", src))));
|
||||||
let content = Tui::bg(Color::Rgb(10, 10, 60), View(self, TokenIter::new(src)));
|
let content = Tui::bg(Color::Rgb(10, 10, 60), View(self, TokenIter::new(src)));
|
||||||
self.1.of(Bsp::s(title, Bsp::n(""/*code*/, content)))
|
self.1.of(Bsp::s(title, Bsp::n(""/*code*/, content)))
|
||||||
}; {
|
|
||||||
":title" => Tui::bg(Color::Rgb(60, 10, 10), Push::y(1, Align::n(format!("Example {}/{}:", self.0 + 1, EXAMPLES.len())))).boxed(),
|
|
||||||
":code" => Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", EXAMPLES[self.0])))).boxed(),
|
|
||||||
":hello" => Tui::bg(Color::Rgb(10, 100, 10), "Hello").boxed(),
|
|
||||||
":world" => Tui::bg(Color::Rgb(100, 10, 10), "world").boxed(),
|
|
||||||
":hello-world" => "Hello world!".boxed(),
|
|
||||||
":map-e" => Map::east(5u16, ||0..5u16, |n, i|format!("{n}")).boxed(),
|
|
||||||
":map-s" => Map::south(5u16, ||0..5u16, |n, i|format!("{n}")).boxed(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
#[tengri_proc::view(TuiOut)]
|
||||||
|
impl Example {
|
||||||
|
pub fn title (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Tui::bg(Color::Rgb(60, 10, 10), Push::y(1, Align::n(format!("Example {}/{}:", self.0 + 1, EXAMPLES.len())))).boxed()
|
||||||
|
}
|
||||||
|
pub fn code (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Tui::bg(Color::Rgb(10, 60, 10), Push::y(2, Align::n(format!("{}", EXAMPLES[self.0])))).boxed()
|
||||||
|
}
|
||||||
|
pub fn hello (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Tui::bg(Color::Rgb(10, 100, 10), "Hello").boxed()
|
||||||
|
}
|
||||||
|
pub fn world (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Tui::bg(Color::Rgb(100, 10, 10), "world").boxed()
|
||||||
|
}
|
||||||
|
pub fn hello_world (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
"Hello world!".boxed()
|
||||||
|
}
|
||||||
|
pub fn map_e (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Map::east(5u16, ||0..5u16, |n, _i|format!("{n}")).boxed()
|
||||||
|
}
|
||||||
|
pub fn map_s (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
Map::south(5u16, ||0..5u16, |n, _i|format!("{n}")).boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ pub(crate) use std::io::{stdout, Stdout};
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_tui_engine () -> Usually<()> {
|
#[cfg(test)] #[test] fn test_tui_engine () -> Usually<()> {
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use std::sync::{Arc, RwLock};
|
//use std::sync::{Arc, RwLock};
|
||||||
struct TestComponent(String);
|
struct TestComponent(String);
|
||||||
impl Content<TuiOut> for TestComponent {
|
impl Content<TuiOut> for TestComponent {
|
||||||
fn content (&self) -> impl Render<TuiOut> {
|
fn content (&self) -> impl Render<TuiOut> {
|
||||||
|
|
@ -44,21 +44,21 @@ pub(crate) use std::io::{stdout, Stdout};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Handle<TuiIn> for TestComponent {
|
impl Handle<TuiIn> for TestComponent {
|
||||||
fn handle (&mut self, from: &TuiIn) -> Perhaps<bool> {
|
fn handle (&mut self, _from: &TuiIn) -> Perhaps<bool> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let engine = Tui::new()?;
|
let engine = Tui::new()?;
|
||||||
engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed);
|
engine.read().unwrap().exited.store(true, std::sync::atomic::Ordering::Relaxed);
|
||||||
let state = TestComponent("hello world".into());
|
let state = TestComponent("hello world".into());
|
||||||
let state = std::sync::Arc::new(std::sync::RwLock::new(state));
|
let _state = std::sync::Arc::new(std::sync::RwLock::new(state));
|
||||||
//engine.run(&state)?;
|
//engine.run(&state)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)] #[test] fn test_parse_key () {
|
#[cfg(test)] #[test] fn test_parse_key () {
|
||||||
use KeyModifiers as Mods;
|
//use KeyModifiers as Mods;
|
||||||
let test = |x: &str, y|assert_eq!(KeyMatcher::new(x).build(), Some(Event::Key(y)));
|
let _test = |x: &str, y|assert_eq!(KeyMatcher::new(x).build(), Some(Event::Key(y)));
|
||||||
//test(":x",
|
//test(":x",
|
||||||
//KeyEvent::new(KeyCode::Char('x'), Mods::NONE));
|
//KeyEvent::new(KeyCode::Char('x'), Mods::NONE));
|
||||||
//test(":ctrl-x",
|
//test(":ctrl-x",
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ impl<T, U> Field<T, U> {
|
||||||
value_align: None,
|
value_align: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn label <L> (
|
pub fn label <L> (
|
||||||
self,
|
self,
|
||||||
label: Option<L>,
|
label: Option<L>,
|
||||||
align: Option<Direction>,
|
align: Option<Direction>,
|
||||||
|
|
@ -75,7 +75,7 @@ impl<T, U> Field<T, U> {
|
||||||
..self
|
..self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn value <V> (
|
pub fn value <V> (
|
||||||
self,
|
self,
|
||||||
value: Option<V>,
|
value: Option<V>,
|
||||||
align: Option<Direction>,
|
align: Option<Direction>,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
render!(TuiOut: |self: u64, to|todo!());
|
render!(TuiOut: |self: u64, _to|todo!());
|
||||||
|
|
||||||
render!(TuiOut: |self: f64, to|todo!());
|
render!(TuiOut: |self: f64, _to|todo!());
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,13 @@ impl TuiIn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "dsl")]
|
//#[cfg(feature = "dsl")]
|
||||||
impl DslInput for TuiIn {
|
//impl DslInput for TuiIn {
|
||||||
fn matches_dsl (&self, token: &str) -> bool {
|
//fn matches_dsl (&self, token: &str) -> bool {
|
||||||
if let Some(event) = KeyMatcher::new(token).build() {
|
//if let Some(event) = KeyMatcher::new(token).build() {
|
||||||
&event == self.event()
|
//&event == self.event()
|
||||||
} else {
|
//} else {
|
||||||
false
|
//false
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue