1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use {
	super::{AggregateOperator, BinaryOperator, FunctionOperator, RecipeError, UnaryOperator},
	crate::{Result, Value},
	sqlparser::ast::{BinaryOperator as AstBinaryOperator, UnaryOperator as AstUnaryOperator},
};

pub trait TryIntoMethod<MethodType> {
	fn into_method(self) -> Result<MethodType>;
}

impl TryIntoMethod<FunctionOperator> for String {
	fn into_method(self) -> Result<FunctionOperator> {
		match self.to_uppercase().as_str() {
			"CONVERT" => Ok(Value::function_convert),
			"TRY_CONVERT" => Ok(Value::function_try_convert),

			"UPPER" => Ok(Value::function_to_uppercase),
			"LOWER" => Ok(Value::function_to_lowercase),

			"LEFT" => Ok(Value::function_left),
			"RIGHT" => Ok(Value::function_right),

			"LEN" => Ok(Value::function_length),
			"CONCAT" => Ok(Value::function_concat),
			"REPLACE" => Ok(Value::function_replace),

			"NOW" => Ok(Value::function_now),

			"YEAR" => Ok(Value::function_year),
			"MONTH" => Ok(Value::function_month),
			"DAY" => Ok(Value::function_day),
			"HOUR" => Ok(Value::function_hour),
			"MINUTE" => Ok(Value::function_minute),
			"SECOND" => Ok(Value::function_second),

			"DATEADD" => Ok(Value::function_timestamp_add),
			"DATEFROMPARTS" => Ok(Value::function_timestamp_from_parts),

			"ROUND" => Ok(Value::function_round),
			"POW" => Ok(Value::function_pow),

			"RAND" => Ok(Value::function_rand),
			"UUID" => Ok(Value::function_rand),

			"IIF" => Ok(Value::function_iif),
			"IFNULL" => Ok(Value::function_if_null),
			"NULLIF" => Ok(Value::function_null_if),

			unimplemented => {
				Err(RecipeError::UnimplementedMethod(String::from(unimplemented)).into())
			}
		}
	}
}

impl TryIntoMethod<AggregateOperator> for String {
	fn into_method(self) -> Result<AggregateOperator> {
		match self.to_uppercase().as_str() {
			"COUNT" => Ok(Value::aggregate_count),
			"MIN" => Ok(Value::aggregate_min),
			"MAX" => Ok(Value::aggregate_max),
			"SUM" => Ok(Value::aggregate_sum),

			unimplemented => {
				Err(RecipeError::UnimplementedMethod(String::from(unimplemented)).into())
			}
		}
	}
}

impl TryIntoMethod<UnaryOperator> for AstUnaryOperator {
	fn into_method(self) -> Result<UnaryOperator> {
		match self {
			AstUnaryOperator::Plus => Ok(Value::generic_unary_plus),
			AstUnaryOperator::Minus => Ok(Value::generic_unary_minus),
			AstUnaryOperator::Not => Ok(Value::not),

			unimplemented => {
				Err(RecipeError::UnimplementedMethod(format!("{:?}", unimplemented)).into())
			}
		}
	}
}

impl TryIntoMethod<BinaryOperator> for AstBinaryOperator {
	fn into_method(self) -> Result<BinaryOperator> {
		match self {
			AstBinaryOperator::Plus => Ok(Value::generic_add),
			AstBinaryOperator::Minus => Ok(Value::generic_subtract),
			AstBinaryOperator::Multiply => Ok(Value::generic_multiply),
			AstBinaryOperator::Divide => Ok(Value::generic_divide),
			AstBinaryOperator::Modulo => Ok(Value::generic_modulus),

			AstBinaryOperator::And => Ok(Value::and),
			AstBinaryOperator::Or => Ok(Value::or),

			AstBinaryOperator::Eq => Ok(Value::eq),
			AstBinaryOperator::NotEq => Ok(Value::not_eq),
			AstBinaryOperator::Gt => Ok(Value::gt),
			AstBinaryOperator::GtEq => Ok(Value::gt_eq),
			AstBinaryOperator::Lt => Ok(Value::lt),
			AstBinaryOperator::LtEq => Ok(Value::lt_eq),

			AstBinaryOperator::StringConcat => Ok(Value::string_concat),

			unimplemented => {
				Err(RecipeError::UnimplementedMethod(format!("{:?}", unimplemented)).into())
			}
		}
	}
}