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    pub fn values(self) -> Vec<KeyValue> {
117        self.values
118    }
119}
120
121#[derive(Debug, PartialEq, Serialize, Deserialize)]
123pub(crate) struct KeyValue {
124    pub key: Vec<u8>,
125    pub value: Vec<u8>,
126}
127
128#[cfg(test)]
129mod tests {
130    use super::*;
131
132    #[test]
133    fn test_document() {
134        let document = Document::new(
135            Metadata::new(),
136            Content::Metadata(MetadataContent::new(vec![KeyValue {
137                key: b"key".to_vec(),
138                value: b"value".to_vec(),
139            }])),
140        );
141
142        let bytes = document.to_bytes(&FileFormat::FlexBuffers).unwrap();
143        let document_deserialized = Document::from_slice(&FileFormat::FlexBuffers, &bytes).unwrap();
144        assert_eq!(
145            document.metadata.created_timestamp_mills,
146            document_deserialized.metadata.created_timestamp_mills
147        );
148        assert_eq!(document.content, document_deserialized.content);
149    }
150}