1use std::sync::Arc;
4
5use crate::error::ValueTypeError;
6
7#[derive(Debug, Clone)]
10pub enum Value {
11 Null,
12 Bool(bool),
13 I8(i8),
14 I16(i16),
15 I32(i32),
16 I64(i64),
17 U8(u8),
18 U16(u16),
19 U32(u32),
20 U64(u64),
21 F32(f32),
22 F64(f64),
23 String(Arc<str>),
24 Bytes(Arc<[u8]>),
25 Struct(Vec<Value>),
26 List(Vec<Value>),
27 Array(Vec<Value>),
28 Map(Vec<(Value, Value)>),
29}
30
31impl Value {
32 pub fn string(s: impl AsRef<str>) -> Self {
33 Self::String(Arc::from(s.as_ref()))
34 }
35
36 pub fn try_i8(&self) -> Result<Option<i8>, ValueTypeError> {
37 match self {
38 Value::I8(v) => Ok(Some(*v)),
39 Value::Null => Ok(None),
40 _ => Err(self.type_mismatch("I8")),
41 }
42 }
43
44 pub fn try_i16(&self) -> Result<Option<i16>, ValueTypeError> {
45 match self {
46 Value::I16(v) => Ok(Some(*v)),
47 Value::Null => Ok(None),
48 _ => Err(self.type_mismatch("I16")),
49 }
50 }
51
52 pub fn try_i32(&self) -> Result<Option<i32>, ValueTypeError> {
53 match self {
54 Value::I32(v) => Ok(Some(*v)),
55 Value::Null => Ok(None),
56 _ => Err(self.type_mismatch("I32")),
57 }
58 }
59
60 pub fn try_i64(&self) -> Result<Option<i64>, ValueTypeError> {
61 match self {
62 Value::I64(v) => Ok(Some(*v)),
63 Value::Null => Ok(None),
64 _ => Err(self.type_mismatch("I64")),
65 }
66 }
67
68 pub fn try_u8(&self) -> Result<Option<u8>, ValueTypeError> {
69 match self {
70 Value::U8(v) => Ok(Some(*v)),
71 Value::Null => Ok(None),
72 _ => Err(self.type_mismatch("U8")),
73 }
74 }
75
76 pub fn try_u16(&self) -> Result<Option<u16>, ValueTypeError> {
77 match self {
78 Value::U16(v) => Ok(Some(*v)),
79 Value::Null => Ok(None),
80 _ => Err(self.type_mismatch("U16")),
81 }
82 }
83
84 pub fn try_u32(&self) -> Result<Option<u32>, ValueTypeError> {
85 match self {
86 Value::U32(v) => Ok(Some(*v)),
87 Value::Null => Ok(None),
88 _ => Err(self.type_mismatch("U32")),
89 }
90 }
91
92 pub fn try_u64(&self) -> Result<Option<u64>, ValueTypeError> {
93 match self {
94 Value::U64(v) => Ok(Some(*v)),
95 Value::Null => Ok(None),
96 _ => Err(self.type_mismatch("U64")),
97 }
98 }
99
100 pub fn try_bool(&self) -> Result<Option<bool>, ValueTypeError> {
101 match self {
102 Value::Bool(v) => Ok(Some(*v)),
103 Value::Null => Ok(None),
104 _ => Err(self.type_mismatch("Bool")),
105 }
106 }
107
108 pub fn try_f32(&self) -> Result<Option<f32>, ValueTypeError> {
109 match self {
110 Value::F32(v) => Ok(Some(*v)),
111 Value::Null => Ok(None),
112 _ => Err(self.type_mismatch("F32")),
113 }
114 }
115
116 pub fn try_f64(&self) -> Result<Option<f64>, ValueTypeError> {
117 match self {
118 Value::F64(v) => Ok(Some(*v)),
119 Value::Null => Ok(None),
120 _ => Err(self.type_mismatch("F64")),
121 }
122 }
123
124 pub fn try_str(&self) -> Result<Option<&str>, ValueTypeError> {
125 match self {
126 Value::String(v) => Ok(Some(v.as_ref())),
127 Value::Null => Ok(None),
128 _ => Err(self.type_mismatch("String")),
129 }
130 }
131
132 pub fn try_bytes(&self) -> Result<Option<&[u8]>, ValueTypeError> {
133 match self {
134 Value::Bytes(v) => Ok(Some(v.as_ref())),
135 Value::Null => Ok(None),
136 _ => Err(self.type_mismatch("Bytes")),
137 }
138 }
139
140 pub fn type_mismatch(&self, expected: impl Into<String>) -> ValueTypeError {
141 ValueTypeError::new(expected, self.variant_name())
142 }
143
144 fn variant_name(&self) -> &'static str {
145 match self {
146 Value::Null => "Null",
147 Value::Bool(_) => "Bool",
148 Value::I8(_) => "I8",
149 Value::I16(_) => "I16",
150 Value::I32(_) => "I32",
151 Value::I64(_) => "I64",
152 Value::U8(_) => "U8",
153 Value::U16(_) => "U16",
154 Value::U32(_) => "U32",
155 Value::U64(_) => "U64",
156 Value::F32(_) => "F32",
157 Value::F64(_) => "F64",
158 Value::String(_) => "String",
159 Value::Bytes(_) => "Bytes",
160 Value::Struct(_) => "Struct",
161 Value::List(_) => "List",
162 Value::Array(_) => "Array",
163 Value::Map(_) => "Map",
164 }
165 }
166}