Skip to content

Commit

Permalink
fix(filter): Switch to standard error type
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Error type for filters changed.
  • Loading branch information
epage committed Sep 26, 2018
1 parent 60b29d0 commit 3d18b71
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 177 deletions.
47 changes: 2 additions & 45 deletions liquid-interpreter/src/filter.rs
@@ -1,52 +1,9 @@
use std::fmt;
use liquid_error;

use std::error::Error;
use value::Value;

/// Replace this with `liquid_error::Error`.
#[derive(Debug, PartialEq, Eq)]
pub enum FilterError {
/// Invalid data type.
InvalidType(String),
/// Invalid number of arguments.
InvalidArgumentCount(String),
/// Invalid argument at a given position.
InvalidArgument(u16, String),
}

impl FilterError {
/// Quick and dirty way to create an error.
pub fn invalid_type<T>(s: &str) -> Result<T, FilterError> {
Err(FilterError::InvalidType(s.to_owned()))
}
}

impl fmt::Display for FilterError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
FilterError::InvalidType(ref e) => write!(f, "Invalid type : {}", e),
FilterError::InvalidArgumentCount(ref e) => {
write!(f, "Invalid number of arguments : {}", e)
}
FilterError::InvalidArgument(ref pos, ref e) => {
write!(f, "Invalid argument given at position {} : {}", pos, e)
}
}
}
}

impl Error for FilterError {
fn description(&self) -> &str {
match *self {
FilterError::InvalidType(ref e)
| FilterError::InvalidArgumentCount(ref e)
| FilterError::InvalidArgument(_, ref e) => e,
}
}
}

/// Expected return type of a `Filter`.
pub type FilterResult = Result<Value, FilterError>;
pub type FilterResult = Result<Value, liquid_error::Error>;

