1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::entities::{CardanoDbBeacon, CompressionAlgorithm, Epoch};
5
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
8pub struct SnapshotMessage {
9 pub digest: String,
11
12 pub network: String,
14
15 pub beacon: CardanoDbBeacon,
17
18 pub certificate_hash: String,
20
21 pub size: u64,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub ancillary_size: Option<u64>,
27
28 pub created_at: DateTime<Utc>,
30
31 pub locations: Vec<String>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub ancillary_locations: Option<Vec<String>>,
37
38 pub compression_algorithm: CompressionAlgorithm,
40
41 pub cardano_node_version: String,
43}
44
45impl SnapshotMessage {
46 pub fn dummy() -> Self {
48 Self {
49 digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
50 network: "preview".to_string(),
51 beacon: CardanoDbBeacon {
52 epoch: Epoch(86),
53 immutable_file_number: 1728,
54 },
55 certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
56 .to_string(),
57 size: 807803196,
58 ancillary_size: Some(123456789),
59 created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
60 .unwrap()
61 .with_timezone(&Utc),
62 locations: vec!["https://host/certificate.tar.gz".to_string()],
63 ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
64 compression_algorithm: CompressionAlgorithm::Gzip,
65 cardano_node_version: "0.0.1".to_string(),
66 }
67 }
68
69 pub fn compute_total_size(&self) -> u64 {
71 self.size + self.ancillary_size.unwrap_or(0)
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
80 pub struct SnapshotMessageUntilV0_1_47 {
81 pub digest: String,
82 pub network: String,
83 pub beacon: CardanoDbBeacon,
84 pub certificate_hash: String,
85 pub size: u64,
86 pub created_at: DateTime<Utc>,
87 pub locations: Vec<String>,
88 pub compression_algorithm: CompressionAlgorithm,
89 pub cardano_node_version: String,
90 }
91
92 const CURRENT_JSON: &str = r#"{
93 "digest": "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6",
94 "network": "preview",
95 "beacon": {
96 "epoch": 86,
97 "immutable_file_number": 1728
98 },
99 "certificate_hash": "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb",
100 "size": 807803196,
101 "ancillary_size": 123456789,
102 "created_at": "2023-01-19T13:43:05.618857482Z",
103 "locations": [
104 "https://host/certificate.tar.gz"
105 ],
106 "ancillary_locations": [
107 "https://host/ancillary.tar.gz"
108 ],
109 "compression_algorithm": "gzip",
110 "cardano_node_version": "0.0.1"
111 }"#;
112
113 fn golden_message_until_open_api_0_1_47() -> SnapshotMessageUntilV0_1_47 {
114 SnapshotMessageUntilV0_1_47 {
115 digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
116 network: "preview".to_string(),
117 beacon: CardanoDbBeacon {
118 epoch: Epoch(86),
119 immutable_file_number: 1728,
120 },
121 certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
122 .to_string(),
123 size: 807803196,
124 created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
125 .unwrap()
126 .with_timezone(&Utc),
127 locations: vec!["https://host/certificate.tar.gz".to_string()],
128 compression_algorithm: CompressionAlgorithm::Gzip,
129 cardano_node_version: "0.0.1".to_string(),
130 }
131 }
132
133 fn golden_message_current() -> SnapshotMessage {
134 SnapshotMessage {
135 digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
136 network: "preview".to_string(),
137 beacon: CardanoDbBeacon {
138 epoch: Epoch(86),
139 immutable_file_number: 1728,
140 },
141 certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
142 .to_string(),
143 size: 807803196,
144 ancillary_size: Some(123456789),
145 created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
146 .unwrap()
147 .with_timezone(&Utc),
148 locations: vec!["https://host/certificate.tar.gz".to_string()],
149 ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
150 compression_algorithm: CompressionAlgorithm::Gzip,
151 cardano_node_version: "0.0.1".to_string(),
152 }
153 }
154
155 #[test]
156 fn test_current_json_deserialized_into_message_supported_until_open_api_0_1_47() {
157 let json = CURRENT_JSON;
158 let message: SnapshotMessageUntilV0_1_47 = serde_json::from_str(json).unwrap();
159
160 assert_eq!(golden_message_until_open_api_0_1_47(), message);
161 }
162
163 #[test]
164 fn test_current_json_deserialized_into_current_message() {
165 let json = CURRENT_JSON;
166 let message: SnapshotMessage = serde_json::from_str(json).unwrap();
167
168 assert_eq!(golden_message_current(), message);
169 }
170
171 #[test]
172 fn compute_total_size_with_ancillary_size() {
173 let message = SnapshotMessage {
174 size: 12,
175 ancillary_size: Some(33),
176 ..SnapshotMessage::dummy()
177 };
178
179 assert_eq!(message.compute_total_size(), 45);
180 }
181
182 #[test]
183 fn compute_total_size_without_ancillary_size() {
184 let message = SnapshotMessage {
185 size: 12,
186 ancillary_size: None,
187 ..SnapshotMessage::dummy()
188 };
189
190 assert_eq!(message.compute_total_size(), 12);
191 }
192}