Skip to content

Commit

Permalink
add int and float filters and Or type
Browse files Browse the repository at this point in the history
  • Loading branch information
suaviloquence committed Jul 12, 2024
1 parent 9b49aa2 commit 99c1e49
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/interpreter/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::{
sync::{Arc, LazyLock},

Check failure on line 3 in src/interpreter/filter.rs

View workflow job for this annotation

GitHub Actions / run cargo tests

use of unstable library feature 'lazy_cell'
};

use super::{ElementContext, TryFromValue, Value};
use anyhow::Context as _;

use super::{value::Or, ElementContext, TryFromValue, Value};

pub use filter_proc_macro::{filter_fn, Args};

Expand Down Expand Up @@ -99,6 +101,32 @@ fn take<'doc>(
Ok(value.remove(&key).unwrap_or(Value::Null))
}

#[filter_fn]
fn int<'doc>(value: Or<i64, Or<f64, Arc<str>>>) -> anyhow::Result<Value<'doc>> {
let n = match value {
Or::A(n) => n,
Or::B(Or::A(x)) => x as i64,
Or::B(Or::B(s)) => s
.parse()
.with_context(|| format!("`{s}` is not an integer."))?,
};

Ok(Value::Int(n))
}

#[filter_fn]
fn float<'doc>(value: Or<f64, Or<i64, Arc<str>>>) -> anyhow::Result<Value<'doc>> {
let x = match value {
Or::A(x) => x,
Or::B(Or::A(n)) => n as f64,
Or::B(Or::B(s)) => s
.parse()
.with_context(|| format!("`{s}` is not a float."))?,
};

Ok(Value::Float(x))
}

macro_rules! build_map {
($(
$id: ident,
Expand All @@ -118,6 +146,8 @@ static BUILTIN_FILTERS: LazyLock<BTreeMap<&'static str, Box<dyn FilterDyn + Send
strip,
take,
attrs,
int,
float,
}
.into_iter()
.collect()
Expand Down
18 changes: 18 additions & 0 deletions src/interpreter/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,3 +217,21 @@ impl<'a> From<scraper::ElementRef<'a>> for Value<'a> {
Self::Element(value)
}
}

#[derive(Debug, Clone)]
pub enum Or<A, B> {
A(A),
B(B),
}

impl<'a, A: TryFromValue<'a>, B: TryFromValue<'a>> TryFromValue<'a> for Or<A, B> {
fn try_from_value(value: Value<'a>) -> anyhow::Result<Self> {
match value.clone().try_into() {
Ok(a) => Ok(Self::A(a)),
Err(a) => match value.try_into() {
Ok(b) => Ok(Self::B(b)),
Err(b) => anyhow::bail!("Error: {a} or {b}"),
},
}
}
}

0 comments on commit 99c1e49

Please sign in to comment.