summaryrefslogtreecommitdiff
path: root/library/src/basics
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-12-15 22:51:55 +0100
committerLaurenz <laurmaedje@gmail.com>2022-12-15 23:11:20 +0100
commitb6202b646a0d5ecced301d9bac8bfcaf977d7ee4 (patch)
tree7d42cb50f9e66153e7e8b2217009684e25f54f42 /library/src/basics
parentf3980c704544a464f9729cc8bc9f97d3a7454769 (diff)
Reflection for castables
Diffstat (limited to 'library/src/basics')
-rw-r--r--library/src/basics/heading.rs2
-rw-r--r--library/src/basics/list.rs36
-rw-r--r--library/src/basics/table.rs11
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")
+ }
}