Generic casting for Axes<T>

This commit is contained in:
Laurenz 2025-06-19 17:20:17 +02:00
parent 3b35f0cecf
commit d821633f50
4 changed files with 38 additions and 33 deletions

View File

@ -4,9 +4,12 @@ use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Deref, Not};
use typst_utils::Get; use typst_utils::Get;
use crate::diag::bail; use crate::diag::{bail, HintedStrResult};
use crate::foundations::{array, cast, Array, Resolve, Smart, StyleChain}; use crate::foundations::{
use crate::layout::{Abs, Dir, Length, Ratio, Rel, Size}; array, cast, Array, CastInfo, FromValue, IntoValue, Reflect, Resolve, Smart,
StyleChain, Value,
};
use crate::layout::{Abs, Dir, Rel, Size};
/// A container with a horizontal and vertical component. /// A container with a horizontal and vertical component.
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
@ -275,40 +278,39 @@ impl BitAndAssign for Axes<bool> {
} }
} }
cast! { impl<T: Reflect> Reflect for Axes<T> {
Axes<Rel<Length>>, fn input() -> CastInfo {
self => array![self.x, self.y].into_value(), Array::input()
array: Array => { }
let mut iter = array.into_iter();
match (iter.next(), iter.next(), iter.next()) { fn output() -> CastInfo {
(Some(a), Some(b), None) => Axes::new(a.cast()?, b.cast()?), Array::output()
_ => bail!("point array must contain exactly two entries"), }
fn castable(value: &Value) -> bool {
Array::castable(value)
} }
},
} }
cast! { impl<T: FromValue> FromValue for Axes<T> {
Axes<Ratio>, fn from_value(value: Value) -> HintedStrResult<Self> {
self => array![self.x, self.y].into_value(), let array = value.cast::<Array>()?;
array: Array => {
let mut iter = array.into_iter(); let mut iter = array.into_iter();
match (iter.next(), iter.next(), iter.next()) { match (iter.next(), iter.next(), iter.next()) {
(Some(a), Some(b), None) => Axes::new(a.cast()?, b.cast()?), (Some(a), Some(b), None) => Ok(Axes::new(a.cast()?, b.cast()?)),
_ => bail!("ratio array must contain exactly two entries"), _ => bail!(
"array must contain exactly two items";
hint: "the first item determines the value for the X axis \
and the second item the value for the Y axis"
),
}
} }
},
} }
cast! { impl<T: IntoValue> IntoValue for Axes<T> {
Axes<Length>, fn into_value(self) -> Value {
self => array![self.x, self.y].into_value(), array![self.x.into_value(), self.y.into_value()].into_value()
array: Array => {
let mut iter = array.into_iter();
match (iter.next(), iter.next(), iter.next()) {
(Some(a), Some(b), None) => Axes::new(a.cast()?, b.cast()?),
_ => bail!("length array must contain exactly two entries"),
} }
},
} }
impl<T: Resolve> Resolve for Axes<T> { impl<T: Resolve> Resolve for Axes<T> {

View File

@ -84,7 +84,8 @@
--- line-bad-point-array --- --- line-bad-point-array ---
// Test errors. // Test errors.
// Error: 12-19 point array must contain exactly two entries // Error: 12-19 array must contain exactly two items
// Hint: 12-19 the first item determines the value for the X axis and the second item the value for the Y axis
#line(end: (50pt,)) #line(end: (50pt,))
--- line-bad-point-component-type --- --- line-bad-point-component-type ---

View File

@ -76,7 +76,8 @@
#path(((0%, 0%), (0%, 0%), (0%, 0%), (0%, 0%))) #path(((0%, 0%), (0%, 0%), (0%, 0%), (0%, 0%)))
--- path-bad-point-array --- --- path-bad-point-array ---
// Error: 7-31 point array must contain exactly two entries // Error: 7-31 array must contain exactly two items
// Hint: 7-31 the first item determines the value for the X axis and the second item the value for the Y axis
// Warning: 2-6 the `path` function is deprecated, use `curve` instead // Warning: 2-6 the `path` function is deprecated, use `curve` instead
#path(((0%, 0%), (0%, 0%, 0%))) #path(((0%, 0%), (0%, 0%, 0%)))

View File

@ -49,7 +49,8 @@
) )
--- polygon-bad-point-array --- --- polygon-bad-point-array ---
// Error: 10-17 point array must contain exactly two entries // Error: 10-17 array must contain exactly two items
// Hint: 10-17 the first item determines the value for the X axis and the second item the value for the Y axis
#polygon((50pt,)) #polygon((50pt,))
--- polygon-infinite-size --- --- polygon-infinite-size ---