p2p_chat/storage/
friends.rs1use crate::crypto::StorageEncryption;
3use crate::types::Friend;
4use anyhow::Result;
5use async_trait::async_trait;
6use libp2p::PeerId;
7use sled::Db;
8
9#[async_trait]
11pub trait FriendsStore {
12 async fn add_friend(&self, friend: Friend) -> Result<()>;
22
23 async fn get_friend(&self, peer_id: &PeerId) -> Result<Option<Friend>>;
37
38 async fn list_friends(&self) -> Result<Vec<Friend>>;
48}
49
50pub struct SledFriendsStore {
52 tree: sled::Tree,
53 encryption: Option<StorageEncryption>,
54}
55
56impl SledFriendsStore {
57 pub fn new(db: Db, encryption: Option<StorageEncryption>) -> Result<Self> {
68 let tree = db.open_tree("friends")?;
69 Ok(Self { tree, encryption })
70 }
71
72 fn serialize_friend(&self, friend: &Friend) -> Result<Vec<u8>> {
74 let serialized = serde_json::to_vec(friend)?;
75
76 if let Some(ref encryption) = self.encryption {
77 encryption.encrypt_value(&serialized)
78 } else {
79 Ok(serialized)
80 }
81 }
82
83 fn deserialize_friend(&self, data: &[u8]) -> Result<Friend> {
85 let decrypted = if let Some(ref encryption) = self.encryption {
86 encryption.decrypt_value(data)?
87 } else {
88 data.to_vec()
89 };
90
91 Ok(serde_json::from_slice(&decrypted)?)
92 }
93}
94
95#[async_trait]
96impl FriendsStore for SledFriendsStore {
97 async fn add_friend(&self, friend: Friend) -> Result<()> {
98 let key = friend.peer_id.to_bytes();
99 let value = self.serialize_friend(&friend)?;
100 self.tree.insert(key, value)?;
101 self.tree.flush_async().await?;
102 Ok(())
103 }
104
105 async fn get_friend(&self, peer_id: &PeerId) -> Result<Option<Friend>> {
106 let key = peer_id.to_bytes();
107 match self.tree.get(key)? {
108 Some(data) => Ok(Some(self.deserialize_friend(&data)?)),
109 None => Ok(None),
110 }
111 }
112
113 async fn list_friends(&self) -> Result<Vec<Friend>> {
114 let mut friends = Vec::new();
115
116 for result in self.tree.iter() {
117 let (_key, value) = result?;
118 friends.push(self.deserialize_friend(&value)?);
119 }
120
121 Ok(friends)
122 }
123}