use crate::error::Error;
use crate::value::Value;
use crate::vm::State;
#[deprecated = "Use the minijinja::functions::Function instead"]
#[doc(hidden)]
pub use crate::functions::Function as Test;
#[deprecated = "Use the minijinja::value::FunctionResult instead"]
#[doc(hidden)]
pub use crate::value::FunctionResult as TestResult;
pub fn is_undefined(v: &Value) -> bool {
v.is_undefined()
}
pub fn is_defined(v: &Value) -> bool {
!v.is_undefined()
}
pub fn is_none(v: &Value) -> bool {
v.is_none()
}
pub fn is_safe(v: &Value) -> bool {
v.is_safe()
}
#[cfg(feature = "builtins")]
mod builtins {
use super::*;
use std::borrow::Cow;
use crate::value::ops::{coerce, CoerceResult};
use crate::value::ValueKind;
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_boolean(v: &Value) -> bool {
v.kind() == ValueKind::Bool
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_odd(v: Value) -> bool {
i128::try_from(v).ok().is_some_and(|x| x % 2 != 0)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_even(v: Value) -> bool {
i128::try_from(v).ok().is_some_and(|x| x % 2 == 0)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_divisibleby(v: &Value, other: &Value) -> bool {
match coerce(v, other, false) {
Some(CoerceResult::I128(a, b)) => (a % b) == 0,
Some(CoerceResult::F64(a, b)) => (a % b) == 0.0,
_ => false,
}
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_number(v: &Value) -> bool {
matches!(v.kind(), ValueKind::Number)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_integer(v: &Value) -> bool {
v.is_integer()
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_float(v: &Value) -> bool {
matches!(v.0, crate::value::ValueRepr::F64(_))
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_string(v: &Value) -> bool {
matches!(v.kind(), ValueKind::String)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_sequence(v: &Value) -> bool {
matches!(v.kind(), ValueKind::Seq)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_iterable(v: &Value) -> bool {
v.try_iter().is_ok()
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_mapping(v: &Value) -> bool {
matches!(v.kind(), ValueKind::Map)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_startingwith(v: Cow<'_, str>, other: Cow<'_, str>) -> bool {
v.starts_with(&other as &str)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
pub fn is_endingwith(v: Cow<'_, str>, other: Cow<'_, str>) -> bool {
v.ends_with(&other as &str)
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_eq(value: &Value, other: &Value) -> bool {
*value == *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_ne(value: &Value, other: &Value) -> bool {
*value != *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_lt(value: &Value, other: &Value) -> bool {
*value < *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_le(value: &Value, other: &Value) -> bool {
*value <= *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_gt(value: &Value, other: &Value) -> bool {
*value > *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_ge(value: &Value, other: &Value) -> bool {
*value >= *other
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_in(state: &State, value: &Value, other: &Value) -> Result<bool, Error> {
ok!(state.undefined_behavior().assert_iterable(other));
Ok(crate::value::ops::contains(other, value)
.map(|value| value.is_true())
.unwrap_or(false))
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_true(value: &Value) -> bool {
matches!(value.0, crate::value::ValueRepr::Bool(true))
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_false(value: &Value) -> bool {
matches!(value.0, crate::value::ValueRepr::Bool(false))
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_filter(state: &State, name: &str) -> bool {
state.env().get_filter(name).is_some()
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_test(state: &State, name: &str) -> bool {
state.env().get_test(name).is_some()
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_lower(name: &str) -> bool {
name.chars().all(|x| x.is_lowercase())
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_upper(name: &str) -> bool {
name.chars().all(|x| x.is_uppercase())
}
#[cfg_attr(docsrs, doc(cfg(feature = "builtins")))]
#[cfg(feature = "builtins")]
pub fn is_sameas(value: &Value, other: &Value) -> bool {
match (value.as_object(), other.as_object()) {
(Some(a), Some(b)) => a.is_same_object(b),
(None, Some(_)) | (Some(_), None) => false,
(None, None) => {
if value.kind() != other.kind() || value.is_integer() != other.is_integer() {
false
} else {
value == other
}
}
}
}
}
#[cfg(feature = "builtins")]
pub use self::builtins::*;