1use crate::{
2 error::{Error, Result},
3 ffi::{
4 FLArray, FLArray_Count, FLArray_Get, FLArray_IsEmpty, FLDict, FLDict_Count, FLDict_Get,
5 FLDict_IsEmpty, FLSlice, FLValue, FLValueType, FLValue_AsArray, FLValue_AsBool,
6 FLValue_AsDict, FLValue_AsDouble, FLValue_AsFloat, FLValue_AsInt, FLValue_AsString,
7 FLValue_AsUnsigned, FLValue_GetType, FLValue_IsDouble, FLValue_IsInteger,
8 FLValue_IsUnsigned,
9 },
10};
11
12#[derive(Debug, Clone, Copy)]
13pub enum ValueRef<'a> {
14 Null,
15 Bool(bool),
16 SignedInt(i64),
17 UnsignedInt(u64),
18 Float(f32),
19 Double(f64),
20 String(&'a str),
21 Array(ValueRefArray),
22 Dict(ValueRefDict),
23}
24
25impl ValueRef<'_> {
26 #[inline]
27 pub fn as_bool(&self) -> Result<bool> {
28 FromValueRef::column_result(*self)
29 }
30 #[inline]
31 pub fn as_i32(&self) -> Result<i32> {
32 FromValueRef::column_result(*self)
33 }
34 #[inline]
35 pub fn as_i64(&self) -> Result<i64> {
36 FromValueRef::column_result(*self)
37 }
38 #[inline]
39 pub fn as_u64(&self) -> Result<u64> {
40 FromValueRef::column_result(*self)
41 }
42 #[inline]
43 pub fn as_f32(&self) -> Result<f32> {
44 FromValueRef::column_result(*self)
45 }
46 #[inline]
47 pub fn as_f64(&self) -> Result<f64> {
48 FromValueRef::column_result(*self)
49 }
50 #[inline]
51 pub fn as_str(&self) -> Result<&str> {
52 FromValueRef::column_result(*self)
53 }
54 #[inline]
55 pub fn is_null(&self) -> bool {
56 matches!(self, ValueRef::Null)
57 }
58 pub(crate) unsafe fn new(value: FLValue) -> Self {
59 use FLValueType::*;
60 match FLValue_GetType(value) {
61 kFLUndefined | kFLNull => ValueRef::Null,
62 kFLBoolean => ValueRef::Bool(FLValue_AsBool(value)),
63 kFLNumber => {
64 if FLValue_IsUnsigned(value) {
65 ValueRef::UnsignedInt(FLValue_AsUnsigned(value))
66 } else if FLValue_IsInteger(value) {
67 ValueRef::SignedInt(FLValue_AsInt(value))
68 } else if FLValue_IsDouble(value) {
69 ValueRef::Double(FLValue_AsDouble(value))
70 } else {
71 ValueRef::Float(FLValue_AsFloat(value))
72 }
73 }
74 kFLString => {
75 let s: &str = FLValue_AsString(value).try_into().expect("not valid utf-8");
76 ValueRef::String(s)
77 }
78 kFLArray => ValueRef::Array(ValueRefArray(FLValue_AsArray(value))),
79 kFLDict => ValueRef::Dict(ValueRefDict(FLValue_AsDict(value))),
80 kFLData => unimplemented!(),
81 }
82 }
83}
84
85#[derive(Debug, Clone, Copy)]
86#[repr(transparent)]
87pub struct ValueRefArray(FLArray);
88
89impl ValueRefArray {
90 #[inline]
91 pub fn len(&self) -> u32 {
92 unsafe { FLArray_Count(self.0) }
93 }
94 #[inline]
95 pub fn is_empty(&self) -> bool {
96 unsafe { FLArray_IsEmpty(self.0) }
97 }
98 pub(crate) unsafe fn get_raw(&self, idx: u32) -> FLValue {
99 FLArray_Get(self.0, idx)
100 }
101 #[inline]
102 pub fn get<'a>(&'a self, idx: u32) -> ValueRef<'a> {
103 unsafe { ValueRef::new(self.get_raw(idx)) }
104 }
105}
106
107#[derive(Debug, Clone, Copy)]
108#[repr(transparent)]
109pub struct ValueRefDict(FLDict);
110
111impl ValueRefDict {
112 #[inline]
113 pub fn len(&self) -> u32 {
114 unsafe { FLDict_Count(self.0) }
115 }
116 #[inline]
117 pub fn is_empty(&self) -> bool {
118 unsafe { FLDict_IsEmpty(self.0) }
119 }
120 pub(crate) unsafe fn get_raw(&self, key: FLSlice) -> FLValue {
121 FLDict_Get(self.0, key)
122 }
123 #[inline]
124 pub fn get<'a>(&'a self, key: FLSlice) -> ValueRef<'a> {
125 unsafe { ValueRef::new(self.get_raw(key)) }
126 }
127}
128
129pub trait FromValueRef<'a>: Sized {
130 fn column_result(val: ValueRef<'a>) -> Result<Self>;
131}
132
133impl<'a> FromValueRef<'a> for bool {
134 #[inline]
135 fn column_result(val: ValueRef<'a>) -> Result<Self> {
136 if let ValueRef::Bool(x) = val {
137 Ok(x)
138 } else {
139 Err(Error::LogicError(
140 format!("Wrong ValueRef type, expect Bool, got {val:?}").into(),
141 ))
142 }
143 }
144}
145
146impl<'a> FromValueRef<'a> for &'a str {
147 #[inline]
148 fn column_result(val: ValueRef<'a>) -> Result<Self> {
149 if let ValueRef::String(x) = val {
150 Ok(x)
151 } else {
152 Err(Error::LogicError(
153 format!("Wrong ValueRef type, expect String, got {val:?}").into(),
154 ))
155 }
156 }
157}
158
159impl<'a> FromValueRef<'a> for u16 {
160 fn column_result(val: ValueRef<'a>) -> Result<Self> {
161 match val {
162 ValueRef::SignedInt(x) => u16::try_from(x).map_err(|err| {
163 Error::LogicError(
164 format!("ValueRef(Signed) {x} to u16 conversation error: {err}").into(),
165 )
166 }),
167 ValueRef::UnsignedInt(x) => u16::try_from(x).map_err(|err| {
168 Error::LogicError(
169 format!("ValueRef(Unsigned) {x} to u16 conversation error: {err}").into(),
170 )
171 }),
172 _ => Err(Error::LogicError(
173 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (u16) got {val:?}")
174 .into(),
175 )),
176 }
177 }
178}
179
180impl<'a> FromValueRef<'a> for i32 {
181 fn column_result(val: ValueRef<'a>) -> Result<Self> {
182 match val {
183 ValueRef::SignedInt(val) => i32::try_from(val).map_err(|err| {
184 Error::LogicError(format!("i64->i32 conversation failure: {err}").into())
185 }),
186 ValueRef::UnsignedInt(val) => i32::try_from(val).map_err(|err| {
187 Error::LogicError(format!("u64->i32 conversation failure: {err}").into())
188 }),
189 _ => Err(Error::LogicError(
190 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (i32) got {val:?}")
191 .into(),
192 )),
193 }
194 }
195}
196
197impl<'a> FromValueRef<'a> for u32 {
198 fn column_result(val: ValueRef<'a>) -> Result<Self> {
199 match val {
200 ValueRef::SignedInt(x) => u32::try_from(x).map_err(|err| {
201 Error::LogicError(
202 format!("ValueRef(Signed) {x} to u32 conversation error: {err}").into(),
203 )
204 }),
205 ValueRef::UnsignedInt(x) => u32::try_from(x).map_err(|err| {
206 Error::LogicError(
207 format!("ValueRef(Unsigned) {x} to u32 conversation error: {err}").into(),
208 )
209 }),
210 _ => Err(Error::LogicError(
211 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (u32) got {val:?}")
212 .into(),
213 )),
214 }
215 }
216}
217
218impl<'a> FromValueRef<'a> for u64 {
219 fn column_result(val: ValueRef<'a>) -> Result<Self> {
220 match val {
221 ValueRef::SignedInt(x) => u64::try_from(x).map_err(|err| {
222 Error::LogicError(
223 format!("ValueRef(Signed) {x} to u32 conversation error: {err}").into(),
224 )
225 }),
226 ValueRef::UnsignedInt(x) => Ok(x),
227 _ => Err(Error::LogicError(
228 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (u64) got {val:?}")
229 .into(),
230 )),
231 }
232 }
233}
234
235impl<'a> FromValueRef<'a> for i64 {
236 fn column_result(val: ValueRef<'a>) -> Result<Self> {
237 match val {
238 ValueRef::SignedInt(x) => Ok(x),
239 ValueRef::UnsignedInt(x) => i64::try_from(x).map_err(|err| {
240 Error::LogicError(
241 format!("ValueRef (UnsignedInt) to i64 conversation failed: {err}").into(),
242 )
243 }),
244 _ => Err(Error::LogicError(
245 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (i64) got {val:?}")
246 .into(),
247 )),
248 }
249 }
250}
251
252impl<'a> FromValueRef<'a> for usize {
253 fn column_result(val: ValueRef<'a>) -> Result<Self> {
254 match val {
255 ValueRef::SignedInt(x) => usize::try_from(x).map_err(|err| {
256 Error::LogicError(
257 format!("ValueRef(Signed) {x} to usize conversation error: {err}").into(),
258 )
259 }),
260 ValueRef::UnsignedInt(x) => usize::try_from(x).map_err(|err| {
261 Error::LogicError(
262 format!("ValueRef(Unsigned) {x} to usize conversation error: {err}").into(),
263 )
264 }),
265 _ => Err(Error::LogicError(
266 format!("Wrong ValueRef type, expect SignedInt|UnsignedInt (usize) got {val:?}")
267 .into(),
268 )),
269 }
270 }
271}
272
273impl<'a> FromValueRef<'a> for f32 {
274 #[inline]
275 fn column_result(val: ValueRef<'a>) -> Result<Self> {
276 if let ValueRef::Float(x) = val {
277 Ok(x)
278 } else {
279 Err(Error::LogicError(
280 format!("Wrong ValueRef type, expect Float, got {val:?}").into(),
281 ))
282 }
283 }
284}
285
286impl<'a> FromValueRef<'a> for f64 {
287 #[inline]
288 fn column_result(val: ValueRef<'a>) -> Result<Self> {
289 match val {
290 ValueRef::Float(x) => Ok(f64::from(x)),
291 ValueRef::Double(x) => Ok(x),
292 _ => Err(Error::LogicError(
293 format!("Wrong ValueRef type, expect Float/Double, got {val:?}").into(),
294 )),
295 }
296 }
297}