summaryrefslogtreecommitdiff
path: root/library/src/meta
diff options
context:
space:
mode:
Diffstat (limited to 'library/src/meta')
-rw-r--r--library/src/meta/bibliography.rs9
-rw-r--r--library/src/meta/context.rs28
-rw-r--r--library/src/meta/counter.rs48
-rw-r--r--library/src/meta/document.rs7
-rw-r--r--library/src/meta/figure.rs19
-rw-r--r--library/src/meta/footnote.rs2
-rw-r--r--library/src/meta/heading.rs6
-rw-r--r--library/src/meta/link.rs13
-rw-r--r--library/src/meta/mod.rs16
-rw-r--r--library/src/meta/numbering.rs56
-rw-r--r--library/src/meta/outline.rs30
-rw-r--r--library/src/meta/query.rs19
-rw-r--r--library/src/meta/reference.rs19
-rw-r--r--library/src/meta/state.rs22
14 files changed, 119 insertions, 175 deletions
diff --git a/library/src/meta/bibliography.rs b/library/src/meta/bibliography.rs
index a2491bb5..5e5145b1 100644
--- a/library/src/meta/bibliography.rs
+++ b/library/src/meta/bibliography.rs
@@ -84,16 +84,13 @@ pub struct BibliographyElem {
#[derive(Debug, Default, Clone, Hash)]
pub struct BibPaths(Vec<EcoString>);
-cast_from_value! {
+cast! {
BibPaths,
+ self => self.0.into_value(),
v: EcoString => Self(vec![v]),
v: Array => Self(v.into_iter().map(Value::cast).collect::<StrResult<_>>()?),
}
-cast_to_value! {
- v: BibPaths => v.0.into()
-}
-
impl BibliographyElem {
/// Find the document's bibliography.
pub fn find(introspector: Tracked<Introspector>) -> StrResult<Self> {
@@ -374,7 +371,7 @@ impl Show for CiteElem {
}
}
-cast_from_value! {
+cast! {
CiteElem,
v: Content => v.to::<Self>().cloned().ok_or("expected citation")?,
}
diff --git a/library/src/meta/context.rs b/library/src/meta/context.rs
index ad466305..d599c63e 100644
--- a/library/src/meta/context.rs
+++ b/library/src/meta/context.rs
@@ -46,7 +46,6 @@ use crate::prelude::*;
///
/// Display: Locate
/// Category: meta
-/// Returns: content
#[func]
pub fn locate(
/// A function that receives a `location`. Its return value is displayed
@@ -56,8 +55,8 @@ pub fn locate(
/// `locate` appears in the document. That makes it possible to generate
/// content that depends on its own location in the document.
func: Func,
-) -> Value {
- LocateElem::new(func).pack().into()
+) -> Content {
+ LocateElem::new(func).pack()
}
/// Executes a `locate` call.
@@ -79,7 +78,7 @@ impl Show for LocateElem {
}
let location = self.0.location().unwrap();
- Ok(self.func().call_vt(vt, [location.into()])?.display())
+ Ok(self.func().call_vt(vt, [location])?.display())
}
}
@@ -102,7 +101,6 @@ impl Show for LocateElem {
///
/// Display: Style
/// Category: meta
-/// Returns: content
#[func]
pub fn style(
/// A function to call with the styles. Its return value is displayed
@@ -112,8 +110,8 @@ pub fn style(
/// `style` appears in the document. That makes it possible to generate
/// content that depends on the style context it appears in.
func: Func,
-) -> Value {
- StyleElem::new(func).pack().into()
+) -> Content {
+ StyleElem::new(func).pack()
}
/// Executes a style access.
@@ -130,7 +128,7 @@ struct StyleElem {
impl Show for StyleElem {
#[tracing::instrument(name = "StyleElem::show", skip_all)]
fn show(&self, vt: &mut Vt, styles: StyleChain) -> SourceResult<Content> {
- Ok(self.func().call_vt(vt, [styles.to_map().into()])?.display())
+ Ok(self.func().call_vt(vt, [styles.to_map()])?.display())
}
}
@@ -177,7 +175,6 @@ impl Show for StyleElem {
///
/// Display: Layout
/// Category: meta
-/// Returns: content
#[func]
pub fn layout(
/// A function to call with the outer container's size. Its return value is
@@ -190,8 +187,8 @@ pub fn layout(
/// `layout` appears in the document. That makes it possible to generate
/// content that depends on the size of the container it is inside of.
func: Func,
-) -> Value {
- LayoutElem::new(func).pack().into()
+) -> Content {
+ LayoutElem::new(func).pack()
}
/// Executes a `layout` call.
@@ -213,16 +210,13 @@ impl Layout for LayoutElem {
styles: StyleChain,
regions: Regions,
) -> SourceResult<Fragment> {
- // Gets the current region's base size, which will be the size of the outer container,
- // or of the page if there is no such container.
+ // Gets the current region's base size, which will be the size of the
+ // outer container, or of the page if there is no such container.
let Size { x, y } = regions.base();
- let size_dict = dict! { "width" => x, "height" => y }.into();
-
let result = self
.func()
- .call_vt(vt, [size_dict])? // calls func(size)
+ .call_vt(vt, [dict! { "width" => x, "height" => y }])?
.display();
-
result.layout(vt, styles, regions)
}
}
diff --git a/library/src/meta/counter.rs b/library/src/meta/counter.rs
index 46992d38..ef4646ab 100644
--- a/library/src/meta/counter.rs
+++ b/library/src/meta/counter.rs
@@ -277,7 +277,6 @@ use crate::prelude::*;
///
/// Display: Counter
/// Category: meta
-/// Returns: counter
#[func]
pub fn counter(
/// The key that identifies this counter.
@@ -288,8 +287,8 @@ pub fn counter(
/// - If this is an element function or selector, counts through its elements,
/// - If this is the [`page`]($func/page) function, counts through pages.
key: CounterKey,
-) -> Value {
- Value::dynamic(Counter::new(key))
+) -> Counter {
+ Counter::new(key)
}
/// Counts through pages, elements, and more.
@@ -317,17 +316,17 @@ impl Counter {
span: Span,
) -> SourceResult<Value> {
let value = match method {
- "display" => {
- self.display(args.eat()?, args.named("both")?.unwrap_or(false)).into()
- }
+ "display" => self
+ .display(args.eat()?, args.named("both")?.unwrap_or(false))
+ .into_value(),
"step" => self
.update(CounterUpdate::Step(
args.named("level")?.unwrap_or(NonZeroUsize::ONE),
))
- .into(),
- "update" => self.update(args.expect("value or function")?).into(),
- "at" => self.at(&mut vm.vt, args.expect("location")?)?.into(),
- "final" => self.final_(&mut vm.vt, args.expect("location")?)?.into(),
+ .into_value(),
+ "update" => self.update(args.expect("value or function")?).into_value(),
+ "at" => self.at(&mut vm.vt, args.expect("location")?)?.into_value(),
+ "final" => self.final_(&mut vm.vt, args.expect("location")?)?.into_value(),
_ => bail!(span, "type counter has no method `{}`", method),
};
args.finish()?;
@@ -342,10 +341,7 @@ impl Counter {
/// Get the value of the state at the given location.
pub fn at(&self, vt: &mut Vt, location: Location) -> SourceResult<CounterState> {
let sequence = self.sequence(vt)?;
- let offset = vt
- .introspector
- .query(&Selector::before(self.selector(), location, true))
- .len();
+ let offset = vt.introspector.query(&self.selector().before(location, true)).len();
let (mut state, page) = sequence[offset].clone();
if self.is_page() {
let delta = vt.introspector.page(location).get().saturating_sub(page.get());
@@ -479,8 +475,8 @@ impl Debug for Counter {
}
}
-cast_from_value! {
- Counter: "counter",
+cast! {
+ type Counter: "counter",
}
/// Identifies a counter.
@@ -495,7 +491,7 @@ pub enum CounterKey {
Str(Str),
}
-cast_from_value! {
+cast! {
CounterKey,
v: Str => Self::Str(v),
label: Label => Self::Selector(Selector::Label(label)),
@@ -503,7 +499,7 @@ cast_from_value! {
if v == PageElem::func() {
Self::Page
} else {
- Self::Selector(LocatableSelector::cast(Value::from(v))?.0)
+ Self::Selector(LocatableSelector::from_value(v.into_value())?.0)
}
},
selector: LocatableSelector => Self::Selector(selector.0),
@@ -536,8 +532,8 @@ impl Debug for CounterUpdate {
}
}
-cast_from_value! {
- CounterUpdate: "counter update",
+cast! {
+ type CounterUpdate: "counter update",
v: CounterState => Self::Set(v),
v: Func => Self::Func(v),
}
@@ -559,10 +555,7 @@ impl CounterState {
CounterUpdate::Set(state) => *self = state,
CounterUpdate::Step(level) => self.step(level, 1),
CounterUpdate::Func(func) => {
- *self = func
- .call_vt(vt, self.0.iter().copied().map(Into::into))?
- .cast()
- .at(func.span())?
+ *self = func.call_vt(vt, self.0.iter().copied())?.cast().at(func.span())?
}
}
Ok(())
@@ -593,8 +586,9 @@ impl CounterState {
}
}
-cast_from_value! {
+cast! {
CounterState,
+ self => Value::Array(self.0.into_iter().map(IntoValue::into_value).collect()),
num: usize => Self(smallvec![num]),
array: Array => Self(array
.into_iter()
@@ -602,10 +596,6 @@ cast_from_value! {
.collect::<StrResult<_>>()?),
}
-cast_to_value! {
- v: CounterState => Value::Array(v.0.into_iter().map(Into::into).collect())
-}
-
/// Executes a display of a state.
///
/// Display: State
diff --git a/library/src/meta/document.rs b/library/src/meta/document.rs
index 1ce900ed..db036e0a 100644
--- a/library/src/meta/document.rs
+++ b/library/src/meta/document.rs
@@ -78,12 +78,9 @@ impl LayoutRoot for DocumentElem {
#[derive(Debug, Default, Clone, Hash)]
pub struct Author(Vec<EcoString>);
-cast_from_value! {
+cast! {
Author,
+ self => self.0.into_value(),
v: EcoString => Self(vec![v]),
v: Array => Self(v.into_iter().map(Value::cast).collect::<StrResult<_>>()?),
}
-
-cast_to_value! {
- v: Author => v.0.into()
-}
diff --git a/library/src/meta/figure.rs b/library/src/meta/figure.rs
index 67087832..0d218770 100644
--- a/library/src/meta/figure.rs
+++ b/library/src/meta/figure.rs
@@ -209,7 +209,7 @@ impl Synthesize for FigureElem {
};
let target = descendant.unwrap_or_else(|| self.body());
- supplement.resolve(vt, [target.into()])?
+ supplement.resolve(vt, [target])?
}
};
@@ -312,8 +312,8 @@ impl FigureElem {
self.counter(),
self.numbering(StyleChain::default()),
) {
- let numbers =
- counter.at(vt, self.0.location().unwrap())?.display(vt, &numbering)?;
+ let loc = self.0.location().unwrap();
+ let numbers = counter.at(vt, loc)?.display(vt, &numbering)?;
if !supplement.is_empty() {
supplement += TextElem::packed("\u{a0}");
@@ -335,19 +335,16 @@ pub enum FigureKind {
Name(EcoString),
}
-cast_from_value! {
+cast! {
FigureKind,
+ self => match self {
+ Self::Elem(v) => v.into_value(),
+ Self::Name(v) => v.into_value(),
+ },
v: ElemFunc => Self::Elem(v),
v: EcoString => Self::Name(v),
}
-cast_to_value! {
- v: FigureKind => match v {
- FigureKind::Elem(v) => v.into(),
- FigureKind::Name(v) => v.into(),
- }
-}
-
/// An element that can be auto-detected in a figure.
///
/// This trait is used to determine the type of a figure.
diff --git a/library/src/meta/footnote.rs b/library/src/meta/footnote.rs
index 22de91c3..1c95716c 100644
--- a/library/src/meta/footnote.rs
+++ b/library/src/meta/footnote.rs
@@ -211,7 +211,7 @@ impl Finalize for FootnoteEntry {
}
}
-cast_from_value! {
+cast! {
FootnoteElem,
v: Content => v.to::<Self>().cloned().unwrap_or_else(|| Self::new(v.clone())),
}
diff --git a/library/src/meta/heading.rs b/library/src/meta/heading.rs
index d6ad7044..7a333e36 100644
--- a/library/src/meta/heading.rs
+++ b/library/src/meta/heading.rs
@@ -104,9 +104,7 @@ impl Synthesize for HeadingElem {
let supplement = match self.supplement(styles) {
Smart::Auto => TextElem::packed(self.local_name_in(styles)),
Smart::Custom(None) => Content::empty(),
- Smart::Custom(Some(supplement)) => {
- supplement.resolve(vt, [self.clone().into()])?
- }
+ Smart::Custom(Some(supplement)) => supplement.resolve(vt, [self.clone()])?,
};
self.push_level(self.level(styles));
@@ -164,7 +162,7 @@ impl Count for HeadingElem {
}
}
-cast_from_value! {
+cast! {
HeadingElem,
v: Content => v.to::<Self>().ok_or("expected heading")?.clone(),
}
diff --git a/library/src/meta/link.rs b/library/src/meta/link.rs
index 93b9999d..43f6a34d 100644
--- a/library/src/meta/link.rs
+++ b/library/src/meta/link.rs
@@ -125,19 +125,16 @@ pub enum LinkTarget {
Label(Label),
}
-cast_from_value! {
+cast! {
LinkTarget,
+ self => match self {
+ Self::Dest(v) => v.into_value(),
+ Self::Label(v) => v.into_value(),
+ },
v: Destination => Self::Dest(v),
v: Label => Self::Label(v),
}
-cast_to_value! {
- v: LinkTarget => match v {
- LinkTarget::Dest(v) => v.into(),
- LinkTarget::Label(v) => v.into(),
- }
-}
-
impl From<Destination> for LinkTarget {
fn from(dest: Destination) -> Self {
Self::Dest(dest)
diff --git a/library/src/meta/mod.rs b/library/src/meta/mod.rs
index 724e5d20..dcac6379 100644
--- a/library/src/meta/mod.rs
+++ b/library/src/meta/mod.rs
@@ -42,14 +42,14 @@ pub(super) fn define(global: &mut Scope) {
global.define("footnote", FootnoteElem::func());
global.define("cite", CiteElem::func());
global.define("bibliography", BibliographyElem::func());
- global.define("locate", locate);
- global.define("style", style);
- global.define("layout", layout);
- global.define("counter", counter);
- global.define("numbering", numbering);
- global.define("state", state);
- global.define("query", query);
- global.define("selector", selector);
+ global.define("locate", locate_func());
+ global.define("style", style_func());
+ global.define("layout", layout_func());
+ global.define("counter", counter_func());
+ global.define("numbering", numbering_func());
+ global.define("state", state_func());
+ global.define("query", query_func());
+ global.define("selector", selector_func());
}
/// The named with which an element is referenced.
diff --git a/library/src/meta/numbering.rs b/library/src/meta/numbering.rs
index fbe7306c..ef0d0f70 100644
--- a/library/src/meta/numbering.rs
+++ b/library/src/meta/numbering.rs
@@ -32,14 +32,13 @@ use crate::text::Case;
///
/// Display: Numbering
/// Category: meta
-/// Returns: any
#[func]
pub fn numbering(
/// Defines how the numbering works.
///
- /// **Counting symbols** are `1`, `a`, `A`, `i`, `I`, `い`, `イ`,
- /// `א`, `가`, `ㄱ`, and `*`. They are replaced by the number in the sequence,
- /// in the given case.
+ /// **Counting symbols** are `1`, `a`, `A`, `i`, `I`, `い`, `イ`, `א`, `가`,
+ /// `ㄱ`, and `*`. They are replaced by the number in the sequence, in the
+ /// given case.
///
/// The `*` character means that symbols should be used to count, in the
/// order of `*`, `†`, `‡`, `§`, `¶`, and `‖`. If there are more than six
@@ -52,9 +51,9 @@ pub fn numbering(
/// suffixes. They are repeated as-is at in front of their rendered
/// equivalent of their counting symbol.
///
- /// This parameter can also be an arbitrary function that gets each number as
- /// an individual argument. When given a function, the `numbering` function
- /// just forwards the arguments to that function. While this is not
+ /// This parameter can also be an arbitrary function that gets each number
+ /// as an individual argument. When given a function, the `numbering`
+ /// function just forwards the arguments to that function. While this is not
/// particularly useful in itself, it means that you can just give arbitrary
/// numberings to the `numbering` function without caring whether they are
/// defined as a pattern or function.
@@ -65,8 +64,10 @@ pub fn numbering(
/// given, the last counting symbol with its prefix is repeated.
#[variadic]
numbers: Vec<usize>,
-) -> Value {
- numbering.apply_vm(vm, &numbers)?
+ /// The virtual machine.
+ vm: &mut Vm,
+) -> SourceResult<Value> {
+ numbering.apply_vm(vm, &numbers)
}
/// How to number a sequence of things.
@@ -84,8 +85,7 @@ impl Numbering {
Ok(match self {
Self::Pattern(pattern) => Value::Str(pattern.apply(numbers).into()),
Self::Func(func) => {
- let args =
- Args::new(func.span(), numbers.iter().map(|&n| Value::Int(n as i64)));
+ let args = Args::new(func.span(), numbers.iter().copied());
func.call_vm(vm, args)?
}
})
@@ -95,9 +95,7 @@ impl Numbering {
pub fn apply_vt(&self, vt: &mut Vt, numbers: &[usize]) -> SourceResult<Value> {
Ok(match self {
Self::Pattern(pattern) => Value::Str(pattern.apply(numbers).into()),
- Self::Func(func) => {
- func.call_vt(vt, numbers.iter().map(|&n| Value::Int(n as i64)))?
- }
+ Self::Func(func) => func.call_vt(vt, numbers.iter().copied())?,
})
}
@@ -116,19 +114,16 @@ impl From<NumberingPattern> for Numbering {
}
}
-cast_from_value! {
+cast! {
Numbering,
+ self => match self {
+ Self::Pattern(pattern) => pattern.into_value(),
+ Self::Func(func) => func.into_value(),
+ },
v: NumberingPattern => Self::Pattern(v),
v: Func => Self::Func(v),
}
-cast_to_value! {
- v: Numbering => match v {
- Numbering::Pattern(pattern) => pattern.into(),
- Numbering::Func(func) => func.into(),
- }
-}
-
/// How to turn a number into text.
///
/// A pattern consists of a prefix, followed by one of `1`, `a`, `A`, `i`,
@@ -230,15 +225,11 @@ impl FromStr for NumberingPattern {
}
}
-cast_from_value! {
+cast! {
NumberingPattern,
- v: Str => v.parse()?,
-}
-
-cast_to_value! {
- v: NumberingPattern => {
+ self => {
let mut pat = EcoString::new();
- for (prefix, kind, case) in &v.pieces {
+ for (prefix, kind, case) in &self.pieces {
pat.push_str(prefix);
let mut c = kind.to_char();
if *case == Case::Upper {
@@ -246,9 +237,10 @@ cast_to_value! {
}
pat.push(c);
}
- pat.push_str(&v.suffix);
- pat.into()
- }
+ pat.push_str(&self.suffix);
+ pat.into_value()
+ },
+ v: Str => v.parse()?,
}
/// Different kinds of numberings.
diff --git a/library/src/meta/outline.rs b/library/src/meta/outline.rs
index 089eceb2..894c3b8b 100644
--- a/library/src/meta/outline.rs
+++ b/library/src/meta/outline.rs
@@ -367,19 +367,14 @@ impl OutlineIndent {
// Length => indent with some fixed spacing per level
Some(Smart::Custom(OutlineIndent::Length(length))) => {
- let Ok(depth): Result<i64, _> = ancestors.len().try_into() else {
- bail!(span, "outline element depth too large");
- };
-
- let hspace = HElem::new(*length).pack().repeat(depth).unwrap();
- seq.push(hspace);
+ seq.push(HElem::new(*length).pack().repeat(ancestors.len()));
}
// Function => call function with the current depth and take
// the returned content
Some(Smart::Custom(OutlineIndent::Function(func))) => {
let depth = ancestors.len();
- let returned = func.call_vt(vt, [depth.into()])?;
+ let returned = func.call_vt(vt, [depth])?;
let Ok(returned) = returned.cast::<Content>() else {
bail!(
span,
@@ -396,17 +391,14 @@ impl OutlineIndent {
}
}
-cast_from_value! {
+cast! {
OutlineIndent,
- b: bool => OutlineIndent::Bool(b),
- s: Spacing => OutlineIndent::Length(s),
- f: Func => OutlineIndent::Function(f),
-}
-
-cast_to_value! {
- v: OutlineIndent => match v {
- OutlineIndent::Bool(b) => b.into(),
- OutlineIndent::Length(s) => s.into(),
- OutlineIndent::Function(f) => f.into()
- }
+ self => match self {
+ Self::Bool(v) => v.into_value(),
+ Self::Length(v) => v.into_value(),
+ Self::Function(v) => v.into_value()
+ },
+ v: bool => OutlineIndent::Bool(v),
+ v: Spacing => OutlineIndent::Length(v),
+ v: Func => OutlineIndent::Function(v),
}
diff --git a/library/src/meta/query.rs b/library/src/meta/query.rs
index ad7274f1..7f839f97 100644
--- a/library/src/meta/query.rs
+++ b/library/src/meta/query.rs
@@ -98,7 +98,6 @@ use crate::prelude::*;
///
/// Display: Query
/// Category: meta
-/// Returns: array
#[func]
pub fn query(
/// Can be an element function like a `heading` or `figure`, a `{<label>}`
@@ -111,7 +110,6 @@ pub fn query(
/// have an explicit label attached to them. This limitation will be
/// resolved in the future.
target: LocatableSelector,
-
/// Can be any location. Why is it required then? As noted before, Typst has
/// to evaluate parts of your code multiple times to determine the values of
/// all state. By only allowing this function within
@@ -120,14 +118,14 @@ pub fn query(
/// level of a module, the evaluation of the whole module and its exports
/// could depend on the query's result.
location: Location,
-) -> Value {
+ /// The virtual machine.
+ vm: &mut Vm,
+) -> Array {
let _ = location;
let vec = vm.vt.introspector.query(&target.0);
- Value::Array(
- vec.into_iter()
- .map(|elem| Value::Content(elem.into_inner()))
- .collect(),
- )
+ vec.into_iter()
+ .map(|elem| Value::Content(elem.into_inner()))
+ .collect()
}
/// Turns a value into a selector. The following values are accepted:
@@ -137,12 +135,11 @@ pub fn query(
///
/// Display: Selector
/// Category: meta
-/// Returns: content
#[func]
pub fn selector(
/// Can be an element function like a `heading` or `figure`, a `{<label>}`
/// or a more complex selector like `{heading.where(level: 1)}`.
target: Selector,
-) -> Value {
- target.into()
+) -> Selector {
+ target
}
diff --git a/library/src/meta/reference.rs b/library/src/meta/reference.rs
index c538b696..42450b97 100644
--- a/library/src/meta/reference.rs
+++ b/library/src/meta/reference.rs
@@ -193,7 +193,7 @@ impl Show for RefElem {
Smart::Auto => refable.supplement(),
Smart::Custom(None) => Content::empty(),
Smart::Custom(Some(supplement)) => {
- supplement.resolve(vt, [(*elem).clone().into()])?
+ supplement.resolve(vt, [(*elem).clone()])?
}
};
@@ -229,10 +229,10 @@ pub enum Supplement {
impl Supplement {
/// Tries to resolve the supplement into its content.
- pub fn resolve(
+ pub fn resolve<T: IntoValue>(
&self,
vt: &mut Vt,
- args: impl IntoIterator<Item = Value>,
+ args: impl IntoIterator<Item = T>,
) -> SourceResult<Content> {
Ok(match self {
Supplement::Content(content) => content.clone(),
@@ -241,19 +241,16 @@ impl Supplement {
}
}
-cast_from_value! {
+cast! {
Supplement,
+ self => match self {
+ Self::Content(v) => v.into_value(),
+ Self::Func(v) => v.into_value(),
+ },
v: Content => Self::Content(v),
v: Func => Self::Func(v),
}
-cast_to_value! {
- v: Supplement => match v {
- Supplement::Content(v) => v.into(),
- Supplement::Func(v) => v.into(),
- }
-}
-
/// Marks an element as being able to be referenced. This is used to implement
/// the `@ref` element.
pub trait Refable {
diff --git a/library/src/meta/state.rs b/library/src/meta/state.rs
index 284daf54..231852e3 100644
--- a/library/src/meta/state.rs
+++ b/library/src/meta/state.rs
@@ -233,7 +233,6 @@ use crate::prelude::*;
///
/// Display: State
/// Category: meta
-/// Returns: state
#[func]
pub fn state(
/// The key that identifies this state.
@@ -241,8 +240,8 @@ pub fn state(
/// The initial value of the state.
#[default]
init: Value,
-) -> Value {
- Value::dynamic(State { key, init })
+) -> State {
+ State { key, init }
}
/// A state.
@@ -265,10 +264,10 @@ impl State {
span: Span,
) -> SourceResult<Value> {
let value = match method {
- "display" => self.display(args.eat()?).into(),
+ "display" => self.display(args.eat()?).into_value(),
"at" => self.at(&mut vm.vt, args.expect("location")?)?,
"final" => self.final_(&mut vm.vt, args.expect("location")?)?,
- "update" => self.update(args.expect("value or function")?).into(),
+ "update" => self.update(args.expect("value or function")?).into_value(),
_ => bail!(span, "type state has no method `{}`", method),
};
args.finish()?;
@@ -284,10 +283,7 @@ impl State {
#[tracing::instrument(skip(self, vt))]
pub fn at(self, vt: &mut Vt, location: Location) -> SourceResult<Value> {
let sequence = self.sequence(vt)?;
- let offset = vt
- .introspector
- .query(&Selector::before(self.selector(), location, true))
- .len();
+ let offset = vt.introspector.query(&self.selector().before(location, true)).len();
Ok(sequence[offset].clone())
}
@@ -358,8 +354,8 @@ impl Debug for State {
}
}
-cast_from_value! {
- State: "state",
+cast! {
+ type State: "state",
}
/// An update to perform on a state.
@@ -377,8 +373,8 @@ impl Debug for StateUpdate {
}
}
-cast_from_value! {
- StateUpdate: "state update",
+cast! {
+ type StateUpdate: "state update",
v: Func => Self::Func(v),
v: Value => Self::Set(v),
}