1use core::fmt;
2use std::str::FromStr;
3
4#[allow(unused_imports)]
5use crate::prelude::*;
6#[allow(unused_imports)]
7use serde::{Deserialize, Serialize};
8
9use crate::enum_with_variants_to_string;
10use crate::traits::ToLatex;
11
12enum_with_variants_to_string! {
13 pub enum Operator derives[Debug, PartialEq, Clone, Copy] with_wasm {
14 Add,
15 Sub,
16 Mul,
17 Div,
18 Neg,
19 }
20}
21impl Operator {
22 pub fn precedence(&self) -> u8 {
26 match self {
27 Operator::Add | Operator::Sub => 1,
28 Operator::Mul | Operator::Div => 2,
29 Operator::Neg => 3,
30 }
31 }
32
33 pub fn is_left_associative(&self) -> bool {
38 match self {
39 Operator::Add | Operator::Sub | Operator::Mul | Operator::Div => true,
40 Operator::Neg => false,
41 }
42 }
43}
44
45impl fmt::Display for Operator {
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 let s = match self {
48 Operator::Add => "+".to_string(),
49 Operator::Sub => "-".to_string(),
50 Operator::Mul => "*".to_string(),
51 Operator::Div => "/".to_string(),
52 Operator::Neg => "-".to_string(),
53 };
54
55 f.write_str(&s)
56 }
57}
58
59enum_with_variants_to_string! {
60 pub enum BinOp derives[Debug, PartialEq, Clone, Copy] with_wasm {
61 Add,
62 Sub,
63 Mul,
64 Div,
65 }
70}
71
72impl BinOp {
73 pub fn precedence(&self) -> u8 {
75 match self {
76 BinOp::Add | BinOp::Sub => 1,
77 BinOp::Mul | BinOp::Div => 2,
78 }
79 }
80
81 pub fn is_left_associative(&self) -> bool {
83 match self {
84 BinOp::Add | BinOp::Sub | BinOp::Mul | BinOp::Div => true,
85 }
86 }
87
88 pub fn to_operator(&self) -> Operator {
90 match self {
91 BinOp::Add => Operator::Add,
92 BinOp::Sub => Operator::Sub,
93 BinOp::Mul => Operator::Mul,
94 BinOp::Div => Operator::Div,
95 }
96 }
97}
98
99impl ToLatex for BinOp {
100 fn to_latex(&self) -> String {
101 match self {
102 BinOp::Add => "+".to_string(),
103 BinOp::Sub => "-".to_string(),
104 BinOp::Mul => "\\cdot".to_string(),
105 BinOp::Div => "\\div".to_string(),
106 }
107 }
108}
109
110impl fmt::Display for BinOp {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 let s = match self {
113 BinOp::Add => "+".to_string(),
114 BinOp::Sub => "-".to_string(),
115 BinOp::Mul => "*".to_string(),
116 BinOp::Div => "/".to_string(),
117 };
118
119 f.write_str(&s)
120 }
121}
122
123impl FromStr for BinOp {
124 type Err = ();
125 fn from_str(s: &str) -> Result<Self, Self::Err> {
126 match s {
127 "+" => Ok(BinOp::Add),
128 "-" => Ok(BinOp::Sub),
129 "*" => Ok(BinOp::Mul),
130 "/" => Ok(BinOp::Div),
131 _ => Err(()),
132 }
133 }
134}
135
136enum_with_variants_to_string! {
137 pub enum UnOp derives[Debug, PartialEq, Clone, Copy] with_wasm {
138 Neg,
139 }
140}
141
142impl UnOp {
143 pub fn precedence(&self) -> u8 {
145 match self {
146 UnOp::Neg => 3,
147 }
148 }
149
150 pub fn is_left_associative(&self) -> bool {
152 match self {
153 UnOp::Neg => false,
154 }
155 }
156
157 pub fn to_operator(&self) -> Operator {
159 match self {
160 UnOp::Neg => Operator::Neg,
161 }
162 }
163}
164
165impl ToLatex for UnOp {
166 fn to_latex(&self) -> String {
167 match self {
168 UnOp::Neg => "-".to_string(),
169 }
170 }
171}
172
173impl fmt::Display for UnOp {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 let s = match self {
176 UnOp::Neg => "-".to_string(),
177 };
178
179 f.write_str(&s)
180 }
181}
182
183impl FromStr for UnOp {
184 type Err = ();
185 fn from_str(s: &str) -> Result<Self, Self::Err> {
186 match s {
187 "-" => Ok(UnOp::Neg),
188 _ => Err(()),
189 }
190 }
191}