|
1 | | -/// `JSArgType` is a 1:1 mapping of [`quaint::ValueType`] that: |
2 | | -/// - only includes the type tag (e.g. `Int32`, `Text`, `Enum`, etc.) |
3 | | -/// - doesn't care for the optionality of the actual value (e.g., `quaint::Value::Int32(None)` -> `JSArgType::Int32`) |
4 | | -/// - is used to guide the JS side on how to serialize the query argument value before sending it to the JS driver. |
5 | 1 | #[derive(Debug, PartialEq)] |
6 | | -pub enum JSArgType { |
7 | | - /// 32-bit signed integer. |
8 | | - Int32, |
9 | | - /// 64-bit signed integer. |
10 | | - Int64, |
11 | | - /// 32-bit floating point. |
| 2 | +pub struct JSArgType { |
| 3 | + pub scalar_type: JSArgScalarType, |
| 4 | + pub db_type: Option<String>, |
| 5 | + pub arity: JSArgArity, |
| 6 | +} |
| 7 | + |
| 8 | +#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 9 | +pub enum JSArgScalarType { |
| 10 | + String, |
| 11 | + Int, |
| 12 | + BigInt, |
12 | 13 | Float, |
13 | | - /// 64-bit floating point. |
14 | | - Double, |
15 | | - /// String value. |
16 | | - Text, |
17 | | - /// Database enum value. |
18 | | - Enum, |
19 | | - /// Database enum array (PostgreSQL specific). |
20 | | - EnumArray, |
21 | | - /// Bytes value. |
22 | | - Bytes, |
23 | | - /// Boolean value. |
| 14 | + Decimal, |
24 | 15 | Boolean, |
25 | | - /// A single character. |
26 | | - Char, |
27 | | - /// An array value (PostgreSQL). |
28 | | - Array, |
29 | | - /// A numeric value. |
30 | | - Numeric, |
31 | | - /// A JSON value. |
32 | | - Json, |
33 | | - /// A XML value. |
34 | | - Xml, |
35 | | - /// An UUID value. |
| 16 | + Enum, |
36 | 17 | Uuid, |
37 | | - /// A datetime value. |
| 18 | + Json, |
38 | 19 | DateTime, |
39 | | - /// A date value. |
40 | | - Date, |
41 | | - /// A time value. |
42 | | - Time, |
| 20 | + Bytes, |
| 21 | + Unknown, |
43 | 22 | } |
44 | 23 |
|
45 | | -impl core::fmt::Display for JSArgType { |
46 | | - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
47 | | - let s = match self { |
48 | | - JSArgType::Int32 => "Int32", |
49 | | - JSArgType::Int64 => "Int64", |
50 | | - JSArgType::Float => "Float", |
51 | | - JSArgType::Double => "Double", |
52 | | - JSArgType::Text => "Text", |
53 | | - JSArgType::Enum => "Enum", |
54 | | - JSArgType::EnumArray => "EnumArray", |
55 | | - JSArgType::Bytes => "Bytes", |
56 | | - JSArgType::Boolean => "Boolean", |
57 | | - JSArgType::Char => "Char", |
58 | | - JSArgType::Array => "Array", |
59 | | - JSArgType::Numeric => "Numeric", |
60 | | - JSArgType::Json => "Json", |
61 | | - JSArgType::Xml => "Xml", |
62 | | - JSArgType::Uuid => "Uuid", |
63 | | - JSArgType::DateTime => "DateTime", |
64 | | - JSArgType::Date => "Date", |
65 | | - JSArgType::Time => "Time", |
66 | | - }; |
| 24 | +impl From<JSArgScalarType> for &'static str { |
| 25 | + fn from(arg: JSArgScalarType) -> Self { |
| 26 | + match arg { |
| 27 | + JSArgScalarType::String => "string", |
| 28 | + JSArgScalarType::Int => "int", |
| 29 | + JSArgScalarType::BigInt => "bigint", |
| 30 | + JSArgScalarType::Float => "float", |
| 31 | + JSArgScalarType::Decimal => "decimal", |
| 32 | + JSArgScalarType::Boolean => "boolean", |
| 33 | + JSArgScalarType::Enum => "enum", |
| 34 | + JSArgScalarType::Uuid => "uuid", |
| 35 | + JSArgScalarType::Json => "json", |
| 36 | + JSArgScalarType::DateTime => "datetime", |
| 37 | + JSArgScalarType::Bytes => "bytes", |
| 38 | + JSArgScalarType::Unknown => "unknown", |
| 39 | + } |
| 40 | + } |
| 41 | +} |
| 42 | + |
| 43 | +#[derive(Debug, Clone, Copy, PartialEq, Eq)] |
| 44 | +pub enum JSArgArity { |
| 45 | + Scalar, |
| 46 | + List, |
| 47 | +} |
67 | 48 |
|
68 | | - write!(f, "{s}") |
| 49 | +impl From<JSArgArity> for &'static str { |
| 50 | + fn from(arg: JSArgArity) -> Self { |
| 51 | + match arg { |
| 52 | + JSArgArity::Scalar => "scalar", |
| 53 | + JSArgArity::List => "list", |
| 54 | + } |
69 | 55 | } |
70 | 56 | } |
71 | 57 |
|
72 | 58 | pub fn value_to_js_arg_type(value: &quaint::Value) -> JSArgType { |
| 59 | + JSArgType { |
| 60 | + scalar_type: value_to_js_arg_scalar_type(value), |
| 61 | + db_type: value.native_column_type_name().map(|nt| nt.to_string()), |
| 62 | + arity: if matches!( |
| 63 | + value.typed, |
| 64 | + quaint::ValueType::Array(_) | quaint::ValueType::EnumArray(_, _) |
| 65 | + ) { |
| 66 | + JSArgArity::List |
| 67 | + } else { |
| 68 | + JSArgArity::Scalar |
| 69 | + }, |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +fn value_to_js_arg_scalar_type(value: &quaint::Value) -> JSArgScalarType { |
73 | 74 | match &value.typed { |
74 | | - quaint::ValueType::Int32(_) => JSArgType::Int32, |
75 | | - quaint::ValueType::Int64(_) => JSArgType::Int64, |
76 | | - quaint::ValueType::Float(_) => JSArgType::Float, |
77 | | - quaint::ValueType::Double(_) => JSArgType::Double, |
78 | | - quaint::ValueType::Text(_) => JSArgType::Text, |
79 | | - quaint::ValueType::Enum(_, _) => JSArgType::Enum, |
80 | | - quaint::ValueType::EnumArray(_, _) => JSArgType::EnumArray, |
81 | | - quaint::ValueType::Bytes(_) => JSArgType::Bytes, |
82 | | - quaint::ValueType::Boolean(_) => JSArgType::Boolean, |
83 | | - quaint::ValueType::Char(_) => JSArgType::Char, |
84 | | - quaint::ValueType::Array(_) => JSArgType::Array, |
85 | | - quaint::ValueType::Numeric(_) => JSArgType::Numeric, |
86 | | - quaint::ValueType::Json(_) => JSArgType::Json, |
87 | | - quaint::ValueType::Xml(_) => JSArgType::Xml, |
88 | | - quaint::ValueType::Uuid(_) => JSArgType::Uuid, |
89 | | - quaint::ValueType::DateTime(_) => JSArgType::DateTime, |
90 | | - quaint::ValueType::Date(_) => JSArgType::Date, |
91 | | - quaint::ValueType::Time(_) => JSArgType::Time, |
| 75 | + quaint::ValueType::Int32(_) => JSArgScalarType::Int, |
| 76 | + quaint::ValueType::Int64(_) => JSArgScalarType::BigInt, |
| 77 | + quaint::ValueType::Float(_) => JSArgScalarType::Float, |
| 78 | + quaint::ValueType::Double(_) => JSArgScalarType::Float, |
| 79 | + quaint::ValueType::Text(_) | quaint::ValueType::Char(_) | quaint::ValueType::Xml(_) => JSArgScalarType::String, |
| 80 | + quaint::ValueType::Enum(_, _) | quaint::ValueType::EnumArray(_, _) => JSArgScalarType::Enum, |
| 81 | + quaint::ValueType::Bytes(_) => JSArgScalarType::Bytes, |
| 82 | + quaint::ValueType::Boolean(_) => JSArgScalarType::Boolean, |
| 83 | + quaint::ValueType::Array(vals) => vals |
| 84 | + .as_deref() |
| 85 | + .unwrap_or_default() |
| 86 | + .first() |
| 87 | + .map_or(JSArgScalarType::Unknown, value_to_js_arg_scalar_type), |
| 88 | + quaint::ValueType::Numeric(_) => JSArgScalarType::Decimal, |
| 89 | + quaint::ValueType::Json(_) => JSArgScalarType::Json, |
| 90 | + quaint::ValueType::Uuid(_) => JSArgScalarType::Uuid, |
| 91 | + quaint::ValueType::DateTime(_) | quaint::ValueType::Date(_) | quaint::ValueType::Time(_) => { |
| 92 | + JSArgScalarType::DateTime |
| 93 | + } |
92 | 94 | quaint::ValueType::Opaque(_) => unreachable!("Opaque values are not supposed to be converted to JSON"), |
93 | 95 | } |
94 | 96 | } |
0 commit comments