common_meta/snapshot/
file.rs1use common_time::util::current_time_millis;
16use flexbuffers::{FlexbufferSerializer, Reader};
17use serde::{Deserialize, Serialize};
18use snafu::ResultExt;
19
20use crate::error::{
21 DeserializeFlexbuffersSnafu, ReadFlexbuffersSnafu, Result, SerializeFlexbuffersSnafu,
22};
23use crate::snapshot::FileFormat;
24
25#[derive(Debug, PartialEq, Serialize, Deserialize)]
27pub(crate) struct Document {
28 metadata: Metadata,
29 content: Content,
30}
31
32impl Document {
33 pub fn new(metadata: Metadata, content: Content) -> Self {
35 Self { metadata, content }
36 }
37
38 fn serialize_to_flexbuffer(&self) -> Result<Vec<u8>> {
39 let mut builder = FlexbufferSerializer::new();
40 self.serialize(&mut builder)
41 .context(SerializeFlexbuffersSnafu)?;
42 Ok(builder.take_buffer())
43 }
44
45 pub(crate) fn to_bytes(&self, format: &FileFormat) -> Result<Vec<u8>> {
47 match format {
48 FileFormat::FlexBuffers => self.serialize_to_flexbuffer(),
49 }
50 }
51
52 fn deserialize_from_flexbuffer(data: &[u8]) -> Result<Self> {
53 let reader = Reader::get_root(data).context(ReadFlexbuffersSnafu)?;
54 Document::deserialize(reader).context(DeserializeFlexbuffersSnafu)
55 }
56
57 pub(crate) fn from_slice(format: &FileFormat, data: &[u8]) -> Result<Self> {
59 match format {
60 FileFormat::FlexBuffers => Self::deserialize_from_flexbuffer(data),
61 }
62 }
63
64 pub(crate) fn into_metadata_content(self) -> Result<MetadataContent> {
66 match self.content {
67 Content::Metadata(metadata) => Ok(metadata),
68 }
69 }
70}
71
72#[derive(Debug, PartialEq, Serialize, Deserialize)]
74pub(crate) struct Metadata {
75 created_timestamp_mills: i64,
77}
78
79impl Metadata {
80 pub fn new() -> Self {
84 Self {
85 created_timestamp_mills: current_time_millis(),
86 }
87 }
88}
89
90#[derive(Debug, PartialEq, Serialize, Deserialize)]
92pub(crate) enum Content {
93 Metadata(MetadataContent),
94}
95
96#[derive(Debug, PartialEq, Serialize, Deserialize)]
98pub(crate) struct MetadataContent {
99 values: Vec<KeyValue>,
100}
101
102impl MetadataContent {
103 pub fn new(values: impl IntoIterator<Item = KeyValue>) -> Self {
105 Self {
106 values: values.into_iter().collect(),
107 }
108 }
109
110 pub fn into_iter(self) -> impl Iterator<Item = KeyValue> {
112 self.values.into_iter()
113 }
114}
115
116#[derive(Debug, PartialEq, Serialize, Deserialize)]
118pub(crate) struct KeyValue {
119 pub key: Vec<u8>,
120 pub value: Vec<u8>,
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_document() {
129 let document = Document::new(
130 Metadata::new(),
131 Content::Metadata(MetadataContent::new(vec![KeyValue {
132 key: b"key".to_vec(),
133 value: b"value".to_vec(),
134 }])),
135 );
136
137 let bytes = document.to_bytes(&FileFormat::FlexBuffers).unwrap();
138 let document_deserialized = Document::from_slice(&FileFormat::FlexBuffers, &bytes).unwrap();
139 assert_eq!(
140 document.metadata.created_timestamp_mills,
141 document_deserialized.metadata.created_timestamp_mills
142 );
143 assert_eq!(document.content, document_deserialized.content);
144 }
145}