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}