use crate::Error;
use core::fmt;
use core::str::FromStr;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum UnaryOperator {
Neg,
Not,
}
impl UnaryOperator {
pub fn as_str(&self) -> &'static str {
match self {
UnaryOperator::Neg => "-",
UnaryOperator::Not => "!",
}
}
}
impl fmt::Display for UnaryOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for UnaryOperator {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"-" => Ok(UnaryOperator::Neg),
"!" => Ok(UnaryOperator::Not),
_ => Err(Error::new(format!("invalid unary operator: `{s}`"))),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum BinaryOperator {
Eq,
NotEq,
LessEq,
GreaterEq,
Less,
Greater,
Plus,
Minus,
Mul,
Div,
Mod,
And,
Or,
}
impl BinaryOperator {
pub fn as_str(&self) -> &'static str {
match self {
BinaryOperator::Eq => "==",
BinaryOperator::NotEq => "!=",
BinaryOperator::LessEq => "<=",
BinaryOperator::GreaterEq => ">=",
BinaryOperator::Less => "<",
BinaryOperator::Greater => ">",
BinaryOperator::Plus => "+",
BinaryOperator::Minus => "-",
BinaryOperator::Mul => "*",
BinaryOperator::Div => "/",
BinaryOperator::Mod => "%",
BinaryOperator::And => "&&",
BinaryOperator::Or => "||",
}
}
pub fn precedence(self) -> u8 {
match self {
BinaryOperator::Mul | BinaryOperator::Div | BinaryOperator::Mod => 6,
BinaryOperator::Plus | BinaryOperator::Minus => 5,
BinaryOperator::LessEq
| BinaryOperator::GreaterEq
| BinaryOperator::Less
| BinaryOperator::Greater => 4,
BinaryOperator::Eq | BinaryOperator::NotEq => 3,
BinaryOperator::And => 2,
BinaryOperator::Or => 1,
}
}
}
impl fmt::Display for BinaryOperator {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl FromStr for BinaryOperator {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"==" => Ok(BinaryOperator::Eq),
"!=" => Ok(BinaryOperator::NotEq),
"<=" => Ok(BinaryOperator::LessEq),
">=" => Ok(BinaryOperator::GreaterEq),
"<" => Ok(BinaryOperator::Less),
">" => Ok(BinaryOperator::Greater),
"+" => Ok(BinaryOperator::Plus),
"-" => Ok(BinaryOperator::Minus),
"*" => Ok(BinaryOperator::Mul),
"/" => Ok(BinaryOperator::Div),
"%" => Ok(BinaryOperator::Mod),
"&&" => Ok(BinaryOperator::And),
"||" => Ok(BinaryOperator::Or),
_ => Err(Error::new(format!("invalid binary operator: `{s}`"))),
}
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for UnaryOperator {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for BinaryOperator {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for UnaryOperator {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(crate::de::FromStrVisitor::<Self>::new("unary operator"))
}
}
#[cfg(feature = "serde")]
impl<'de> serde::de::IntoDeserializer<'de, Error> for UnaryOperator {
type Deserializer = serde::de::value::StrDeserializer<'static, Error>;
fn into_deserializer(self) -> Self::Deserializer {
self.as_str().into_deserializer()
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for BinaryOperator {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_any(crate::de::FromStrVisitor::<Self>::new("binary operator"))
}
}
#[cfg(feature = "serde")]
impl<'de> serde::de::IntoDeserializer<'de, Error> for BinaryOperator {
type Deserializer = serde::de::value::StrDeserializer<'static, Error>;
fn into_deserializer(self) -> Self::Deserializer {
self.as_str().into_deserializer()
}
}