use js::function::NativeFunctionData;
use js::value::{from_value, to_value, ResultValue, Value, ValueData};
use rand::random;
use std::f64;
pub fn abs(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.abs()
} else {
f64::NAN
}))
}
pub fn acos(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.acos()
} else {
f64::NAN
}))
}
pub fn asin(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.asin()
} else {
f64::NAN
}))
}
pub fn atan(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.atan()
} else {
f64::NAN
}))
}
pub fn atan2(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.atan2(args.get(1).unwrap().to_num())
} else {
f64::NAN
}))
}
pub fn cbrt(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.cbrt()
} else {
f64::NAN
}))
}
pub fn ceil(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.ceil()
} else {
f64::NAN
}))
}
pub fn cos(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.cos()
} else {
f64::NAN
}))
}
pub fn exp(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.exp()
} else {
f64::NAN
}))
}
pub fn floor(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.floor()
} else {
f64::NAN
}))
}
pub fn log(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.log(f64::consts::E)
} else {
f64::NAN
}))
}
pub fn max(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
let mut max = f64::NEG_INFINITY;
for arg in args.iter() {
let num = arg.to_num();
max = max.max(num);
}
Ok(to_value(max))
}
pub fn min(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
let mut max = f64::INFINITY;
for arg in args.iter() {
let num = arg.to_num();
max = max.min(num);
}
Ok(to_value(max))
}
pub fn pow(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 2 {
let num: f64 = from_value(args.get(0).unwrap().clone()).unwrap();
let power: f64 = from_value(args.get(1).unwrap().clone()).unwrap();
num.powf(power)
} else {
f64::NAN
}))
}
pub fn _random(_: Value, _: Value, _args: Vec<Value>) -> ResultValue {
Ok(to_value(random::<f64>()))
}
pub fn round(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.round()
} else {
f64::NAN
}))
}
pub fn sin(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.sin()
} else {
f64::NAN
}))
}
pub fn sqrt(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.sqrt()
} else {
f64::NAN
}))
}
pub fn tan(_: Value, _: Value, args: Vec<Value>) -> ResultValue {
Ok(to_value(if args.len() >= 1 {
from_value::<f64>(args.get(0).unwrap().clone())
.unwrap()
.tan()
} else {
f64::NAN
}))
}
pub fn _create(global: Value) -> Value {
let math = ValueData::new_obj(Some(global));
math.set_field_slice("E", to_value(f64::consts::E));
math.set_field_slice("LN2", to_value(f64::consts::LN_2));
math.set_field_slice("LN10", to_value(f64::consts::LN_10));
math.set_field_slice("LOG2E", to_value(f64::consts::LOG2_E));
math.set_field_slice("LOG10E", to_value(f64::consts::LOG10_E));
math.set_field_slice("SQRT1_2", to_value(0.5f64.sqrt()));
math.set_field_slice("SQRT2", to_value(f64::consts::SQRT_2));
math.set_field_slice("PI", to_value(f64::consts::PI));
math.set_field_slice("abs", to_value(abs as NativeFunctionData));
math.set_field_slice("acos", to_value(acos as NativeFunctionData));
math.set_field_slice("asin", to_value(asin as NativeFunctionData));
math.set_field_slice("atan", to_value(atan as NativeFunctionData));
math.set_field_slice("atan2", to_value(atan2 as NativeFunctionData));
math.set_field_slice("cbrt", to_value(cbrt as NativeFunctionData));
math.set_field_slice("ceil", to_value(ceil as NativeFunctionData));
math.set_field_slice("cos", to_value(cos as NativeFunctionData));
math.set_field_slice("exp", to_value(exp as NativeFunctionData));
math.set_field_slice("floor", to_value(floor as NativeFunctionData));
math.set_field_slice("log", to_value(log as NativeFunctionData));
math.set_field_slice("max", to_value(max as NativeFunctionData));
math.set_field_slice("min", to_value(min as NativeFunctionData));
math.set_field_slice("pow", to_value(pow as NativeFunctionData));
math.set_field_slice("random", to_value(_random as NativeFunctionData));
math.set_field_slice("round", to_value(round as NativeFunctionData));
math.set_field_slice("sin", to_value(sin as NativeFunctionData));
math.set_field_slice("sqrt", to_value(sqrt as NativeFunctionData));
math.set_field_slice("tan", to_value(tan as NativeFunctionData));
math
}
pub fn init(global: Value) {
global.set_field_slice("Math", _create(global.clone()));
}