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::rpc::KeyValue;
24use crate::snapshot::FileFormat;
25
26#[derive(Debug, PartialEq, Serialize, Deserialize)]
28pub(crate) struct Document {
29 metadata: Metadata,
30 content: Content,
31}
32
33impl Document {
34 pub fn new(metadata: Metadata, content: Content) -> Self {
36 Self { metadata, content }
37 }
38
39 fn serialize_to_flexbuffer(&self) -> Result<Vec<u8>> {
40 let mut builder = FlexbufferSerializer::new();
41 self.serialize(&mut builder)
42 .context(SerializeFlexbuffersSnafu)?;
43 Ok(builder.take_buffer())
44 }
45
46 pub(crate) fn to_bytes(&self, format: &FileFormat) -> Result<Vec<u8>> {
48 match format {
49 FileFormat::FlexBuffers => self.serialize_to_flexbuffer(),
50 }
51 }
52
53 fn deserialize_from_flexbuffer(data: &[u8]) -> Result<Self> {
54 let reader = Reader::get_root(data).context(ReadFlexbuffersSnafu)?;
55 Document::deserialize(reader).context(DeserializeFlexbuffersSnafu)
56 }
57
58 pub(crate) fn from_slice(format: &FileFormat, data: &[u8]) -> Result<Self> {
60 match format {
61 FileFormat::FlexBuffers => Self::deserialize_from_flexbuffer(data),
62 }
63 }
64
65 pub(crate) fn into_metadata_content(self) -> Result<MetadataContent> {
67 match self.content {
68 Content::Metadata(metadata) => Ok(metadata),
69 }
70 }
71}
72
73#[derive(Debug, PartialEq, Serialize, Deserialize)]
75pub(crate) struct Metadata {
76 created_timestamp_mills: i64,
78}
79
80impl Metadata {
81 pub fn new() -> Self {
85 Self {
86 created_timestamp_mills: current_time_millis(),
87 }
88 }
89}
90
91#[derive(Debug, PartialEq, Serialize, Deserialize)]
93pub(crate) enum Content {
94 Metadata(MetadataContent),
95}
96
97#[derive(Debug, PartialEq, Serialize, Deserialize)]
99pub(crate) struct MetadataContent {
100 values: Vec<KeyValue>,
101}
102
103impl MetadataContent {
104 pub fn new(values: impl IntoIterator<Item = KeyValue>) -> Self {
106 Self {
107 values: values.into_iter().collect(),
108 }
109 }
110
111 pub fn into_iter(self) -> impl Iterator<Item = KeyValue> {
113 self.values.into_iter()
114 }
115
116 pub fn values(self) -> Vec<KeyValue> {
118 self.values
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_document() {
128 let document = Document::new(
129 Metadata::new(),
130 Content::Metadata(MetadataContent::new(vec![KeyValue {
131 key: b"key".to_vec(),
132 value: b"value".to_vec(),
133 }])),
134 );
135
136 let bytes = document.to_bytes(&FileFormat::FlexBuffers).unwrap();
137 let document_deserialized = Document::from_slice(&FileFormat::FlexBuffers, &bytes).unwrap();
138 assert_eq!(
139 document.metadata.created_timestamp_mills,
140 document_deserialized.metadata.created_timestamp_mills
141 );
142 assert_eq!(document.content, document_deserialized.content);
143 }
144}