1use std::{fmt, time::Duration};
2
3mod scalar;
5pub use self::scalar::{Type as ScalarType, Value as ScalarValue};
6
7pub trait ToValueType {
8 fn to_value_type(&self) -> ValueType;
9}
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13pub enum ValueType {
14 Scalar(ScalarType),
16
17 Duration,
19
20 String,
22
23 Bytes,
25}
26
27const TYPE_STR_DURATION: &str = "duration";
29const TYPE_STR_STRING: &str = "string";
30const TYPE_STR_BYTES: &str = "bytes";
31
32impl ValueType {
33 #[must_use]
34 pub const fn to_scalar(self) -> Option<ScalarType> {
35 match self {
36 Self::Scalar(s) => Some(s),
37 _ => None,
38 }
39 }
40
41 #[must_use]
42 pub const fn is_scalar(self) -> bool {
43 self.to_scalar().is_some()
44 }
45
46 #[must_use]
47 pub const fn from_scalar(scalar: ScalarType) -> Self {
48 Self::Scalar(scalar)
49 }
50
51 const fn as_str(self) -> &'static str {
52 match self {
53 Self::Scalar(s) => s.as_str(),
54 Self::Duration => TYPE_STR_DURATION,
55 Self::String => TYPE_STR_STRING,
56 Self::Bytes => TYPE_STR_BYTES,
57 }
58 }
59
60 #[must_use]
61 pub fn try_from_str(s: &str) -> Option<Self> {
62 ScalarType::try_from_str(s).map(Into::into).or(match s {
63 TYPE_STR_DURATION => Some(Self::Duration),
64 TYPE_STR_STRING => Some(Self::String),
65 TYPE_STR_BYTES => Some(Self::Bytes),
66 _ => None,
67 })
68 }
69}
70
71impl From<ScalarType> for ValueType {
72 fn from(from: ScalarType) -> Self {
73 Self::from_scalar(from)
74 }
75}
76
77impl fmt::Display for ValueType {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 f.write_str(self.as_str())
80 }
81}
82
83#[derive(Debug, Clone, PartialEq)]
89pub enum Value {
90 Scalar(ScalarValue),
94
95 Duration(Duration),
99
100 String(String),
104
105 Bytes(Vec<u8>),
109}
110
111impl From<Duration> for Value {
112 fn from(from: Duration) -> Value {
113 Self::Duration(from)
114 }
115}
116
117impl From<String> for Value {
118 fn from(from: String) -> Value {
119 Self::String(from)
120 }
121}
122
123impl From<Vec<u8>> for Value {
124 fn from(from: Vec<u8>) -> Value {
125 Self::Bytes(from)
126 }
127}
128
129impl Value {
130 #[must_use]
131 pub const fn to_type(&self) -> ValueType {
132 match self {
133 Self::Scalar(value) => ValueType::Scalar(value.to_type()),
134 Self::Duration(_) => ValueType::Duration,
135 Self::String(_) => ValueType::String,
136 Self::Bytes(_) => ValueType::Bytes,
137 }
138 }
139
140 #[must_use]
141 pub const fn to_scalar(&self) -> Option<ScalarValue> {
142 match self {
143 Self::Scalar(scalar) => Some(*scalar),
144 _ => None,
145 }
146 }
147
148 #[must_use]
149 pub const fn from_scalar(scalar: ScalarValue) -> Self {
150 Self::Scalar(scalar)
151 }
152
153 pub fn to_i32(&self) -> Option<i32> {
154 self.to_scalar().and_then(ScalarValue::to_i32)
155 }
156
157 pub fn to_u32(&self) -> Option<u32> {
158 self.to_scalar().and_then(ScalarValue::to_u32)
159 }
160
161 pub fn to_i64(&self) -> Option<i64> {
162 self.to_scalar().and_then(ScalarValue::to_i64)
163 }
164
165 pub fn to_u64(&self) -> Option<u64> {
166 self.to_scalar().and_then(ScalarValue::to_u64)
167 }
168
169 pub fn to_f32(&self) -> Option<f32> {
170 self.to_scalar().and_then(ScalarValue::to_f32)
171 }
172
173 pub fn to_f64(&self) -> Option<f64> {
174 self.to_scalar().and_then(ScalarValue::to_f64)
175 }
176}
177
178impl ToValueType for Value {
179 fn to_value_type(&self) -> ValueType {
180 self.to_type()
181 }
182}
183
184impl<S> From<S> for Value
185where
186 S: Into<ScalarValue>,
187{
188 fn from(from: S) -> Self {
189 Value::Scalar(from.into())
190 }
191}