From abc87d3234a382b74228ce01ab250df875f8467d Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 21 May 2025 14:17:27 +0300 Subject: [PATCH] dsl, output: error handlers --- dsl/src/dsl_provide.rs | 12 +-- output/src/lib.rs | 174 +----------------------------------- output/src/ops/align.rs | 2 +- output/src/ops/bsp.rs | 4 +- output/src/ops/either.rs | 6 +- output/src/ops/transform.rs | 20 ++--- output/src/ops/when.rs | 4 +- 7 files changed, 25 insertions(+), 197 deletions(-) diff --git a/dsl/src/dsl_provide.rs b/dsl/src/dsl_provide.rs index 639fddf..c2f411f 100644 --- a/dsl/src/dsl_provide.rs +++ b/dsl/src/dsl_provide.rs @@ -2,13 +2,13 @@ use crate::*; pub trait Dsl { fn take <'source> (&self, words: &mut TokenIter<'source>) -> Perhaps; - fn take_or_fail <'source> ( - &self, words: &mut TokenIter<'source>, error: impl Into> + fn take_or_fail <'source, E: Into>, F: Fn()->E> ( + &self, words: &mut TokenIter<'source>, error: F ) -> Usually { if let Some(value) = Dsl::::take(self, words)? { Ok(value) } else { - Result::Err(format!("{}: {:?}", error.into(), words.peek().map(|x|x.value)).into()) + Result::Err(format!("{}: {:?}", error().into(), words.peek().map(|x|x.value)).into()) } } } @@ -22,13 +22,13 @@ impl, State> Dsl for State { pub trait Namespace: Sized { fn take_from <'source> (state: &State, words: &mut TokenIter<'source>) -> Perhaps; - fn take_from_or_fail <'source> ( - state: &State, words: &mut TokenIter<'source>, error: impl Into> + fn take_from_or_fail <'source, E: Into>, F: Fn()->E> ( + state: &State, words: &mut TokenIter<'source>, error: F ) -> Usually { if let Some(value) = Namespace::::take_from(state, words)? { Ok(value) } else { - Result::Err(format!("{}: {:?}", error.into(), words.peek().map(|x|x.value)).into()) + Result::Err(format!("{}: {:?}", error().into(), words.peek().map(|x|x.value)).into()) } } } diff --git a/output/src/lib.rs b/output/src/lib.rs index 6b2946a..394f332 100644 --- a/output/src/lib.rs +++ b/output/src/lib.rs @@ -7,176 +7,4 @@ pub(crate) use std::marker::PhantomData; mod space; pub use self::space::*; mod ops; pub use self::ops::*; mod output; pub use self::output::*; -#[cfg(test)] mod test { - use crate::*; - use proptest_derive::Arbitrary; - use proptest::{prelude::*, option::of}; - - proptest! { - #[test] fn proptest_direction ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - ) { - let _ = d.split_fixed([x, y, w, h], a); - } - } - - proptest! { - #[test] fn proptest_size ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let size = [x, y]; - let _ = size.w(); - let _ = size.h(); - let _ = size.wh(); - let _ = size.clip_w(a); - let _ = size.clip_h(b); - let _ = size.expect_min(a, b); - let _ = size.to_area_pos(); - let _ = size.to_area_size(); - } - } - - proptest! { - #[test] fn proptest_area ( - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - a in u16::MIN..u16::MAX, - b in u16::MIN..u16::MAX, - ) { - let _: [u16;4] = <[u16;4] as Area>::zero(); - let _: [u16;4] = <[u16;4] as Area>::from_position([a, b]); - let _: [u16;4] = <[u16;4] as Area>::from_size([a, b]); - let area: [u16;4] = [x, y, w, h]; - let _ = area.expect_min(a, b); - let _ = area.xy(); - let _ = area.wh(); - let _ = area.xywh(); - let _ = area.clip_h(a); - let _ = area.clip_w(b); - let _ = area.clip([a, b]); - let _ = area.set_w(a); - let _ = area.set_h(b); - let _ = area.x2(); - let _ = area.y2(); - let _ = area.lrtb(); - let _ = area.center(); - let _ = area.center_x(a); - let _ = area.center_y(b); - let _ = area.center_xy([a, b]); - let _ = area.centered(); - } - } - - macro_rules! test_op_transform { - ($fn:ident, $Op:ident) => { - proptest! { - #[test] fn $fn ( - op_x in of(u16::MIN..u16::MAX), - op_y in of(u16::MIN..u16::MAX), - content in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - if let Some(op) = match (op_x, op_y) { - (Some(x), Some(y)) => Some($Op::xy(x, y, content)), - (Some(x), None) => Some($Op::x(x, content)), - (Some(y), None) => Some($Op::y(y, content)), - _ => None - } { - assert_eq!(Content::layout(&op, [x, y, w, h]), - Render::layout(&op, [x, y, w, h])); - } - } - } - } - } - - test_op_transform!(proptest_op_fixed, Fixed); - test_op_transform!(proptest_op_min, Min); - test_op_transform!(proptest_op_max, Max); - test_op_transform!(proptest_op_push, Push); - test_op_transform!(proptest_op_pull, Pull); - test_op_transform!(proptest_op_shrink, Shrink); - test_op_transform!(proptest_op_expand, Expand); - test_op_transform!(proptest_op_margin, Margin); - test_op_transform!(proptest_op_padding, Padding); - - proptest! { - #[test] fn proptest_op_bsp ( - d in prop_oneof![ - Just(North), Just(South), - Just(East), Just(West), - Just(Above), Just(Below) - ], - a in "\\PC*", - b in "\\PC*", - x in u16::MIN..u16::MAX, - y in u16::MIN..u16::MAX, - w in u16::MIN..u16::MAX, - h in u16::MIN..u16::MAX, - ) { - let bsp = Bsp(d, a, b); - assert_eq!( - Content::layout(&bsp, [x, y, w, h]), - Render::layout(&bsp, [x, y, w, h]), - ); - } - } - - #[test] fn test_stub_output () -> Usually<()> { - use crate::*; - struct TestOutput([u16;4]); - impl Output for TestOutput { - type Unit = u16; - type Size = [u16;2]; - type Area = [u16;4]; - fn area (&self) -> [u16;4] { - self.0 - } - fn area_mut (&mut self) -> &mut [u16;4] { - &mut self.0 - } - fn place (&mut self, _: [u16;4], _: &impl Render) { - () - } - } - impl Content for String { - fn render (&self, to: &mut TestOutput) { - to.area_mut().set_w(self.len() as u16); - } - } - Ok(()) - } - - #[test] fn test_space () { - use crate::*; - assert_eq!(Area::center(&[10u16, 10, 20, 20]), [20, 20]); - } - - #[test] fn test_iter_map () { - struct Foo; - impl Content for Foo {} - fn make_map + Send + Sync> (data: &Vec) -> impl Content { - Map::new(||data.iter(), |foo, index|{}) - } - let data = vec![Foo, Foo, Foo]; - //let map = make_map(&data); - } - -} +#[cfg(test)] mod test; diff --git a/output/src/ops/align.rs b/output/src/ops/align.rs index 5702a40..0809a10 100644 --- a/output/src/ops/align.rs +++ b/output/src/ops/align.rs @@ -42,7 +42,7 @@ from_dsl!(@a: Align: |state, iter|if let Some(Token { value: Value::Key(key), "align/n"|"align/s"|"align/e"|"align/w"| "align/nw"|"align/sw"|"align/ne"|"align/se" => { let _ = iter.next().unwrap(); - let content = state.take_or_fail(&mut iter.clone(), "expected content")?; + let content = state.take_or_fail(&mut iter.clone(), ||"expected content")?; return Ok(Some(match key { "align/c" => Self::c(content), "align/x" => Self::x(content), diff --git a/output/src/ops/bsp.rs b/output/src/ops/bsp.rs index 8e1d8e9..41fd5e6 100644 --- a/output/src/ops/bsp.rs +++ b/output/src/ops/bsp.rs @@ -28,8 +28,8 @@ impl + Dsl + std::fmt::Debug, A, B> Namespace for Bsp Self::n(a, b), Some(Token { value: Value::Key("bsp/s"), .. }) => Self::s(a, b), diff --git a/output/src/ops/either.rs b/output/src/ops/either.rs index 75c6ccf..b8e6ef9 100644 --- a/output/src/ops/either.rs +++ b/output/src/ops/either.rs @@ -18,9 +18,9 @@ impl + Dsl + Dsl> Namespace for Either { let base = token.clone(); let _ = token.next().unwrap(); return Ok(Some(Self( - state.take_or_fail(token, "either: no condition")?, - state.take_or_fail(token, "either: no content 1")?, - state.take_or_fail(token, "either: no content 2")?, + state.take_or_fail(token, ||"either: no condition")?, + state.take_or_fail(token, ||"either: no content 1")?, + state.take_or_fail(token, ||"either: no content 2")?, ))) } Ok(None) diff --git a/output/src/ops/transform.rs b/output/src/ops/transform.rs index 776d95c..9719c9a 100644 --- a/output/src/ops/transform.rs +++ b/output/src/ops/transform.rs @@ -41,11 +41,11 @@ macro_rules! transform_xy { let mut base = token.clone(); return Ok(Some(match token.next() { Some(Token{value:Value::Key($x),..}) => - Self::x(state.take_or_fail(token, "x: no content")?), + Self::x(state.take_or_fail(token, ||"x: no content")?), Some(Token{value:Value::Key($y),..}) => - Self::y(state.take_or_fail(token, "y: no content")?), + Self::y(state.take_or_fail(token, ||"y: no content")?), Some(Token{value:Value::Key($xy),..}) => - Self::xy(state.take_or_fail(token, "xy: no content")?), + Self::xy(state.take_or_fail(token, ||"xy: no content")?), _ => unreachable!() })) } @@ -87,17 +87,17 @@ macro_rules! transform_xy_unit { let mut base = token.clone(); Some(match token.next() { Some(Token { value: Value::Key($x), .. }) => Self::x( - state.take_or_fail(token, "x: no unit")?, - state.take_or_fail(token, "x: no content")?, + state.take_or_fail(token, ||"x: no unit")?, + state.take_or_fail(token, ||"x: no content")?, ), Some(Token { value: Value::Key($y), .. }) => Self::y( - state.take_or_fail(token, "y: no unit")?, - state.take_or_fail(token, "y: no content")?, + state.take_or_fail(token, ||"y: no unit")?, + state.take_or_fail(token, ||"y: no content")?, ), Some(Token { value: Value::Key($x), .. }) => Self::xy( - state.take_or_fail(token, "xy: no unit x")?, - state.take_or_fail(token, "xy: no unit y")?, - state.take_or_fail(token, "xy: no content")? + state.take_or_fail(token, ||"xy: no unit x")?, + state.take_or_fail(token, ||"xy: no unit y")?, + state.take_or_fail(token, ||"xy: no content")? ), _ => unreachable!(), }) diff --git a/output/src/ops/when.rs b/output/src/ops/when.rs index 188a5b5..35f1910 100644 --- a/output/src/ops/when.rs +++ b/output/src/ops/when.rs @@ -20,8 +20,8 @@ impl + Dsl> Namespace for When { }) = token.peek() { let base = token.clone(); return Ok(Some(Self( - state.take_or_fail(token, "cond: no condition")?, - state.take_or_fail(token, "cond: no content")?, + state.take_or_fail(token, ||"cond: no condition")?, + state.take_or_fail(token, ||"cond: no content")?, ))) } else { None