serde_fleece/
dict.rs

1use couchbase_lite_core_sys::{FLValue_AsString, FLValue_GetType};
2
3use crate::{
4    ffi::{
5        FLDict, FLDict_Get, FLError, FLMutableDict_New, FLMutableDict_Release,
6        FLMutableDict_SetInt, FLMutableDict_SetString, FLSlice, FLValueType, FLValue_AsData,
7        _FLDict, _FLValue,
8    },
9    Error, NonNullConst,
10};
11use std::{borrow::Borrow, marker::PhantomData, ptr::NonNull};
12
13#[repr(transparent)]
14pub struct MutableDict(NonNull<_FLDict>);
15
16impl MutableDict {
17    #[inline]
18    pub fn new() -> Result<Self, Error> {
19        let dict = unsafe { FLMutableDict_New() };
20        NonNull::new(dict)
21            .ok_or(Error::Fleece(FLError::kFLMemoryError))
22            .map(MutableDict)
23    }
24    #[inline]
25    pub fn set_string(&mut self, key: &str, value: &str) {
26        unsafe { FLMutableDict_SetString(self.0.as_ptr(), key.into(), value.into()) };
27    }
28    #[inline]
29    pub fn set_i64(&mut self, key: &str, value: i64) {
30        unsafe { FLMutableDict_SetInt(self.0.as_ptr(), key.into(), value) };
31    }
32    #[inline]
33    pub fn as_dict(&self) -> NonNullConst<_FLDict> {
34        self.0.into()
35    }
36    #[inline]
37    pub fn as_fleece_slice(&self) -> FLSlice {
38        let value: NonNull<_FLValue> = self.0.cast();
39        unsafe { FLValue_AsData(value.as_ptr()) }
40    }
41}
42
43impl Drop for MutableDict {
44    #[inline]
45    fn drop(&mut self) {
46        unsafe { FLMutableDict_Release(self.0.as_ptr()) };
47    }
48}
49
50pub struct Dict<'a> {
51    inner: NonNullConst<_FLDict>,
52    marker: PhantomData<&'a FLDict>,
53}
54
55impl<'a> Dict<'a> {
56    #[inline]
57    pub fn new(dict: &FLDict) -> Option<Self> {
58        let inner = NonNullConst::new(*dict)?;
59        Some(Self {
60            inner,
61            marker: PhantomData,
62        })
63    }
64    pub fn get_as_str(&self, prop_name: &str) -> Option<&str> {
65        let val = unsafe { FLDict_Get(self.inner.as_ptr(), prop_name.into()) };
66        let val = NonNullConst::new(val)?;
67        if unsafe { FLValue_GetType(val.as_ptr()) } == FLValueType::kFLString {
68            let raw_s = unsafe { FLValue_AsString(val.as_ptr()) };
69            raw_s.try_into().ok()
70        } else {
71            None
72        }
73    }
74}
75
76impl<'a> Borrow<NonNullConst<_FLDict>> for Dict<'a> {
77    #[inline]
78    fn borrow(&self) -> &NonNullConst<_FLDict> {
79        &self.inner
80    }
81}