diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-12-15 22:51:55 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-12-15 23:11:20 +0100 |
| commit | b6202b646a0d5ecced301d9bac8bfcaf977d7ee4 (patch) | |
| tree | 7d42cb50f9e66153e7e8b2217009684e25f54f42 /library/src/basics | |
| parent | f3980c704544a464f9729cc8bc9f97d3a7454769 (diff) | |
Reflection for castables
Diffstat (limited to 'library/src/basics')
| -rw-r--r-- | library/src/basics/heading.rs | 2 | ||||
| -rw-r--r-- | library/src/basics/list.rs | 36 | ||||
| -rw-r--r-- | library/src/basics/table.rs | 11 |
3 files changed, 33 insertions, 16 deletions
diff --git a/library/src/basics/heading.rs b/library/src/basics/heading.rs index 80f93e8d..60415697 100644 --- a/library/src/basics/heading.rs +++ b/library/src/basics/heading.rs @@ -6,6 +6,8 @@ use crate::prelude::*; use crate::text::{SpaceNode, TextNode, TextSize}; /// A section heading. +/// +/// Tags: basics. #[func] #[capable(Prepare, Show, Finalize)] #[derive(Debug, Hash)] diff --git a/library/src/basics/list.rs b/library/src/basics/list.rs index 0fa8f125..4c016128 100644 --- a/library/src/basics/list.rs +++ b/library/src/basics/list.rs @@ -4,6 +4,8 @@ use crate::prelude::*; use crate::text::{SpaceNode, TextNode}; /// An unordered (bulleted) or ordered (numbered) list. +/// +/// Tags: basics. #[func] #[capable(Layout)] #[derive(Debug, Hash)] @@ -24,7 +26,7 @@ pub type DescNode = ListNode<DESC>; impl<const L: ListKind> ListNode<L> { /// How the list is labelled. #[property(referenced)] - pub const LABEL: Label = Label::Default; + pub const LABEL: ListLabel = ListLabel::Default; /// The indentation of each item's label. #[property(resolve)] pub const INDENT: Length = Length::zero(); @@ -199,10 +201,10 @@ pub struct DescItem { castable! { DescItem, - Expected: "dictionary with `term` and `body` keys", - Value::Dict(dict) => { - let term: Content = dict.get("term")?.clone().cast()?; - let body: Content = dict.get("body")?.clone().cast()?; + mut dict: Dict => { + let term: Content = dict.take("term")?.cast()?; + let body: Content = dict.take("body")?.cast()?; + dict.finish(&["term", "body"])?; Self { term, body } }, } @@ -221,7 +223,7 @@ pub const DESC: ListKind = 2; /// How to label a list or enumeration. #[derive(Debug, Clone, Hash)] -pub enum Label { +pub enum ListLabel { /// The default labelling. Default, /// A pattern with prefix, numbering, lower / upper case and suffix. @@ -232,7 +234,7 @@ pub enum Label { Func(Func, Span), } -impl Label { +impl ListLabel { /// Resolve the label based on the level. pub fn resolve( &self, @@ -256,9 +258,12 @@ impl Label { } } -impl Cast<Spanned<Value>> for Label { +impl Cast<Spanned<Value>> for ListLabel { fn is(value: &Spanned<Value>) -> bool { - matches!(&value.v, Value::Content(_) | Value::Func(_)) + matches!( + &value.v, + Value::None | Value::Str(_) | Value::Content(_) | Value::Func(_) + ) } fn cast(value: Spanned<Value>) -> StrResult<Self> { @@ -267,10 +272,15 @@ impl Cast<Spanned<Value>> for Label { Value::Str(v) => Ok(Self::Pattern(v.parse()?)), Value::Content(v) => Ok(Self::Content(v)), Value::Func(v) => Ok(Self::Func(v, value.span)), - v => Err(format_eco!( - "expected string, content or function, found {}", - v.type_name(), - )), + v => Self::error(v), } } + + fn describe() -> CastInfo { + CastInfo::Union(vec![ + CastInfo::Type("string"), + CastInfo::Type("content"), + CastInfo::Type("function"), + ]) + } } diff --git a/library/src/basics/table.rs b/library/src/basics/table.rs index 5a4e8e81..10a9143f 100644 --- a/library/src/basics/table.rs +++ b/library/src/basics/table.rs @@ -2,6 +2,8 @@ use crate::layout::{GridNode, TrackSizing, TrackSizings}; use crate::prelude::*; /// A table of items. +/// +/// Tags: basics. #[func] #[capable(Layout)] #[derive(Debug, Hash)] @@ -125,9 +127,12 @@ impl<T: Cast> Cast<Spanned<Value>> for Celled<T> { fn cast(value: Spanned<Value>) -> StrResult<Self> { match value.v { Value::Func(v) => Ok(Self::Func(v, value.span)), - v => T::cast(v) - .map(Self::Value) - .map_err(|msg| with_alternative(msg, "function")), + v if T::is(&v) => Ok(Self::Value(T::cast(v)?)), + v => Self::error(v), } } + + fn describe() -> CastInfo { + T::describe() + CastInfo::Type("function") + } } |
