mirror of
https://codeberg.org/unspeaker/tengri.git
synced 2026-08-28 05:06:56 +02:00
parent
a9f2fa2cdd
commit
291ab63224
11 changed files with 98 additions and 96 deletions
19
Justfile
19
Justfile
|
|
@ -1,6 +1,9 @@
|
|||
export CARGO_INCREMENTAL := '0'
|
||||
export RUSTFLAGS := '-Zmacro-backtrace -Cinstrument-coverage'
|
||||
export RUSTDOCFLAGS := '-Zmacro-backtrace -Cinstrument-coverage'
|
||||
export LLVM_PROFILE_FILE := "cov/cargo-test-%p-%m.profraw"
|
||||
grcov-binary := "--binary-path ./target/coverage/deps/"
|
||||
grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
||||
grcov-binary := "--binary-path ./target/coverage/build/tengri"
|
||||
grcov-ignore := ""#--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'"
|
||||
|
||||
[private]
|
||||
default:
|
||||
|
|
@ -10,24 +13,20 @@ bacon:
|
|||
bacon -s
|
||||
|
||||
cov:
|
||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
||||
time cargo test -j4 --workspace --profile coverage
|
||||
time cargo test -j4 --workspace --profile coverage
|
||||
rm -rf target/coverage/html || true
|
||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t html -o target/coverage/html && reset
|
||||
|
||||
cov-md:
|
||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
||||
time cargo test -j4 --workspace --profile coverage
|
||||
time cargo test -j4 --workspace --profile coverage
|
||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
||||
|
||||
cov-md-ci:
|
||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' \
|
||||
time cargo test -j4 --workspace --profile coverage -- --skip test_tui_engine
|
||||
time cargo test -j4 --workspace --profile coverage -- --skip test_tui_engine
|
||||
time grcov . -s . {{grcov-binary}} {{grcov-ignore}} -t markdown | sort
|
||||
|
||||
doc:
|
||||
CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' \
|
||||
cargo doc
|
||||
cargo doc
|
||||
|
||||
mode MODE:
|
||||
cargo run --example "mode_{{MODE}}"
|
||||
|
|
|
|||
12
bacon.toml
12
bacon.toml
|
|
@ -1,14 +1,15 @@
|
|||
default_job = "check-all"
|
||||
default_job = "coverage"
|
||||
|
||||
env.CARGO_TERM_COLOR = "always"
|
||||
env.RUSTFLAGS = "-Zmacro-backtrace"
|
||||
|
||||
[keybindings]
|
||||
c = "job:check"
|
||||
C = "job:clippy"
|
||||
d = "job:doc"
|
||||
D = "job:doc-open"
|
||||
t = "job:test"
|
||||
T = "job:nextest"
|
||||
l = "job:clippy"
|
||||
T = "job:coverage"
|
||||
|
||||
[jobs]
|
||||
|
||||
|
|
@ -27,6 +28,11 @@ command = ["cargo", "test"]
|
|||
need_stdout = true
|
||||
watch = ["tengri"]
|
||||
|
||||
[jobs.coverage]
|
||||
command = ["just", "cov"]
|
||||
need_stdout = true
|
||||
watch = ["src", "proc"]
|
||||
|
||||
[jobs.doc]
|
||||
command = ["cargo", "doc", "--no-deps"]
|
||||
need_stdout = false
|
||||
|
|
|
|||
2
dizzle
2
dizzle
|
|
@ -1 +1 @@
|
|||
Subproject commit 648be30918bef0a975bd225c0499911aaa88bc13
|
||||
Subproject commit 3c80e3bb8c1d104f61f212b4961d927ac845e289
|
||||
|
|
@ -27,7 +27,7 @@ tui_keys!(self: State, input {
|
|||
});
|
||||
|
||||
tui_view!(self: State {
|
||||
let title = "Demo [Mode 01]";
|
||||
let title = "Demo [Mode 01";
|
||||
let items = self.history.iter().take(10).map(|x|format!("{x:?}")).join("\n");
|
||||
let history = format!("History: {}\n{items}", self.history.len());
|
||||
let cursor = format!("Counter: {}", self.cursor);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ tui_view!(self: State {
|
|||
let heading = format!("Demo [Mode 02]\nExample {}/{}\nSize {:?}", index, VIEWS.len(), &wh);
|
||||
let title = bg(Color::Rgb(60, 10, 10), heading);
|
||||
let code = bg(Color::Rgb(10, 60, 10), format!("Source:\n{}", src).max_h(10));
|
||||
let widget = draw(move|to: &mut Tui|self.interpret(to, &src)); // FIXME this forcefills
|
||||
let widget = draw(move|to: &mut Tui|self.interpret(to, src)); // FIXME this forcefills
|
||||
let sidebar = bg(Color::Rgb(20, 20, 20), north(code, title)).max_w(40);
|
||||
let content = bg(Color::Rgb(64, 64, 64), widget);
|
||||
east(sidebar, ShowSizeOf(content))
|
||||
|
|
@ -31,22 +31,8 @@ tui_view!(self: State {
|
|||
//self.size.of(bg(Color::Rgb(10, 10, 10), east(sidebar, content)).full_w())
|
||||
});
|
||||
|
||||
impl_keywords!(Tui, XYWH<u16>, State [
|
||||
kw_when,
|
||||
kw_either,
|
||||
kw_split,
|
||||
kw_align,
|
||||
kw_exact,
|
||||
kw_min,
|
||||
kw_max,
|
||||
kw_push,
|
||||
kw_tui_text,
|
||||
kw_tui_fg,
|
||||
kw_tui_bg
|
||||
]);
|
||||
|
||||
impl<'a> Interpret<'a, Tui, Option<XYWH<u16>>> for State {
|
||||
fn interpret_word <L: Language<'a> + ?Sized> (&'a self, to: &mut Tui, lang: &'a L)
|
||||
fn interpret_word <L: Language + ?Sized> (&'a self, to: &mut Tui, lang: &'a L)
|
||||
-> Drawn<'a, u16>
|
||||
{
|
||||
match lang.src()? {
|
||||
|
|
@ -56,13 +42,20 @@ impl<'a> Interpret<'a, Tui, Option<XYWH<u16>>> for State {
|
|||
src => todo!("src: {src:?}")
|
||||
}
|
||||
}
|
||||
fn interpret_expr <L: Language<'a> + ?Sized> (&self, to: &mut Tui, src: &'a L)
|
||||
fn interpret_expr <L: Language + ?Sized> (&'a self, to: &mut Tui, src: &'a L)
|
||||
-> Drawn<'a, u16>
|
||||
{
|
||||
if let Some(area) = self.keyword(to, src)? {
|
||||
Ok(Some(area))
|
||||
if let Some(src) = src.src()? {
|
||||
interpret_keyword!(self, to, src, [
|
||||
kw_when, kw_either,
|
||||
kw_split, kw_align,
|
||||
kw_exact, kw_min, kw_max,
|
||||
kw_push, kw_pull,
|
||||
kw_tui_text, kw_tui_fg, kw_tui_bg
|
||||
]);
|
||||
Err(format!("interpret_expr: unexpected: {src:?}").into())
|
||||
} else {
|
||||
Err(format!("App::interpret_expr: unexpected: {src:?}").into())
|
||||
Err(format!("interpret_expr: no keyword: {src:?}").into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ pub enum Pad<'a, S: Screen, I: Draw<'a, S>, X: Into<Option<S::Unit>>> {
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_layout_full () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_layout_full () -> Usually<()> {
|
||||
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
||||
/// assert_eq!(check_layout("1".full_w())?, Some(XYWH(1u16, 1, 80, 1)));
|
||||
/// assert_eq!(check_layout("1".full_h())?, Some(XYWH(1u16, 1, 1, 25)));
|
||||
/// assert_eq!(check_layout("1".full_wh())?, Some(XYWH(1u16, 1, 80, 25)));
|
||||
/// # Ok(()) }}
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub trait LayoutFull<'a, S: Screen>: Draw<'a, S> + Sized {
|
||||
fn full_w (self) -> Full<'a, S, Self> { Full::W(self) }
|
||||
|
|
@ -43,12 +43,12 @@ pub trait LayoutFull<'a, S: Screen>: Draw<'a, S> + Sized {
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_layout_exact () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_layout_exact () -> Usually<()> {
|
||||
/// assert_eq!(check_layout("FOOBAR\nKILROY")?, Some(XYWH(1, 1, 6, 2)));
|
||||
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_w(3))?, Some(XYWH(1, 1, 3, 2)));
|
||||
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_h(1))?, Some(XYWH(1, 1, 6, 1)));
|
||||
/// assert_eq!(check_layout("FOOBAR\nKILROY".exact_wh(2, 1))?, Some(XYWH(1, 1, 2, 1)));
|
||||
/// # Ok(()) }}
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub trait LayoutExact<'a, S: Screen>: Draw<'a, S> + Sized {
|
||||
fn exact_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
||||
|
|
@ -60,12 +60,12 @@ pub trait LayoutExact<'a, S: Screen>: Draw<'a, S> + Sized {
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_layout_min () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_layout_min () -> Usually<()> {
|
||||
/// assert_eq!(check_layout("1".min_w(5))?, Some(XYWH(1u16, 1, 5, 1)));
|
||||
/// assert_eq!(check_layout("1".min_h(5))?, Some(XYWH(1u16, 1, 1, 5)));
|
||||
/// assert_eq!(check_layout("1".min_wh(5, 5))?, Some(XYWH(1u16, 1, 5, 5)));
|
||||
/// assert_eq!(check_layout("123456".min_w(5))?, Some(XYWH(1u16, 1, 6, 1)));
|
||||
/// # Ok(()) }}
|
||||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub trait LayoutMin<'a, S: Screen>: Draw<'a, S> + Sized {
|
||||
fn min_w <X: Into<Option<S::Unit>> + Copy> (self, w: X)
|
||||
|
|
@ -95,7 +95,7 @@ pub trait LayoutPad<'a, S: Screen>: Draw<'a, S> + Sized {
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_layout_pull () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_layout_pull () -> Usually<()> {
|
||||
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
||||
/// assert_eq!(check_layout("1".push_x(1))?, Some(XYWH(2u16, 1, 1, 1)));
|
||||
/// assert_eq!(check_layout("1".push_y(1))?, Some(XYWH(1u16, 2, 1, 1)));
|
||||
|
|
@ -112,7 +112,7 @@ pub trait LayoutPush<'a, S: Screen>: Draw<'a, S> + Sized {
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_layout_push () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_layout_push () -> Usually<()> {
|
||||
/// assert_eq!(check_layout("1")?, Some(XYWH(1u16, 1, 1, 1)));
|
||||
/// assert_eq!(check_layout("1".pull_x(1))?, Some(XYWH(0u16, 1, 1, 1)));
|
||||
/// assert_eq!(check_layout("1".pull_y(1))?, Some(XYWH(1u16, 0, 1, 1)));
|
||||
|
|
@ -160,14 +160,14 @@ where
|
|||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("exact/w") => thunk.exact_w(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("exact/h") => thunk.exact_h(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("exact/wh") => thunk.exact_wh(
|
||||
state.namespace(expr.nth(1)?)?,
|
||||
state.namespace(expr.nth(2)?)?,
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
|
|
@ -186,14 +186,14 @@ where
|
|||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("min/w") => thunk.min_w(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("min/h") => thunk.min_h(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("min/wh") => thunk.min_wh(
|
||||
state.namespace(expr.nth(1)?)?,
|
||||
state.namespace(expr.nth(2)?)?,
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
|
|
@ -212,14 +212,14 @@ where
|
|||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("max/w") => thunk.max_w(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("max/h") => thunk.max_h(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("max/wh") => thunk.max_wh(
|
||||
state.namespace(expr.nth(1)?)?,
|
||||
state.namespace(expr.nth(2)?)?,
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
|
|
@ -237,9 +237,12 @@ where
|
|||
{
|
||||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("push/w") => thunk.push_x(state.namespace(expr.nth(1)?)?).draw(to)?,
|
||||
Some("push/h") => thunk.push_y(state.namespace(expr.nth(1)?)?).draw(to)?,
|
||||
Some("push/wh") => thunk.push_xy(state.namespace(expr.nth(1)?)?, state.namespace(expr.nth(2)?)?,).draw(to)?,
|
||||
Some("push/w") => thunk.push_x(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
||||
Some("push/h") => thunk.push_y(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
||||
Some("push/wh") => thunk.push_xy(
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
}
|
||||
|
|
@ -256,9 +259,12 @@ where
|
|||
{
|
||||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("pull/w") => thunk.pull_x(state.namespace(expr.nth(1)?)?).draw(to)?,
|
||||
Some("pull/h") => thunk.pull_y(state.namespace(expr.nth(1)?)?).draw(to)?,
|
||||
Some("pull/wh") => thunk.pull_xy(state.namespace(expr.nth(1)?)?, state.namespace(expr.nth(2)?)?,).draw(to)?,
|
||||
Some("pull/w") => thunk.pull_x(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
||||
Some("pull/h") => thunk.pull_y(state.namespace(&expr.nth(1)?)?).draw(to)?,
|
||||
Some("pull/wh") => thunk.pull_xy(
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
}
|
||||
|
|
@ -276,14 +282,14 @@ where
|
|||
let thunk = draw(move|screen|ok_flat(expr.last()?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(match expr.head()? {
|
||||
Some("pad/w") => thunk.pad_w(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("pad/h") => thunk.pad_h(
|
||||
state.namespace(expr.nth(1)?)?
|
||||
state.namespace(&expr.nth(1)?)?
|
||||
).draw(to)?,
|
||||
Some("pad/wh") => thunk.pad_wh(
|
||||
state.namespace(expr.nth(1)?)?,
|
||||
state.namespace(expr.nth(2)?)?,
|
||||
state.namespace(&expr.nth(1)?)?,
|
||||
state.namespace(&expr.nth(2)?)?,
|
||||
).draw(to)?,
|
||||
_ => return Err(format!("invalid variant: {:?}", expr.head()?).into())
|
||||
})
|
||||
|
|
@ -438,6 +444,6 @@ impl<'a, S: Screen, T: Draw<'a, S>> LayoutPull<'a, S> for T {}
|
|||
|
||||
impl<'a, S: Screen, T: Draw<'a, S>> LayoutPad<'a, S> for T {}
|
||||
|
||||
#[cfg(test)] fn check_layout <'a> (t: impl Draw<'a, Tui>) -> Drawn<'a, u16> {
|
||||
pub fn check_layout <'a> (t: impl Draw<'a, Tui>) -> Drawn<'a, u16> {
|
||||
Tui::Layout(XYWH(1u16, 1, 80, 25)).size(None, t)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -185,8 +185,9 @@ pub struct Pair<A, B>(Split, A, B);
|
|||
|
||||
/// ```
|
||||
/// # fn test_split_stack () -> Usually<()> {
|
||||
/// use ::tengri::*;
|
||||
/// use Split::*;
|
||||
/// fn size_of <A: Draw<Tui>, B: Draw<Tui>> (stack: &Pair<Tui, A, B>) -> Drawn<'a, S::Unit> {
|
||||
/// fn size_of <'a, A: Draw<'a, Tui>, B: Draw<'a, Tui>> (stack: &Pair<Tui, A, B>) -> Drawn<'a, S::Unit> {
|
||||
/// Tui::Layout(XYWH(0, 0, 80, 25)).size(None, stack)
|
||||
/// }
|
||||
/// assert_eq!(size_of(&split(East, "foo", "bar"))?, Some(XYWH(0, 0, 6, 1)));
|
||||
|
|
@ -238,7 +239,7 @@ fn draw_stacks <'a, S: Screen> (
|
|||
}
|
||||
|
||||
/// ```
|
||||
/// # fn test_stack_areas () -> Usually<()> {
|
||||
/// # use ::tengri::*; fn test_stack_areas () -> Usually<()> {
|
||||
/// let area = XYWH(0u16, 0, 80, 25);
|
||||
/// assert_eq!(stack_areas(&Split::East, &mut Tui::Layout(area), &"foo", &"bar")?, (
|
||||
/// Some(XYWH(0u16, 0, 3, 1)),
|
||||
|
|
|
|||
|
|
@ -3,15 +3,14 @@ use crate::*;
|
|||
fn_kw_layout!(kw_when |state, output, expr| {
|
||||
let thunk = draw(move|screen|ok_flat(expr.nth(2)?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
ok_flat(matches!(expr.head()?, Some("when")).then(||{
|
||||
when(state.namespace(expr.nth(1)?)?.unwrap(), thunk) .draw(output)
|
||||
when(state.namespace(&expr.nth(1)?)?.unwrap(), thunk) .draw(output)
|
||||
}))
|
||||
});
|
||||
|
||||
/// Only render when condition is true.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::*;
|
||||
/// # fn test () -> impl Draw<Tui> {
|
||||
/// # use ::tengri::*; fn test <'a> () -> impl Draw<'a, Tui> {
|
||||
/// when(true, "Yes")
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
@ -23,15 +22,14 @@ fn_kw_layout!(kw_either |state, output, expr| {
|
|||
let thunk_a = draw(move|screen|ok_flat(expr.nth(2)?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
let thunk_b = draw(move|screen|ok_flat(expr.nth(3)?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
ok_flat(matches!(expr.head()?, Some("either")).then(||{
|
||||
either(state.namespace(expr.nth(1)?)?.unwrap(), thunk_a, thunk_b).draw(output)
|
||||
either(state.namespace(&expr.nth(1)?)?.unwrap(), thunk_a, thunk_b).draw(output)
|
||||
}))
|
||||
});
|
||||
|
||||
/// Render one thing if a condition is true and another false.
|
||||
///
|
||||
/// ```
|
||||
/// # use tengri::*;
|
||||
/// # fn test () -> impl Draw<Tui> {
|
||||
/// # use ::tengri::*; fn test <'a> () -> impl Draw<'a, Tui> {
|
||||
/// either(true, "Yes", "No")
|
||||
/// # }
|
||||
/// ```
|
||||
|
|
|
|||
16
src/lib.rs
16
src/lib.rs
|
|
@ -1797,19 +1797,19 @@ pub trait AsMutOpt<T> { fn as_mut_opt (&mut self) -> Option<&mut T>; }
|
|||
-> UsuallyRef<'a, Self>;
|
||||
}
|
||||
|
||||
impl<'a, T: Language<'a> + 'a> ColorDsl<'a, T> for Color {
|
||||
impl<'a, T: Language + 'a> ColorDsl<'a, T> for Color {
|
||||
fn new_g (expr: &'a T, try_to_u8: impl Fn(PerhapsRef<'a, &'a str>)->PerhapsRef<'a, u8>)
|
||||
-> Result<Self, Box<dyn Error + 'a>>
|
||||
{
|
||||
let n = try_to_u8(expr.tail().map_err(Into::into))?.ok_or(Domain("not gray"))?;
|
||||
let n = try_to_u8(expr.tail().map_err(Into::into))?.ok_or(LanguageError::domain("not gray"))?;
|
||||
Ok(Self::Rgb(n, n, n))
|
||||
}
|
||||
fn new_rgb (expr: &'a T, try_to_u8: impl Fn(PerhapsRef<'a, &str>)->PerhapsRef<'a, u8>)
|
||||
-> Result<Self, Box<dyn Error + 'a>>
|
||||
{
|
||||
let r = try_to_u8(expr.nth(1).map_err(Into::into))?.ok_or(Domain("not red"))?;
|
||||
let g = try_to_u8(expr.nth(2).map_err(Into::into))?.ok_or(Domain("not green"))?;
|
||||
let b = try_to_u8(expr.nth(3).map_err(Into::into))?.ok_or(Domain("not blue"))?;
|
||||
let r = try_to_u8(expr.nth(1).map_err(Into::into))?.ok_or(LanguageError::domain("not red"))?;
|
||||
let g = try_to_u8(expr.nth(2).map_err(Into::into))?.ok_or(LanguageError::domain("not green"))?;
|
||||
let b = try_to_u8(expr.nth(3).map_err(Into::into))?.ok_or(LanguageError::domain("not blue"))?;
|
||||
Ok(Color::Rgb(r, g, b))
|
||||
}
|
||||
}
|
||||
|
|
@ -1935,8 +1935,8 @@ pub trait AsMutOpt<T> { fn as_mut_opt (&mut self) -> Option<&mut T>; }
|
|||
/// # Ok(()) }
|
||||
/// ```
|
||||
pub trait Keywords <U, V>: 'static {
|
||||
fn keywords () -> impl Iterator<Item = fn(&Self, &mut U, &str) -> Perhaps<V>>;
|
||||
fn keyword <'a> (&self, to: &mut U, expr: &'a impl Language<'a>) -> PerhapsRef<'a, V> {
|
||||
fn keywords <'a> () -> impl Iterator<Item = fn(&Self, &mut U, &str) -> PerhapsRef<'a, V>>;
|
||||
fn keyword <'a> (&self, to: &mut U, expr: &'a (impl Language + ?Sized)) -> PerhapsRef<'a, V> {
|
||||
if let Some(expr) = expr.src()? {
|
||||
for keyword in Self::keywords() {
|
||||
if let Some(result) = keyword(self, to, &expr)? {
|
||||
|
|
@ -1951,7 +1951,7 @@ pub trait AsMutOpt<T> { fn as_mut_opt (&mut self) -> Option<&mut T>; }
|
|||
#[macro_export] macro_rules! impl_keywords {
|
||||
($T:ty, $U:ty, $V:ty [ $($kw:ident),* ]) => {
|
||||
impl Keywords<$T, $U> for $V {
|
||||
fn keywords () -> impl Iterator<Item = fn(&Self, &mut $T, &str) -> Perhaps<$U>> {
|
||||
fn keywords <'a> () -> impl Iterator<Item = fn(&Self, &mut $T, &str) -> PerhapsRef<'a, $U>> {
|
||||
[ $($kw),* ].into_iter()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl TuiKey {
|
|||
}
|
||||
|
||||
#[cfg(feature = "lang")]
|
||||
pub fn from_dsl <'a> (dsl: &'a impl Language<'a>) -> UsuallyRef<'a, Self> {
|
||||
pub fn from_dsl <'a> (dsl: &'a impl Language) -> UsuallyRef<'a, Self> {
|
||||
if let Some(word) = dsl.word()? {
|
||||
let word = word.trim();
|
||||
Ok(if word == ":char" {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use Color::*;
|
|||
fn_kw_layout_tui!(kw_tui_fg |state, output, expr| {
|
||||
let thunk = draw(move|screen|ok_flat(expr.nth(2)?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(matches!(expr.head()?, Some("fg")).then(||{
|
||||
if let Some(color) = state.namespace(expr.nth(1)?.expect("fg: expected arg 0 (color)"))? {
|
||||
if let Some(color) = state.namespace(&expr.nth(1)?.expect("fg: expected arg 0 (color)"))? {
|
||||
fg(color, thunk).draw(output)
|
||||
} else {
|
||||
return Err(format!("fg: {:?}: not a color", expr.nth(1)).into())
|
||||
|
|
@ -15,7 +15,7 @@ fn_kw_layout_tui!(kw_tui_fg |state, output, expr| {
|
|||
fn_kw_layout_tui!(kw_tui_bg |state, output, expr| {
|
||||
let thunk = draw(move|screen|ok_flat(expr.nth(2)?.map(|x: &'a str|state.interpret(screen, x))));
|
||||
Ok(matches!(expr.head()?, Some("bg")).then(||{
|
||||
if let Some(color) = state.namespace(expr.nth(1)?.expect("bg: expected arg 0 (color)"))? {
|
||||
if let Some(color) = state.namespace(&expr.nth(1)?.expect("bg: expected arg 0 (color)"))? {
|
||||
bg(color, thunk).draw(output)
|
||||
} else {
|
||||
return Err(format!("bg: {:?}: not a color", expr.nth(1)?).into())
|
||||
|
|
@ -24,23 +24,21 @@ fn_kw_layout_tui!(kw_tui_bg |state, output, expr| {
|
|||
});
|
||||
|
||||
impl Tui {
|
||||
pub fn eval_color_expr <'a> (state: &impl Namespace<u8>, src: &'a impl Language<'a>)
|
||||
-> Result<Option<Color>, Box<dyn Error + 'a>>
|
||||
{
|
||||
|
||||
pub fn eval_color_expr <'a> (
|
||||
state: &'a impl Namespace<u8>,
|
||||
src: &'a impl Language
|
||||
) -> Result<Option<Color>, Box<dyn Error>> {
|
||||
if let Some(expr) = src.expr()? {
|
||||
match (expr.head()?, expr.tail()?) {
|
||||
(Some("g"), Some(tail)) => {
|
||||
let n: u8 = state.namespace(tail.head().map_err(Into::into))?
|
||||
.ok_or(LanguageError::Domain("not gray"))?;
|
||||
let n: u8 = state.namespace(&tail.head()?)?.ok_or(LanguageError::domain("not gray"))?;
|
||||
Ok(Some(Color::Rgb(n, n, n)))
|
||||
},
|
||||
(Some("rgb"), Some(tail)) => {
|
||||
let r: u8 = state.namespace(tail.head().map_err(Into::into))?
|
||||
.ok_or(LanguageError::Domain("not red"))?;
|
||||
let g: u8 = state.namespace(tail.tail().head().map_err(Into::into))?
|
||||
.ok_or(LanguageError::Domain("not green"))?;
|
||||
let b: u8 = state.namespace(tail.tail().tail().head().map_err(Into::into))?
|
||||
.ok_or(LanguageError::Domain("not blue"))?;
|
||||
let r: u8 = state.namespace(&tail.nth(0)?)?.ok_or(LanguageError::domain("not red"))?;
|
||||
let g: u8 = state.namespace(&tail.nth(1)?)?.ok_or(LanguageError::domain("not green"))?;
|
||||
let b: u8 = state.namespace(&tail.nth(2)?)?.ok_or(LanguageError::domain("not blue"))?;
|
||||
Ok(Some(Color::Rgb(r, g, b)))
|
||||
},
|
||||
(Some(_), _) => return Err(
|
||||
|
|
@ -54,6 +52,7 @@ impl Tui {
|
|||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Apply foreground color.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue