1 use crate::result::FResult;
2 use crate::value::Expr;
3 use crate::value::Ident;
4 use crate::value::Scope;
5 use crate::FendError;
6 use crate::{Deserialize, Serialize};
7 use std::{fmt, io};
8 
9 use std::sync::Arc;
10 
11 use crate::value::Value;
12 
13 #[derive(Copy, Clone, Eq, PartialEq, Debug)]
14 pub(crate) enum BuiltInFunction {
15 	Approximately,
16 	Abs,
17 	Sin,
18 	Cos,
19 	Tan,
20 	Asin,
21 	Acos,
22 	Atan,
23 	Sinh,
24 	Cosh,
25 	Tanh,
26 	Asinh,
27 	Acosh,
28 	Atanh,
29 	Ln,
30 	Log2,
31 	Log10,
32 	Base,
33 	Sample,
34 	Mean,
35 	Not,
36 	Conjugate,
37 	Real,
38 	Imag,
39 	Arg,
40 	Floor,
41 	Ceil,
42 	Round,
43 }
44 
45 impl BuiltInFunction {
wrap_with_expr( self, lazy_fn: impl FnOnce(Box<Expr>) -> Expr, scope: Option<Arc<Scope>>, ) -> Value46 	pub(crate) fn wrap_with_expr(
47 		self,
48 		lazy_fn: impl FnOnce(Box<Expr>) -> Expr,
49 		scope: Option<Arc<Scope>>,
50 	) -> Value {
51 		Value::Fn(
52 			Ident::new_str("x"),
53 			Box::new(lazy_fn(Box::new(Expr::ApplyFunctionCall(
54 				Box::new(Expr::Ident(Ident::new_str(self.as_str()))),
55 				Box::new(Expr::Ident(Ident::new_str("x"))),
56 			)))),
57 			scope,
58 		)
59 	}
60 
invert(self) -> FResult<Value>61 	pub(crate) fn invert(self) -> FResult<Value> {
62 		Ok(match self {
63 			Self::Sin => Value::BuiltInFunction(Self::Asin),
64 			Self::Cos => Value::BuiltInFunction(Self::Acos),
65 			Self::Tan => Value::BuiltInFunction(Self::Atan),
66 			Self::Asin => Value::BuiltInFunction(Self::Sin),
67 			Self::Acos => Value::BuiltInFunction(Self::Cos),
68 			Self::Atan => Value::BuiltInFunction(Self::Tan),
69 			Self::Sinh => Value::BuiltInFunction(Self::Asinh),
70 			Self::Cosh => Value::BuiltInFunction(Self::Acosh),
71 			Self::Tanh => Value::BuiltInFunction(Self::Atanh),
72 			Self::Asinh => Value::BuiltInFunction(Self::Sinh),
73 			Self::Acosh => Value::BuiltInFunction(Self::Cosh),
74 			Self::Atanh => Value::BuiltInFunction(Self::Tanh),
75 			_ => return Err(FendError::UnableToInvertFunction(self.as_str())),
76 		})
77 	}
78 
as_str(self) -> &'static str79 	pub(crate) const fn as_str(self) -> &'static str {
80 		match self {
81 			Self::Approximately => "approximately",
82 			Self::Abs => "abs",
83 			Self::Sin => "sin",
84 			Self::Cos => "cos",
85 			Self::Tan => "tan",
86 			Self::Asin => "asin",
87 			Self::Acos => "acos",
88 			Self::Atan => "atan",
89 			Self::Sinh => "sinh",
90 			Self::Cosh => "cosh",
91 			Self::Tanh => "tanh",
92 			Self::Asinh => "asinh",
93 			Self::Acosh => "acosh",
94 			Self::Atanh => "atanh",
95 			Self::Ln => "ln",
96 			Self::Log2 => "log2",
97 			Self::Log10 => "log10",
98 			Self::Base => "base",
99 			Self::Sample => "sample",
100 			Self::Mean => "mean",
101 			Self::Not => "not",
102 			Self::Conjugate => "conjugate",
103 			Self::Real => "real",
104 			Self::Imag => "imag",
105 			Self::Arg => "arg",
106 			Self::Floor => "floor",
107 			Self::Ceil => "ceil",
108 			Self::Round => "round",
109 		}
110 	}
111 
try_from_str(s: &str) -> FResult<Self>112 	fn try_from_str(s: &str) -> FResult<Self> {
113 		Ok(match s {
114 			"approximately" => Self::Approximately,
115 			"abs" => Self::Abs,
116 			"sin" => Self::Sin,
117 			"cos" => Self::Cos,
118 			"tan" => Self::Tan,
119 			"asin" => Self::Asin,
120 			"acos" => Self::Acos,
121 			"atan" => Self::Atan,
122 			"sinh" => Self::Sinh,
123 			"cosh" => Self::Cosh,
124 			"tanh" => Self::Tanh,
125 			"asinh" => Self::Asinh,
126 			"acosh" => Self::Acosh,
127 			"atanh" => Self::Atanh,
128 			"ln" => Self::Ln,
129 			"log2" => Self::Log2,
130 			"log10" => Self::Log10,
131 			"base" => Self::Base,
132 			"sample" => Self::Sample,
133 			"not" => Self::Not,
134 			"conjugate" => Self::Conjugate,
135 			"real" => Self::Real,
136 			"imag" => Self::Imag,
137 			_ => return Err(FendError::DeserializationError),
138 		})
139 	}
140 
serialize(self, write: &mut impl io::Write) -> FResult<()>141 	pub(crate) fn serialize(self, write: &mut impl io::Write) -> FResult<()> {
142 		self.as_str().serialize(write)
143 	}
144 
deserialize(read: &mut impl io::Read) -> FResult<Self>145 	pub(crate) fn deserialize(read: &mut impl io::Read) -> FResult<Self> {
146 		Self::try_from_str(String::deserialize(read)?.as_str())
147 	}
148 }
149 
150 impl fmt::Display for BuiltInFunction {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result151 	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 		write!(f, "{}", self.as_str())
153 	}
154 }
155