pastry_dht/
client.rs

1use tonic::transport::Channel;
2
3use crate::{
4    error::*,
5    internal::{
6        dht::service::grpc::{NodeServiceClient, QueryRequest, QueryType},
7        hring::hasher::Sha256Hasher,
8    },
9};
10
11/// A client for Pastry nodes.
12///
13#[derive(Clone)]
14pub struct PastryClient {
15    client: NodeServiceClient<Channel>,
16}
17
18impl PastryClient {
19    /// Connects to a node in the Pastry network.
20    ///
21    /// # Arguments
22    ///
23    /// * `address` - The public address of the node.
24    ///
25    /// # Returns
26    ///
27    /// Returns a `Result` containing the client.
28    ///
29    pub async fn connect(address: &str) -> Result<Self> {
30        Ok(PastryClient {
31            client: NodeServiceClient::connect(address.to_owned()).await?,
32        })
33    }
34
35    /// Retrieves a value associated with the given key stored in the Pastry
36    /// network.
37    ///
38    /// # Arguments
39    ///
40    /// * `key` - A slice of bytes representing the key for which the value is
41    /// requested.
42    ///
43    /// # Returns
44    ///
45    /// Returns a `Result` which is:
46    ///
47    /// - `Ok(Some(Vec<u8>))` if the key exists, containing the associated
48    /// value.
49    /// - `Ok(None)` if the key does not exist.
50    /// - `Err(e)` where `e` encapsulates any error encountered during the
51    /// operation.
52    ///
53    pub async fn get_kv(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
54        let response = self
55            .client
56            .query(QueryRequest {
57                from_id: 0,
58                matched_digits: 0,
59                hops: 0,
60                query_type: QueryType::Get.into(),
61                key: Sha256Hasher::hash_once(key),
62                value: None,
63            })
64            .await?
65            .into_inner();
66
67        Ok(response.value)
68    }
69
70    /// Sets a value for a given key in the Pastry network.
71    ///
72    /// # Arguments
73    ///
74    /// * `key` - A slice of bytes representing the key to which the value is
75    /// to be associated.
76    /// * `value` - A slice of bytes representing the value to be set.
77    ///
78    /// # Returns
79    ///
80    /// Returns a `Result` which is:
81    ///
82    /// - `Ok(Some(Vec<u8>))` if the key existed and the value was replaced,
83    /// containing the old value.
84    /// - `Ok(None)` if the key did not exist and a new entry was created.
85    /// - `Err(e)` where `e` encapsulates any error encountered during the
86    /// operation.
87    ///
88    pub async fn set_kv(&mut self, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>> {
89        let response = self
90            .client
91            .query(QueryRequest {
92                from_id: 0,
93                matched_digits: 0,
94                hops: 0,
95                query_type: QueryType::Set.into(),
96                key: Sha256Hasher::hash_once(key),
97                value: Some(value.to_vec()),
98            })
99            .await?
100            .into_inner();
101
102        Ok(response.value)
103    }
104
105    /// Deletes the value associated with the given key in the Pastry network.
106    ///
107    /// # Arguments
108    ///
109    /// * `key` - A slice of bytes representing the key whose associated value
110    /// is to be deleted.
111    ///
112    /// # Returns
113    ///
114    /// Returns a `Result` which is:
115    ///
116    /// - `Ok(Some(Vec<u8>))` if the key existed and the value was successfully deleted, containing the deleted value.
117    /// - `Ok(None)` if the key did not exist.
118    /// - `Err(e)` where `e` encapsulates any error encountered during the operation.
119    ///
120    pub async fn delete_kv(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
121        let response = self
122            .client
123            .query(QueryRequest {
124                from_id: 0,
125                matched_digits: 0,
126                hops: 0,
127                query_type: QueryType::Delete.into(),
128                key: Sha256Hasher::hash_once(key),
129                value: None,
130            })
131            .await?
132            .into_inner();
133
134        Ok(response.value)
135    }
136}