dig_node_control_interface/
traits.rs1use async_trait::async_trait;
14use serde::de::DeserializeOwned;
15use serde::Serialize;
16use serde_json::Value;
17
18use crate::envelope::{JsonRpcRequest, JsonRpcResponse, RequestId};
19use crate::error::{ControlError, ControlErrorCode};
20use crate::method::ControlMethod;
21use crate::params;
22use crate::results;
23
24pub trait ControlCall: Serialize {
29 const METHOD: ControlMethod;
31 type Output: DeserializeOwned;
33}
34
35fn params_value<C: ControlCall>(call: &C) -> Value {
37 match serde_json::to_value(call) {
38 Ok(Value::Null) => Value::Object(Default::default()),
39 Ok(v) => v,
40 Err(_) => Value::Object(Default::default()),
41 }
42}
43
44pub fn build_request<C: ControlCall>(id: RequestId, call: &C) -> JsonRpcRequest {
46 JsonRpcRequest::new(id, C::METHOD.name(), params_value(call))
47}
48
49pub fn parse_response<C: ControlCall>(
51 response: JsonRpcResponse,
52) -> Result<C::Output, ControlError> {
53 let value = response.into_result()?;
54 serde_json::from_value(value).map_err(|e| {
55 ControlError::of(
56 ControlErrorCode::ControlError,
57 format!("failed to parse {} result: {e}", C::METHOD.name()),
58 )
59 })
60}
61
62pub trait ControlClient {
69 fn build_request<C: ControlCall>(&self, id: RequestId, call: &C) -> JsonRpcRequest {
71 build_request(id, call)
72 }
73
74 fn parse_response<C: ControlCall>(
76 &self,
77 response: JsonRpcResponse,
78 ) -> Result<C::Output, ControlError> {
79 parse_response::<C>(response)
80 }
81}
82
83#[derive(Debug, Clone, Copy, Default)]
85pub struct DefaultControlClient;
86
87impl ControlClient for DefaultControlClient {}
88
89#[async_trait]
98pub trait ControlHandler: Sync {
99 async fn status(&self) -> Result<results::StatusResult, ControlError>;
101 async fn config_get(&self) -> Result<results::ConfigResult, ControlError>;
103 async fn config_set_upstream(
105 &self,
106 params: params::SetUpstreamParams,
107 ) -> Result<results::SetUpstreamResult, ControlError>;
108 async fn log_set_level(
110 &self,
111 params: params::SetLevelParams,
112 ) -> Result<results::SetLevelResult, ControlError>;
113 async fn cache_get(&self) -> Result<results::CacheView, ControlError>;
115 async fn cache_set_cap(
117 &self,
118 params: params::SetCapParams,
119 ) -> Result<results::SetCapResult, ControlError>;
120 async fn cache_clear(&self) -> Result<results::CacheClearResult, ControlError>;
122 async fn hosted_stores_list(&self) -> Result<results::HostedStoresListResult, ControlError>;
124 async fn hosted_stores_pin(
126 &self,
127 params: params::PinParams,
128 ) -> Result<results::PinResult, ControlError>;
129 async fn hosted_stores_unpin(
131 &self,
132 params: params::UnpinParams,
133 ) -> Result<results::UnpinResult, ControlError>;
134 async fn hosted_stores_status(
136 &self,
137 params: params::HostedStoreStatusParams,
138 ) -> Result<results::HostedStoreStatusResult, ControlError>;
139 async fn sync_status(&self) -> Result<results::SyncStatusResult, ControlError>;
141 async fn sync_trigger(
143 &self,
144 params: params::SyncTriggerParams,
145 ) -> Result<results::SyncTriggerResult, ControlError>;
146 async fn updater_status(&self) -> Result<Value, ControlError>;
148 async fn updater_set_channel(
150 &self,
151 params: params::SetChannelParams,
152 ) -> Result<Value, ControlError>;
153 async fn updater_pause(&self, params: params::PauseParams) -> Result<Value, ControlError>;
155 async fn updater_resume(&self) -> Result<Value, ControlError>;
157 async fn updater_check_now(&self) -> Result<Value, ControlError>;
159 async fn pairing_list(&self) -> Result<Value, ControlError>;
161 async fn pairing_approve(
163 &self,
164 params: params::ApproveParams,
165 ) -> Result<results::PairingApproveResult, ControlError>;
166 async fn pairing_revoke(
168 &self,
169 params: params::RevokeParams,
170 ) -> Result<results::PairingRevokeResult, ControlError>;
171 async fn peer_status(&self) -> Result<Value, ControlError>;
173 async fn peers_connect(
175 &self,
176 params: params::PeersConnectParams,
177 ) -> Result<results::PeersConnectResult, ControlError>;
178 async fn peers_disconnect(
180 &self,
181 params: params::PeersDisconnectParams,
182 ) -> Result<results::PeersDisconnectResult, ControlError>;
183 async fn subscribe(
185 &self,
186 params: params::SubscribeParams,
187 ) -> Result<results::SubscribeResult, ControlError>;
188 async fn unsubscribe(
190 &self,
191 params: params::UnsubscribeParams,
192 ) -> Result<results::UnsubscribeResult, ControlError>;
193 async fn list_subscriptions(&self) -> Result<results::ListSubscriptionsResult, ControlError>;
195 async fn wallet_balance(
197 &self,
198 params: params::WalletBalanceParams,
199 ) -> Result<results::WalletBalanceResult, ControlError>;
200 async fn wallet_coins(
205 &self,
206 params: params::WalletCoinsParams,
207 ) -> Result<results::WalletCoinsResult, ControlError>;
208 async fn wallet_coin_by_id(
218 &self,
219 params: params::WalletCoinByIdParams,
220 ) -> Result<results::WalletCoinByIdResult, ControlError>;
221 async fn wallet_peak(&self) -> Result<results::WalletPeakResult, ControlError>;
223 async fn peer_counts(&self) -> Result<results::PeerCountsResult, ControlError>;
230 async fn wallet_sync_status(&self) -> Result<results::WalletSyncStatusResult, ControlError>;
237 async fn wallet_broadcast(
243 &self,
244 params: params::WalletBroadcastParams,
245 ) -> Result<results::WalletBroadcastResult, ControlError>;
246 async fn pairing_request(
248 &self,
249 params: params::RequestParams,
250 ) -> Result<results::PairingRequestResult, ControlError>;
251 async fn pairing_poll(
253 &self,
254 params: params::PollParams,
255 ) -> Result<results::PairingPollResult, ControlError>;
256
257 async fn dispatch(&self, request: JsonRpcRequest) -> JsonRpcResponse {
263 let id = request.id.clone();
264 let Some(method) = ControlMethod::from_name(&request.method) else {
265 return JsonRpcResponse::error(
266 id,
267 ControlError::of(
268 ControlErrorCode::MethodNotFound,
269 format!("unknown control method: {}", request.method),
270 ),
271 );
272 };
273 match self.dispatch_method(method, request.params).await {
274 Ok(result) => JsonRpcResponse::success(id, result),
275 Err(err) => JsonRpcResponse::error(id, err),
276 }
277 }
278
279 #[doc(hidden)]
282 async fn dispatch_method(
283 &self,
284 method: ControlMethod,
285 params: Value,
286 ) -> Result<Value, ControlError> {
287 fn decode<T: DeserializeOwned>(params: Value) -> Result<T, ControlError> {
289 serde_json::from_value(params)
290 .map_err(|e| ControlError::of(ControlErrorCode::InvalidParams, e.to_string()))
291 }
292 fn encode<T: Serialize>(value: T) -> Result<Value, ControlError> {
294 serde_json::to_value(value)
295 .map_err(|e| ControlError::of(ControlErrorCode::ControlError, e.to_string()))
296 }
297 match method {
298 ControlMethod::Status => encode(self.status().await?),
299 ControlMethod::ConfigGet => encode(self.config_get().await?),
300 ControlMethod::ConfigSetUpstream => {
301 encode(self.config_set_upstream(decode(params)?).await?)
302 }
303 ControlMethod::LogSetLevel => encode(self.log_set_level(decode(params)?).await?),
304 ControlMethod::CacheGet => encode(self.cache_get().await?),
305 ControlMethod::CacheSetCap => encode(self.cache_set_cap(decode(params)?).await?),
306 ControlMethod::CacheClear => encode(self.cache_clear().await?),
307 ControlMethod::HostedStoresList => encode(self.hosted_stores_list().await?),
308 ControlMethod::HostedStoresPin => {
309 encode(self.hosted_stores_pin(decode(params)?).await?)
310 }
311 ControlMethod::HostedStoresUnpin => {
312 encode(self.hosted_stores_unpin(decode(params)?).await?)
313 }
314 ControlMethod::HostedStoresStatus => {
315 encode(self.hosted_stores_status(decode(params)?).await?)
316 }
317 ControlMethod::SyncStatus => encode(self.sync_status().await?),
318 ControlMethod::SyncTrigger => encode(self.sync_trigger(decode(params)?).await?),
319 ControlMethod::UpdaterStatus => self.updater_status().await,
320 ControlMethod::UpdaterSetChannel => self.updater_set_channel(decode(params)?).await,
321 ControlMethod::UpdaterPause => self.updater_pause(decode(params)?).await,
322 ControlMethod::UpdaterResume => self.updater_resume().await,
323 ControlMethod::UpdaterCheckNow => self.updater_check_now().await,
324 ControlMethod::PairingList => self.pairing_list().await,
325 ControlMethod::PairingApprove => encode(self.pairing_approve(decode(params)?).await?),
326 ControlMethod::PairingRevoke => encode(self.pairing_revoke(decode(params)?).await?),
327 ControlMethod::PeerStatus => self.peer_status().await,
328 ControlMethod::PeerCounts => encode(self.peer_counts().await?),
329 ControlMethod::PeersConnect => encode(self.peers_connect(decode(params)?).await?),
330 ControlMethod::PeersDisconnect => encode(self.peers_disconnect(decode(params)?).await?),
331 ControlMethod::Subscribe => encode(self.subscribe(decode(params)?).await?),
332 ControlMethod::Unsubscribe => encode(self.unsubscribe(decode(params)?).await?),
333 ControlMethod::ListSubscriptions => encode(self.list_subscriptions().await?),
334 ControlMethod::WalletBalance => encode(self.wallet_balance(decode(params)?).await?),
335 ControlMethod::WalletCoins => encode(self.wallet_coins(decode(params)?).await?),
336 ControlMethod::WalletCoinById => {
338 let params: params::WalletCoinByIdParams = decode(params)?;
339 encode(self.wallet_coin_by_id(params.validated()?).await?)
340 }
341 ControlMethod::WalletPeak => encode(self.wallet_peak().await?),
342 ControlMethod::WalletSyncStatus => encode(self.wallet_sync_status().await?),
343 ControlMethod::WalletBroadcast => encode(self.wallet_broadcast(decode(params)?).await?),
344 ControlMethod::PairingRequest => encode(self.pairing_request(decode(params)?).await?),
345 ControlMethod::PairingPoll => encode(self.pairing_poll(decode(params)?).await?),
346 }
347 }
348}