1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use_prelude!();
use crate::error::{DittoError, ErrorKind};
#[derive(Debug, Clone, Default, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct DocumentId {
pub(crate) bytes: Vec<u8>,
}
impl DocumentId {
pub fn new<V: ::serde::Serialize>(value: &V) -> Result<Self, DittoError> {
use ::safer_ffi::prelude::{AsOut, ManuallyDropMut};
let cbor_bytes = ::serde_cbor::to_vec(value).unwrap();
let mut out_cbor_slot = None;
let out_cbor = out_cbor_slot.manually_drop_mut().as_out();
unsafe {
let res = ffi_sdk::ditto_validate_document_id((&cbor_bytes[..]).into(), out_cbor);
if res != 0 {
return Err(DittoError::from_ffi(ErrorKind::Internal));
}
}
let bytes = match out_cbor_slot {
None => cbor_bytes,
Some(cbor_boxed_slice) => cbor_boxed_slice.as_slice().to_vec(),
};
Ok(Self { bytes })
}
pub fn to_query_compatible(
&self,
string_primitive_fmt: ffi_sdk::StringPrimitiveFormat,
) -> String {
unsafe {
let str_boxed = ffi_sdk::ditto_document_id_query_compatible(
self.bytes.as_slice().into(),
string_primitive_fmt,
);
str_boxed.to_str().to_owned()
}
}
pub fn value(&self) -> ::serde_cbor::Value {
self.to_cbor()
}
pub fn to_cbor(&self) -> ::serde_cbor::Value {
::serde_cbor::from_slice(&self.bytes[..]).expect("DocumentId can be represented as CBOR")
}
}
impl From<Vec<u8>> for DocumentId {
fn from(bytes: Vec<u8>) -> Self {
Self { bytes }
}
}
impl From<Box<[u8]>> for DocumentId {
fn from(bytes: Box<[u8]>) -> Self {
Self {
bytes: bytes.into(),
}
}
}
impl From<&[u8]> for DocumentId {
fn from(slice: &[u8]) -> Self {
Self {
bytes: slice.to_owned().to_vec(),
}
}
}
impl AsRef<[u8]> for DocumentId {
fn as_ref(&self) -> &[u8] {
&self.bytes[..]
}
}
impl std::fmt::Display for DocumentId {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"{}",
self.to_query_compatible(ffi_sdk::StringPrimitiveFormat::WithoutQuotes)
)
}
}
impl serde::Serialize for DocumentId {
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let s: serde_cbor::Value = serde_cbor::from_slice(&self.bytes[..]).unwrap();
s.serialize(serializer)
}
}
impl<'de> serde::de::Deserialize<'de> for DocumentId {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::de::Deserializer<'de>,
{
Ok(Self {
bytes: serde_cbor::to_vec(&serde_cbor::Value::deserialize(deserializer)?).unwrap(),
})
}
}