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)]
20#[repr(u64)]
21#[bitflags]
22pub enum Typ {
23 U8 = 0x0000_0001,
24 I8 = 0x0000_0002,
25 U16 = 0x0000_0004,
26 I16 = 0x0000_0008,
27 U32 = 0x0000_0010,
28 V32 = 0x0000_0020,
29 I32 = 0x0000_0040,
30 Z32 = 0x0000_0080,
31 U64 = 0x0000_0100,
32 V64 = 0x0000_0200,
33 I64 = 0x0000_0400,
34 Z64 = 0x0000_0800,
35 F32 = 0x0000_1000,
36 F64 = 0x0000_2000,
37 Bool = 0x0000_4000,
38 Null = 0x0000_8000,
39 String = 0x8000_0000,
40 Bytes = 0x4000_0000,
41 Error = 0x2000_0000,
42 Array = 0x1000_0000,
43 Map = 0x0800_0000,
44 Decimal = 0x0400_0000,
45 DateTime = 0x0200_0000,
46 Duration = 0x0100_0000,
47 Abstract = 0x0080_0000,
48}
49
50impl Typ {
51 pub fn parse(&self, s: &str) -> anyhow::Result<Value> {
52 match self {
53 Typ::U8 => Ok(Value::U8(s.parse::<u8>()?)),
54 Typ::I8 => Ok(Value::I8(s.parse::<i8>()?)),
55 Typ::U16 => Ok(Value::U16(s.parse::<u16>()?)),
56 Typ::I16 => Ok(Value::I16(s.parse::<i16>()?)),
57 Typ::U32 => Ok(Value::U32(s.parse::<u32>()?)),
58 Typ::V32 => Ok(Value::V32(s.parse::<u32>()?)),
59 Typ::I32 => Ok(Value::I32(s.parse::<i32>()?)),
60 Typ::Z32 => Ok(Value::Z32(s.parse::<i32>()?)),
61 Typ::U64 => Ok(Value::U64(s.parse::<u64>()?)),
62 Typ::V64 => Ok(Value::V64(s.parse::<u64>()?)),
63 Typ::I64 => Ok(Value::I64(s.parse::<i64>()?)),
64 Typ::Z64 => Ok(Value::Z64(s.parse::<i64>()?)),
65 Typ::F32 => Ok(Value::F32(s.parse::<f32>()?)),
66 Typ::F64 => Ok(Value::F64(s.parse::<f64>()?)),
67 Typ::Decimal => Ok(Value::Decimal(Arc::new(s.parse::<Decimal>()?))),
68 Typ::DateTime => Ok(Value::DateTime(Arc::new(DateTime::from_str(s)?))),
69 Typ::Duration => {
70 let mut tmp = String::from("duration:");
71 tmp.push_str(s);
72 Ok(tmp.parse::<Value>()?)
73 }
74 Typ::Bool => Ok(Value::Bool(s.parse::<bool>()?)),
75 Typ::String => Ok(Value::String(ArcStr::from(s))),
76 Typ::Bytes => {
77 let mut tmp = String::from("bytes:");
78 tmp.push_str(s);
79 Ok(tmp.parse::<Value>()?)
80 }
81 Typ::Error => Ok(s.parse::<Value>()?),
82 Typ::Array => Ok(s.parse::<Value>()?),
83 Typ::Map => Ok(s.parse::<Value>()?),
84 Typ::Null => {
85 if s.trim() == "null" {
86 Ok(Value::Null)
87 } else {
88 bail!("expected null")
89 }
90 }
91 Typ::Abstract => {
92 let mut tmp = String::from("abstract:");
93 tmp.push_str(s);
94 Ok(tmp.parse::<Value>()?)
95 }
96 }
97 }
98
99 pub fn name(&self) -> &'static str {
100 match self {
101 Typ::U8 => "u8",
102 Typ::I8 => "i8",
103 Typ::U16 => "u16",
104 Typ::I16 => "i16",
105 Typ::U32 => "u32",
106 Typ::V32 => "v32",
107 Typ::I32 => "i32",
108 Typ::Z32 => "z32",
109 Typ::U64 => "u64",
110 Typ::I64 => "i64",
111 Typ::V64 => "v64",
112 Typ::Z64 => "z64",
113 Typ::F32 => "f32",
114 Typ::F64 => "f64",
115 Typ::Decimal => "decimal",
116 Typ::DateTime => "datetime",
117 Typ::Duration => "duration",
118 Typ::Bool => "bool",
119 Typ::String => "string",
120 Typ::Bytes => "bytes",
121 Typ::Error => "error",
122 Typ::Array => "array",
123 Typ::Map => "map",
124 Typ::Null => "null",
125 Typ::Abstract => "abstract",
126 }
127 }
128
129 pub fn get(v: &Value) -> Self {
130 unsafe { mem::transmute::<u64, Typ>(v.discriminant()) }
133 }
134
135 pub fn any() -> BitFlags<Typ> {
136 BitFlags::all()
137 }
138
139 pub fn number() -> BitFlags<Typ> {
140 Typ::U8
141 | Typ::I8
142 | Typ::U16
143 | Typ::I16
144 | Typ::U32
145 | Typ::V32
146 | Typ::I32
147 | Typ::Z32
148 | Typ::U64
149 | Typ::V64
150 | Typ::I64
151 | Typ::Z64
152 | Typ::F32
153 | Typ::F64
154 | Typ::Decimal
155 }
156
157 pub fn is_number(&self) -> bool {
158 Self::number().contains(*self)
159 }
160
161 pub fn integer() -> BitFlags<Typ> {
162 Typ::U8
163 | Typ::I8
164 | Typ::U16
165 | Typ::I16
166 | Typ::U32
167 | Typ::V32
168 | Typ::I32
169 | Typ::Z32
170 | Typ::U64
171 | Typ::V64
172 | Typ::I64
173 | Typ::Z64
174 }
175
176 pub fn is_integer(&self) -> bool {
177 Self::integer().contains(*self)
178 }
179
180 pub fn signed_integer() -> BitFlags<Typ> {
181 Typ::I8 | Typ::I16 | Typ::I32 | Typ::Z32 | Typ::I64 | Typ::Z64
182 }
183
184 pub fn is_signed_integer(&self) -> bool {
185 Self::signed_integer().contains(*self)
186 }
187
188 pub fn unsigned_integer() -> BitFlags<Typ> {
189 Typ::U8 | Typ::U16 | Typ::U32 | Typ::V32 | Typ::U64 | Typ::V64
190 }
191
192 pub fn is_unsigned_integer(&self) -> bool {
193 Self::unsigned_integer().contains(*self)
194 }
195
196 pub fn float() -> BitFlags<Typ> {
197 Typ::F32 | Typ::F64
198 }
199
200 pub fn real() -> BitFlags<Typ> {
201 Typ::F32 | Typ::F64 | Typ::Decimal
202 }
203
204 pub fn is_real(&self) -> bool {
205 Self::real().contains(*self)
206 }
207}
208
209impl FromStr for Typ {
210 type Err = anyhow::Error;
211
212 fn from_str(s: &str) -> result::Result<Self, Self::Err> {
213 match s {
214 "U8" | "u8" => Ok(Typ::U8),
215 "I8" | "i8" => Ok(Typ::I8),
216 "U16" | "u16" => Ok(Typ::U16),
217 "I16" | "i16" => Ok(Typ::I16),
218 "U32" | "u32" => Ok(Typ::U32),
219 "V32" | "v32" => Ok(Typ::V32),
220 "I32" | "i32" => Ok(Typ::I32),
221 "Z32" | "z32" => Ok(Typ::Z32),
222 "U64" | "u64" => Ok(Typ::U64),
223 "V64" | "v64" => Ok(Typ::V64),
224 "I64" | "i64" => Ok(Typ::I64),
225 "Z64" | "z64" => Ok(Typ::Z64),
226 "F32" | "f32" => Ok(Typ::F32),
227 "F64" | "f64" => Ok(Typ::F64),
228 "Decimal" | "decimal" => Ok(Typ::Decimal),
229 "DateTime" | "datetime" => Ok(Typ::DateTime),
230 "Duration" | "duration" => Ok(Typ::Duration),
231 "Bool" | "bool" => Ok(Typ::Bool),
232 "String" | "string" => Ok(Typ::String),
233 "Bytes" | "bytes" => Ok(Typ::Bytes),
234 "Error" | "error" => Ok(Typ::Error),
235 "Array" | "array" => Ok(Typ::Array),
236 "Map" | "map" => Ok(Typ::Map),
237 "Null" | "null" => Ok(Typ::Null),
238 "Abstract" | "abstract" => Ok(Typ::Abstract),
239 s => Err(anyhow!(
240 "invalid type, {}, valid types: u32, i32, u64, i64, f32, f64, bool, string, bytes, error, array, map, null", s))
241 }
242 }
243}
244
245impl fmt::Display for Typ {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 write!(f, "{}", self.name())
248 }
249}