From 1198e0cd385737efc38dbd8ba13db802a68e0dc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20d=27Herbais=20de=20Thun?= Date: Wed, 12 Apr 2023 12:47:51 +0200 Subject: Selector rework (#640) --- src/eval/methods.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'src/eval/methods.rs') diff --git a/src/eval/methods.rs b/src/eval/methods.rs index 452b90da..56d1c7b7 100644 --- a/src/eval/methods.rs +++ b/src/eval/methods.rs @@ -4,7 +4,7 @@ use ecow::EcoString; use super::{Args, Str, Value, Vm}; use crate::diag::{At, SourceResult}; -use crate::model::Location; +use crate::model::{Location, Selector}; use crate::syntax::Span; /// Call a method on a value. @@ -151,11 +151,29 @@ pub fn call( }, Value::Dyn(dynamic) => { - if let Some(&location) = dynamic.downcast::() { + if let Some(location) = dynamic.downcast::() { match method { - "page" => vm.vt.introspector.page(location).into(), - "position" => vm.vt.introspector.position(location).into(), - "page-numbering" => vm.vt.introspector.page_numbering(location), + "page" => vm.vt.introspector.page(*location).into(), + "position" => vm.vt.introspector.position(*location).into(), + "page-numbering" => vm.vt.introspector.page_numbering(*location), + _ => return missing(), + } + } else if let Some(selector) = dynamic.downcast::() { + match method { + "or" => selector.clone().or(args.all::()?).into(), + "and" => selector.clone().and(args.all::()?).into(), + "before" => { + let location = args.expect::("selector")?; + let inclusive = + args.named_or_find::("inclusive")?.unwrap_or(true); + selector.clone().before(location, inclusive).into() + } + "after" => { + let location = args.expect::("selector")?; + let inclusive = + args.named_or_find::("inclusive")?.unwrap_or(true); + selector.clone().after(location, inclusive).into() + } _ => return missing(), } } else { @@ -312,6 +330,7 @@ pub fn methods_on(type_name: &str) -> &[(&'static str, bool)] { "function" => &[("where", true), ("with", true)], "arguments" => &[("named", false), ("pos", false)], "location" => &[("page", false), ("position", false), ("page-numbering", false)], + "selector" => &[("or", true), ("and", true), ("before", true), ("after", true)], "counter" => &[ ("display", true), ("at", true), -- cgit v1.2.3