/// A trait for creating custom tags. This is a simple type alias for a function.
///
Expand Down
4 changes: 1 addition & 3 deletions liquid-interpreter/src/text.rs
Expand Up @@ -13,9 +13,7 @@ pub struct Text {
impl Text {
/// Create a raw template expression.
pub fn new<S: Into<String>>(text: S) -> Text {
Text {
text: text.into(),
}
Text { text: text.into() }
}
}

Expand Down
45 changes: 14 additions & 31 deletions src/filters/date.rs
@@ -1,13 +1,11 @@
use liquid_value::Scalar;
use liquid_value::Value;

use super::check_args_len;
use super::{check_args_len, invalid_argument, invalid_input};
use interpreter::FilterResult;

#[cfg(feature = "extra-filters")]
use chrono::FixedOffset;
#[cfg(feature = "extra-filters")]
use interpreter::FilterError;

pub fn date(input: &Value, args: &[Value]) -> FilterResult {
check_args_len(args, 1, 0)?;
Expand Down Expand Up @@ -37,14 +35,14 @@ pub fn date_in_tz(input: &Value, args: &[Value]) -> FilterResult {
let date = input
.as_scalar()
.and_then(Scalar::to_date)
.ok_or_else(|| FilterError::InvalidType("Invalid date format".into()))?;
.ok_or_else(|| invalid_input("Invalid date format"))?;

let format = args[0].to_str();

let n = args[1]
.as_scalar()
.and_then(Scalar::to_integer)
.ok_or_else(|| FilterError::InvalidArgument(1, "Whole number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(1, "Whole number expected"))?;
let timezone = FixedOffset::east(n * 3600);

Ok(Value::scalar(
Expand Down Expand Up @@ -145,21 +143,15 @@ mod tests {

#[test]
fn unit_date_missing_format() {
assert_eq!(
failed!(date, tos!("13 Jun 2016 02:30:00 +0300")),
FilterError::InvalidArgumentCount("expected at least 1, 0 given".to_owned())
);
failed!(date, tos!("13 Jun 2016 02:30:00 +0300"));
}

#[test]
fn unit_date_extra_param() {
assert_eq!(
failed!(
date,
tos!("13 Jun 2016 02:30:00 +0300"),
&[Value::scalar(0f64), Value::scalar(1f64)]
),
FilterError::InvalidArgumentCount("expected at most 1, 2 given".to_owned())
failed!(
date,
tos!("13 Jun 2016 02:30:00 +0300"),
&[Value::scalar(0f64), Value::scalar(1f64)]
);
}

Expand Down Expand Up @@ -195,46 +187,39 @@ mod tests {
fn unit_date_in_tz_input_not_a_string() {
let input = &Value::scalar(0f64);
let args = &[tos!("%Y-%m-%d %H:%M:%S %z"), Value::scalar(0i32)];
let desired_result = FilterError::InvalidType("Invalid date format".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}

#[test]
#[cfg(feature = "extra-filters")]
fn unit_date_in_tz_input_not_a_date_string() {
let input = &tos!("blah blah blah");
let args = &[tos!("%Y-%m-%d %H:%M:%S %z"), Value::scalar(0i32)];
let desired_result = FilterError::InvalidType("Invalid date format".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}

#[test]
#[cfg(feature = "extra-filters")]
fn unit_date_in_tz_offset_not_a_num() {
let input = &tos!("13 Jun 2016 12:00:00 +0000");
let args = &[tos!("%Y-%m-%d %H:%M:%S %z"), tos!("Hello")];
let desired_result = FilterError::InvalidArgument(1, "Whole number expected".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}

#[test]
#[cfg(feature = "extra-filters")]
fn unit_date_in_tz_zero_arguments() {
let input = &tos!("13 Jun 2016 12:00:00 +0000");
let args = &[];
let desired_result =
FilterError::InvalidArgumentCount("expected at least 2, 0 given".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}

#[test]
#[cfg(feature = "extra-filters")]
fn unit_date_in_tz_one_argument() {
let input = &tos!("13 Jun 2016 12:00:00 +0000");
let args = &[tos!("%Y-%m-%d %H:%M:%S %z")];
let desired_result =
FilterError::InvalidArgumentCount("expected at least 2, 1 given".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}

#[test]
Expand All @@ -246,8 +231,6 @@ mod tests {
Value::scalar(0f64),
Value::scalar(1f64),
];
let desired_result =
FilterError::InvalidArgumentCount("expected at most 2, 3 given".to_owned());
assert_eq!(failed!(date_in_tz, input, args), desired_result);
failed!(date_in_tz, input, args);
}
}
5 changes: 1 addition & 4 deletions src/filters/html.rs
Expand Up @@ -101,7 +101,6 @@ pub fn newline_to_br(input: &Value, args: &[Value]) -> FilterResult {
mod tests {

use super::*;
use interpreter::FilterError;

macro_rules! unit {
($a:ident, $b:expr) => {{
Expand Down Expand Up @@ -218,8 +217,6 @@ mod tests {
fn unit_newline_to_br_one_argument() {
let input = &tos!("a\nb");
let args = &[Value::scalar(0f64)];
let desired_result =
FilterError::InvalidArgumentCount("expected at most 0, 1 given".to_owned());
assert_eq!(failed!(newline_to_br, input, args), desired_result);
failed!(newline_to_br, input, args);
}
}
45 changes: 21 additions & 24 deletions src/filters/math.rs
@@ -1,7 +1,7 @@
use liquid_value::Value;

use super::check_args_len;
use interpreter::{FilterError, FilterResult};
use super::{check_args_len, invalid_argument, invalid_input};
use interpreter::FilterResult;

/// Returns the absolute value of a number.
pub fn abs(input: &Value, args: &[Value]) -> FilterResult {
Expand All @@ -12,8 +12,8 @@ pub fn abs(input: &Value, args: &[Value]) -> FilterResult {
.to_integer()
.map(|i| Value::scalar(i.abs()))
.or_else(|| s.to_float().map(|i| Value::scalar(i.abs())))
.ok_or_else(|| FilterError::InvalidType("Numeric value expected".to_owned())),
_ => Err(FilterError::InvalidType("Number expected".to_owned())),
.ok_or_else(|| invalid_input("Numeric value expected")),
_ => Err(invalid_input("Number expected")),
}
}

Expand All @@ -22,11 +22,11 @@ pub fn plus(input: &Value, args: &[Value]) -> FilterResult {

let input = input
.as_scalar()
.ok_or_else(|| FilterError::InvalidType("Number expected".to_owned()))?;
.ok_or_else(|| invalid_input("Number expected"))?;

let operand = args[0]
.as_scalar()
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

let result = input
.to_integer()
Expand All @@ -36,7 +36,7 @@ pub fn plus(input: &Value, args: &[Value]) -> FilterResult {
.to_float()
.and_then(|i| operand.to_float().map(|o| Value::scalar(i + o)))
})
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

Ok(result)
}
Expand All @@ -46,11 +46,11 @@ pub fn minus(input: &Value, args: &[Value]) -> FilterResult {

let input = input
.as_scalar()
.ok_or_else(|| FilterError::InvalidType("Number expected".to_owned()))?;
.ok_or_else(|| invalid_input("Number expected"))?;

let operand = args[0]
.as_scalar()
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

let result = input
.to_integer()
Expand All @@ -60,7 +60,7 @@ pub fn minus(input: &Value, args: &[Value]) -> FilterResult {
.to_float()
.and_then(|i| operand.to_float().map(|o| Value::scalar(i - o)))
})
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

Ok(result)
}
Expand All @@ -70,11 +70,11 @@ pub fn times(input: &Value, args: &[Value]) -> FilterResult {

let input = input
.as_scalar()
.ok_or_else(|| FilterError::InvalidType("Number expected".to_owned()))?;
.ok_or_else(|| invalid_input("Number expected"))?;

let operand = args[0]
.as_scalar()
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

let result = input
.to_integer()
Expand All @@ -84,7 +84,7 @@ pub fn times(input: &Value, args: &[Value]) -> FilterResult {
.to_float()
.and_then(|i| operand.to_float().map(|o| Value::scalar(i * o)))
})
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

Ok(result)
}
Expand All @@ -94,11 +94,11 @@ pub fn divided_by(input: &Value, args: &[Value]) -> FilterResult {

let input = input
.as_scalar()
.ok_or_else(|| FilterError::InvalidType("Number expected".to_owned()))?;
.ok_or_else(|| invalid_input("Number expected"))?;

let operand = args[0]
.as_scalar()
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

let result = input
.to_integer()
Expand All @@ -108,7 +108,7 @@ pub fn divided_by(input: &Value, args: &[Value]) -> FilterResult {
.to_float()
.and_then(|i| operand.to_float().map(|o| Value::scalar(i / o)))
})
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

Ok(result)
}
Expand All @@ -118,11 +118,11 @@ pub fn modulo(input: &Value, args: &[Value]) -> FilterResult {

let input = input
.as_scalar()
.ok_or_else(|| FilterError::InvalidType("Number expected".to_owned()))?;
.ok_or_else(|| invalid_input("Number expected"))?;

let operand = args[0]
.as_scalar()
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

let result = input
.to_integer()
Expand All @@ -132,7 +132,7 @@ pub fn modulo(input: &Value, args: &[Value]) -> FilterResult {
.to_float()
.and_then(|i| operand.to_float().map(|o| Value::scalar(i % o)))
})
.ok_or_else(|| FilterError::InvalidArgument(0, "Number expected".to_owned()))?;
.ok_or_else(|| invalid_argument(0, "Number expected"))?;

Ok(result)
}
Expand Down Expand Up @@ -186,17 +186,14 @@ mod tests {
fn unit_abs_not_number_or_string() {
let input = &Value::scalar(true);
let args = &[];
let desired_result = FilterError::InvalidType("Numeric value expected".to_owned());
assert_eq!(failed!(abs, input, args), desired_result);
failed!(abs, input, args);
}

#[test]
fn unit_abs_one_argument() {
let input = &Value::scalar(-1f64);
let args = &[Value::scalar(0f64)];
let desired_result =
FilterError::InvalidArgumentCount("expected at most 0, 1 given".to_owned());
assert_eq!(failed!(abs, input, args), desired_result);
failed!(abs, input, args);
}

#[test]
Expand Down

0 comments on commit 3d18b71

Please sign in to comment.