1use crate::Value;
2use anyhow::{anyhow, bail};
3use arcstr::ArcStr;
4use chrono::prelude::*;
5use enumflags2::{bitflags, BitFlags};
6use rust_decimal::Decimal;
7use serde::{Deserialize, Serialize};
8use std::{
9 cmp::{PartialEq, PartialOrd},
10 fmt, mem, result,
11 str::FromStr,
12};
13use triomphe::Arc;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
18#[repr(u32)]
19#[bitflags]
20pub enum Typ {
21 U32 = 0x0000_0001,
22 V32 = 0x0000_0002,
23 I32 = 0x0000_0004,
24 Z32 = 0x0000_0008,
25 U64 = 0x0000_0010,
26 V64 = 0x0000_0020,
27 I64 = 0x0000_0040,
28 Z64 = 0x0000_0080,
29 F32 = 0x0000_0100,
30 F64 = 0x0000_0200,
31 Bool = 0x0000_0400,
32 Null = 0x0000_0800,
33 String = 0x8000_0000,
34 Bytes = 0x4000_0000,
35 Error = 0x2000_0000,
36 Array = 0x1000_0000,
37 Map = 0x0800_0000,
38 Decimal = 0x0400_0000,
39 DateTime = 0x0200_0000,
40 Duration = 0x0100_0000,
41}
42
43impl Typ {
44 pub fn parse(&self, s: &str) -> anyhow::Result<Value> {
45 match self {
46 Typ::U32 => Ok(Value::U32(s.parse::<u32>()?)),
47 Typ::V32 => Ok(Value::V32(s.parse::<u32>()?)),
48 Typ::I32 => Ok(Value::I32(s.parse::<i32>()?)),
49 Typ::Z32 => Ok(Value::Z32(s.parse::<i32>()?)),
50 Typ::U64 => Ok(Value::U64(s.parse::<u64>()?)),
51 Typ::V64 => Ok(Value::V64(s.parse::<u64>()?)),
52 Typ::I64 => Ok(Value::I64(s.parse::<i64>()?)),
53 Typ::Z64 => Ok(Value::Z64(s.parse::<i64>()?)),
54 Typ::F32 => Ok(Value::F32(s.parse::<f32>()?)),
55 Typ::F64 => Ok(Value::F64(s.parse::<f64>()?)),
56 Typ::Decimal => Ok(Value::Decimal(Arc::new(s.parse::<Decimal>()?))),
57 Typ::DateTime => Ok(Value::DateTime(Arc::new(DateTime::from_str(s)?))),
58 Typ::Duration => {
59 let mut tmp = String::from("duration:");
60 tmp.push_str(s);
61 Ok(tmp.parse::<Value>()?)
62 }
63 Typ::Bool => Ok(Value::Bool(s.parse::<bool>()?)),
64 Typ::String => Ok(Value::String(ArcStr::from(s))),
65 Typ::Bytes => {
66 let mut tmp = String::from("bytes:");
67 tmp.push_str(s);
68 Ok(tmp.parse::<Value>()?)
69 }
70 Typ::Error => Ok(s.parse::<Value>()?),
71 Typ::Array => Ok(s.parse::<Value>()?),
72 Typ::Map => Ok(s.parse::<Value>()?),
73 Typ::Null => {
74 if s.trim() == "null" {
75 Ok(Value::Null)
76 } else {
77 bail!("expected null")
78 }
79 }
80 }
81 }
82
83 pub fn name(&self) -> &'static str {
84 match self {
85 Typ::U32 => "u32",
86 Typ::V32 => "v32",
87 Typ::I32 => "i32",
88 Typ::Z32 => "z32",
89 Typ::U64 => "u64",
90 Typ::I64 => "i64",
91 Typ::V64 => "v64",
92 Typ::Z64 => "z64",
93 Typ::F32 => "f32",
94 Typ::F64 => "f64",
95 Typ::Decimal => "decimal",
96 Typ::DateTime => "datetime",
97 Typ::Duration => "duration",
98 Typ::Bool => "bool",
99 Typ::String => "string",
100 Typ::Bytes => "bytes",
101 Typ::Error => "error",
102 Typ::Array => "array",
103 Typ::Map => "map",
104 Typ::Null => "null",
105 }
106 }
107
108 pub fn get(v: &Value) -> Self {
109 unsafe { mem::transmute::<u32, Typ>(v.discriminant()) }
112 }
113
114 pub fn any() -> BitFlags<Typ> {
115 BitFlags::all()
116 }
117
118 pub fn number() -> BitFlags<Typ> {
119 Typ::U32
120 | Typ::V32
121 | Typ::I32
122 | Typ::Z32
123 | Typ::U64
124 | Typ::V64
125 | Typ::I64
126 | Typ::Z64
127 | Typ::F32
128 | Typ::F64
129 | Typ::Decimal
130 }
131
132 pub fn is_number(&self) -> bool {
133 Self::number().contains(*self)
134 }
135
136 pub fn integer() -> BitFlags<Typ> {
137 Typ::U32
138 | Typ::V32
139 | Typ::I32
140 | Typ::Z32
141 | Typ::U64
142 | Typ::V64
143 | Typ::I64
144 | Typ::Z64
145 }
146
147 pub fn is_integer(&self) -> bool {
148 Self::integer().contains(*self)
149 }
150
151 pub fn signed_integer() -> BitFlags<Typ> {
152 Typ::I32 | Typ::Z32 | Typ::I64 | Typ::Z64
153 }
154
155 pub fn is_signed_integer(&self) -> bool {
156 Self::signed_integer().contains(*self)
157 }
158
159 pub fn unsigned_integer() -> BitFlags<Typ> {
160 Typ::U32 | Typ::V32 | Typ::U64 | Typ::V64
161 }
162
163 pub fn is_unsigned_integer(&self) -> bool {
164 Self::unsigned_integer().contains(*self)
165 }
166
167 pub fn float() -> BitFlags<Typ> {
168 Typ::F32 | Typ::F64
169 }
170
171 pub fn real() -> BitFlags<Typ> {
172 Typ::F32 | Typ::F64 | Typ::Decimal
173 }
174
175 pub fn is_real(&self) -> bool {
176 Self::real().contains(*self)
177 }
178}
179
180impl FromStr for Typ {
181 type Err = anyhow::Error;
182
183 fn from_str(s: &str) -> result::Result<Self, Self::Err> {
184 match s {
185 "U32" | "u32" => Ok(Typ::U32),
186 "V32" | "v32" => Ok(Typ::V32),
187 "I32" | "i32" => Ok(Typ::I32),
188 "Z32" | "z32" => Ok(Typ::Z32),
189 "U64" | "u64" => Ok(Typ::U64),
190 "V64" | "v64" => Ok(Typ::V64),
191 "I64" | "i64" => Ok(Typ::I64),
192 "Z64" | "z64" => Ok(Typ::Z64),
193 "F32" | "f32" => Ok(Typ::F32),
194 "F64" | "f64" => Ok(Typ::F64),
195 "Decimal" | "decimal" => Ok(Typ::Decimal),
196 "DateTime" | "datetime" => Ok(Typ::DateTime),
197 "Duration" | "duration" => Ok(Typ::Duration),
198 "Bool" | "bool" => Ok(Typ::Bool),
199 "String" | "string" => Ok(Typ::String),
200 "Bytes" | "bytes" => Ok(Typ::Bytes),
201 "Error" | "error" => Ok(Typ::Error),
202 "Array" | "array" => Ok(Typ::Array),
203 "Map" | "map" => Ok(Typ::Map),
204 "Null" | "null" => Ok(Typ::Null),
205 s => Err(anyhow!(
206 "invalid type, {}, valid types: u32, i32, u64, i64, f32, f64, bool, string, bytes, error, array, map, null", s))
207 }
208 }
209}
210
211impl fmt::Display for Typ {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 write!(f, "{}", self.name())
214 }
215}