From 78da4ad2fe90bbba6fd06bc26f74221666ba8962 Mon Sep 17 00:00:00 2001 From: Connor Skees Date: Sun, 26 Jul 2020 22:15:28 -0400 Subject: [PATCH] use macro to simplify declaration of trig fns --- src/builtin/modules/math.rs | 221 +++++++----------------------------- src/value/number/mod.rs | 93 ++++----------- 2 files changed, 61 insertions(+), 253 deletions(-) diff --git a/src/builtin/modules/math.rs b/src/builtin/modules/math.rs index 1c6dce0..1e6ebe1 100644 --- a/src/builtin/modules/math.rs +++ b/src/builtin/modules/math.rs @@ -140,192 +140,49 @@ fn sqrt(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { }) } -fn cos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - let number = args.get_err(0, "number")?; +macro_rules! trig_fn { + ($name:ident, $name_deg:ident) => { + fn $name(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { + args.max_args(1)?; + let number = args.get_err(0, "number")?; - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.cos(), Unit::None, true) + Ok(match number { + Value::Dimension(Some(n), Unit::None, ..) + | Value::Dimension(Some(n), Unit::Rad, ..) => { + Value::Dimension(n.$name(), Unit::None, true) + } + Value::Dimension(Some(n), Unit::Deg, ..) => { + Value::Dimension(n.$name_deg(), Unit::None, true) + } + v @ Value::Dimension(Some(..), ..) => { + return Err(( + format!( + "$number: Expected {} to be an angle.", + v.inspect(args.span())? + ), + args.span(), + ) + .into()) + } + Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), + v => { + return Err(( + format!("$number: {} is not a number.", v.inspect(args.span())?), + args.span(), + ) + .into()) + } + }) } - Value::Dimension(Some(n), Unit::Deg, ..) => Value::Dimension(n.cos_deg(), Unit::None, true), - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) + }; } -fn sin(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - let number = args.get_err(0, "number")?; - - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.sin(), Unit::None, true) - } - Value::Dimension(Some(n), Unit::Deg, ..) => Value::Dimension(n.sin_deg(), Unit::None, true), - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) -} - -fn tan(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - let number = args.get_err(0, "number")?; - - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.tan(), Unit::None, true) - } - Value::Dimension(Some(n), Unit::Deg, ..) => Value::Dimension(n.tan_deg(), Unit::None, true), - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) -} - -fn acos(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - args.max_args(1)?; - let number = args.get_err(0, "number")?; - - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.acos(), Unit::None, true) - } - Value::Dimension(Some(n), Unit::Deg, ..) => { - Value::Dimension(n.acos_deg(), Unit::None, true) - } - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) -} - -fn asin(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - let number = args.get_err(0, "number")?; - - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.asin(), Unit::None, true) - } - Value::Dimension(Some(n), Unit::Deg, ..) => { - Value::Dimension(n.asin_deg(), Unit::None, true) - } - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) -} - -fn atan(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { - args.max_args(1)?; - let number = args.get_err(0, "number")?; - - Ok(match number { - Value::Dimension(Some(n), Unit::None, ..) | Value::Dimension(Some(n), Unit::Rad, ..) => { - Value::Dimension(n.atan(), Unit::None, true) - } - Value::Dimension(Some(n), Unit::Deg, ..) => { - Value::Dimension(n.atan_deg(), Unit::None, true) - } - v @ Value::Dimension(Some(..), ..) => { - return Err(( - format!( - "$number: Expected {} to be an angle.", - v.inspect(args.span())? - ), - args.span(), - ) - .into()) - } - Value::Dimension(None, ..) => Value::Dimension(None, Unit::None, true), - v => { - return Err(( - format!("$number: {} is not a number.", v.inspect(args.span())?), - args.span(), - ) - .into()) - } - }) -} +trig_fn!(cos, cos_deg); +trig_fn!(sin, sin_deg); +trig_fn!(tan, tan_deg); +trig_fn!(acos, acos_deg); +trig_fn!(asin, asin_deg); +trig_fn!(atan, atan_deg); fn atan2(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult { args.max_args(2)?; diff --git a/src/value/number/mod.rs b/src/value/number/mod.rs index 8e9b9e7..7c3158b 100644 --- a/src/value/number/mod.rs +++ b/src/value/number/mod.rs @@ -124,79 +124,30 @@ impl Number { } } +macro_rules! trig_fn( + ($name:ident, $name_deg:ident) => { + pub fn $name(self) -> Option { + Some(Number::Big(Box::new(BigRational::from_float( + self.as_float()?.$name(), + )?))) + } + + pub fn $name_deg(self) -> Option { + Some(Number::Big(Box::new(BigRational::from_float( + self.as_float()?.to_radians().$name(), + )?))) + } + } +); + /// Trigonometry methods impl Number { - pub fn cos(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.cos(), - )?))) - } - - pub fn cos_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().cos(), - )?))) - } - - pub fn acos(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.acos(), - )?))) - } - - pub fn acos_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().acos(), - )?))) - } - - pub fn sin(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.sin(), - )?))) - } - - pub fn sin_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().sin(), - )?))) - } - - pub fn asin(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.asin(), - )?))) - } - - pub fn asin_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().asin(), - )?))) - } - - pub fn tan(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.tan(), - )?))) - } - - pub fn tan_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().tan(), - )?))) - } - - pub fn atan(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.atan(), - )?))) - } - - pub fn atan_deg(self) -> Option { - Some(Number::Big(Box::new(BigRational::from_float( - self.as_float()?.to_radians().atan(), - )?))) - } + trig_fn!(cos, cos_deg); + trig_fn!(sin, sin_deg); + trig_fn!(tan, tan_deg); + trig_fn!(acos, acos_deg); + trig_fn!(asin, asin_deg); + trig_fn!(atan, atan_deg); } impl Default for Number {