use super::*;
impl Add for Value {
type Output = Self;
fn add(self, other: Self) -> Self {
match (self, other) {
(Self::String(ref s), ref o) => {
Self::string(format!("{}{}", s.clone(), &o.to_string()))
}
(Self::BigInt(ref n1), Self::BigInt(ref n2)) => {
Self::bigint(n1.as_inner().clone() + n2.as_inner().clone())
}
(ref s, Self::String(ref o)) => Self::string(format!("{}{}", s.to_string(), o)),
(ref s, ref o) => Self::rational(s.to_number() + o.to_number()),
}
}
}
impl Sub for Value {
type Output = Self;
fn sub(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() - b.as_inner().clone())
}
(a, b) => Self::rational(a.to_number() - b.to_number()),
}
}
}
impl Mul for Value {
type Output = Self;
fn mul(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() * b.as_inner().clone())
}
(a, b) => Self::rational(a.to_number() * b.to_number()),
}
}
}
impl Div for Value {
type Output = Self;
fn div(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() / b.as_inner().clone())
}
(a, b) => Self::rational(a.to_number() / b.to_number()),
}
}
}
impl Rem for Value {
type Output = Self;
fn rem(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() % b.as_inner().clone())
}
(a, b) => Self::rational(a.to_number() % b.to_number()),
}
}
}
impl BitAnd for Value {
type Output = Self;
fn bitand(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() & b.as_inner().clone())
}
(a, b) => Self::integer(a.to_integer() & b.to_integer()),
}
}
}
impl BitOr for Value {
type Output = Self;
fn bitor(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() | b.as_inner().clone())
}
(a, b) => Self::integer(a.to_integer() | b.to_integer()),
}
}
}
impl BitXor for Value {
type Output = Self;
fn bitxor(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() ^ b.as_inner().clone())
}
(a, b) => Self::integer(a.to_integer() ^ b.to_integer()),
}
}
}
impl Shl for Value {
type Output = Self;
fn shl(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() << b.as_inner().clone())
}
(a, b) => Self::integer(a.to_integer() << b.to_integer()),
}
}
}
impl Shr for Value {
type Output = Self;
fn shr(self, other: Self) -> Self {
match (self, other) {
(Self::BigInt(ref a), Self::BigInt(ref b)) => {
Self::bigint(a.as_inner().clone() >> b.as_inner().clone())
}
(a, b) => Self::integer(a.to_integer() >> b.to_integer()),
}
}
}
impl Not for Value {
type Output = Self;
fn not(self) -> Self {
Self::boolean(!self.is_true())
}
}
impl Neg for Value {
type Output = Self;
fn neg(self) -> Self::Output {
match self {
Self::Object(_) | Self::Symbol(_) | Self::Undefined => Self::rational(NAN),
Self::String(ref str) => Self::rational(match f64::from_str(str) {
Ok(num) => -num,
Err(_) => NAN,
}),
Self::Rational(num) => Self::rational(-num),
Self::Integer(num) => Self::rational(-f64::from(num)),
Self::Boolean(true) => Self::integer(1),
Self::Boolean(false) | Self::Null => Self::integer(0),
Self::BigInt(ref num) => Self::bigint(-num.as_inner().clone()),
}
}
}