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