aleph_types/message/
store.rs1use crate::cid::Cid;
2use crate::item_hash::{AlephItemHash, ItemHash};
3use crate::memory_size::Bytes;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[serde(tag = "item_type", rename_all = "lowercase")]
9pub enum StorageBackend {
10 Ipfs { item_hash: Cid },
11 Storage { item_hash: AlephItemHash },
12}
13
14#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
15pub struct StoreContent {
16 #[serde(flatten)]
17 file_hash: StorageBackend,
20 #[serde(default)]
21 pub size: Option<Bytes>,
23 pub content_type: Option<String>,
25 #[serde(rename = "ref", default)]
26 pub reference: Option<String>,
27 pub metadata: Option<HashMap<String, serde_json::Value>>,
29}
30
31impl StoreContent {
32 pub fn file_hash(&self) -> ItemHash {
33 match &self.file_hash {
34 StorageBackend::Ipfs { item_hash: cid } => ItemHash::Ipfs(cid.clone()),
35 StorageBackend::Storage { item_hash } => ItemHash::Native(*item_hash),
36 }
37 }
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use crate::chain::{Address, Chain, Signature};
44 use crate::channel::Channel;
45 use crate::item_hash;
46 use crate::message::base_message::{Message, MessageContentEnum};
47 use crate::message::{ContentSource, MessageType};
48 use crate::timestamp::Timestamp;
49 use assert_matches::assert_matches;
50
51 const STORE_IPFS_FIXTURE: &str = include_str!(concat!(
52 env!("CARGO_MANIFEST_DIR"),
53 "/../../fixtures/messages/store/store-ipfs.json"
54 ));
55
56 #[test]
57 fn test_deserialize_store_message() {
58 let message: Message = serde_json::from_str(STORE_IPFS_FIXTURE).unwrap();
59
60 assert_eq!(
61 message.sender,
62 Address::from("0x238224C744F4b90b4494516e074D2676ECfC6803".to_string())
63 );
64 assert_eq!(message.chain, Chain::Ethereum);
65 assert_eq!(
66 message.signature,
67 Signature::from(
68 "0x9c87f5d659b9165be7cbd4b9f0bd5df5c66b9bb9a384a0a33b1277428be21244595a0731697035c4b085064cd3fc088bc5b3cddeb22159e7f462e6e5b5e7e8181c".to_string()
69 )
70 );
71 assert_matches!(message.message_type, MessageType::Store);
72 assert_matches!(
73 message.content_source,
74 ContentSource::Inline { item_content: _ }
75 );
76 assert_eq!(
77 &message.item_hash.to_string(),
78 "afe106f1fd70b6b806e0452cc2f9485e518143581ffd046ae19fc64af7b6bbaa"
79 );
80 assert_eq!(message.time, Timestamp::from(1761047957.74837));
81 assert_matches!(message.channel, Some(ref channel) if channel == &Channel::from("ALEPH-CLOUDSOLUTIONS".to_string()));
82
83 assert_eq!(
85 &message.content.address,
86 &Address::from("0x238224C744F4b90b4494516e074D2676ECfC6803".to_string())
87 );
88 assert_eq!(&message.content.time, &Timestamp::from(1761047957.7483068));
89 assert_eq!(message.sent_at(), &message.content.time);
90
91 match message.content() {
93 MessageContentEnum::Store(store) => {
94 assert_eq!(
95 store.file_hash,
96 StorageBackend::Ipfs {
97 item_hash: Cid::try_from("QmYULJoNGPDmoRq4WNWTDTUvJGJv1hosox8H6vVd1kCsY8")
98 .unwrap()
99 }
100 );
101 assert_eq!(
102 store.file_hash(),
103 item_hash!("QmYULJoNGPDmoRq4WNWTDTUvJGJv1hosox8H6vVd1kCsY8")
104 );
105
106 assert!(store.size.is_none());
107 assert!(store.content_type.is_none());
108 assert!(store.reference.is_none());
109 assert!(store.metadata.is_none());
110 }
111 other => {
112 panic!("Expected MessageContentEnum::Store, got {:?}", other)
113 }
114 }
115
116 assert!(message.confirmed());
118 assert_eq!(message.confirmations.len(), 1);
119
120 let confirmation = &message.confirmations[0];
121 assert_eq!(confirmation.chain, Chain::Ethereum);
122 assert_eq!(confirmation.height, 23626206);
123 assert_eq!(
124 confirmation.hash,
125 "0x7e73ff97d7920fcfc289a899aeac4bc2898d1482a9876bd2ac4584ae876d22be"
126 );
127 assert!(confirmation.time.is_none());
128 assert!(confirmation.publisher.is_none());
129 }
130
131 #[test]
132 fn test_deserialize_serialized_store_message() {
133 let message: Message = serde_json::from_str(STORE_IPFS_FIXTURE).unwrap();
134 let serialized_message = serde_json::to_string(&message).unwrap();
135 let deserialized_message: Message = serde_json::from_str(&serialized_message).unwrap();
136
137 assert_eq!(message, deserialized_message);
138 }
139}