arti_rpcserver/objmap/
methods.rs1use derive_deftly::Deftly;
8use futures::FutureExt as _;
9use std::sync::Arc;
10use tor_rpcbase::{self as rpc, SingleIdResponse, templates::*};
11
12#[derive(Debug, serde::Deserialize, Deftly)]
17#[derive_deftly(DynMethod)]
18#[deftly(rpc(method_name = "rpc:release", bypass_method_dispatch))]
19struct RpcRelease {}
20
21impl rpc::RpcMethod for RpcRelease {
22 type Output = rpc::Nil;
23 type Update = rpc::NoUpdates;
24}
25
26impl rpc::DynMethod for RpcRelease {
27 fn invoke_without_dispatch(
28 &self,
29 ctx: Arc<dyn rpc::Context>,
30 obj_id: &rpc::ObjectId,
31 ) -> Result<tor_rpcbase::dispatch::RpcResultFuture, tor_rpcbase::InvokeError> {
32 let result = match ctx.release(obj_id) {
33 Ok(()) => Ok(Box::new(rpc::NIL) as _),
34 Err(e) => Err(rpc::RpcError::from(e)),
35 };
36 Ok(futures::future::ready(result).boxed())
37 }
38}
39
40#[derive(Debug, serde::Deserialize, Deftly)]
51#[derive_deftly(DynMethod)]
52#[deftly(rpc(method_name = "rpc:clone_id", bypass_method_dispatch))]
53struct RpcCloneId {
54 #[serde(default)]
59 weak: bool,
60
61 #[serde(default)]
63 release: bool,
64}
65
66impl rpc::RpcMethod for RpcCloneId {
67 type Output = rpc::SingleIdResponse;
68 type Update = rpc::NoUpdates;
69}
70
71impl rpc::DynMethod for RpcCloneId {
72 fn invoke_without_dispatch(
73 &self,
74 ctx: Arc<dyn rpc::Context>,
75 obj_id: &rpc::ObjectId,
76 ) -> Result<tor_rpcbase::dispatch::RpcResultFuture, tor_rpcbase::InvokeError> {
77 let result = match ctx.lookup_object(obj_id) {
78 Ok(obj) => {
79 let new_id = if self.weak {
80 ctx.register_weak(&obj)
81 } else {
82 ctx.register_owned(obj)
83 };
84 if self.release {
85 let _ignore = ctx.release(obj_id);
86 }
87 Ok(Box::new(SingleIdResponse::from(new_id)) as _)
88 }
89 Err(e) => Err(rpc::RpcError::from(e)),
90 };
91
92 Ok(futures::future::ready(result).boxed())
93 }
94}