secretspec_ipc/
resolver.rs1use crate::error::{ErrorKind, RpcError};
2use crate::protocol::RESOLVER_PROTOCOL;
3use crate::protocol::callback::{self, PromptParams, PromptResult};
4use crate::protocol::resolver::{
5 CAPABILITIES, DeleteParams, DeleteResult, GetParams, GetResult, InitializeApplication,
6 InitializedApplication, ReleaseParams, ReleaseResult, SetParams, SetResult, method,
7 validate_capabilities,
8};
9use crate::server::{ApplicationHandler, RequestContext, RpcResult, ServerConfig};
10use async_trait::async_trait;
11use serde::de::DeserializeOwned;
12use serde_json::Value;
13use std::sync::Arc;
14
15#[async_trait]
24pub trait ResolverHandler: Send + Sync + 'static {
25 async fn initialize(
26 &self,
27 context: &RequestContext,
28 application: InitializeApplication,
29 ) -> RpcResult<InitializedApplication>;
30
31 async fn get(&self, context: RequestContext, params: GetParams) -> RpcResult<GetResult>;
32
33 async fn release(
34 &self,
35 context: RequestContext,
36 params: ReleaseParams,
37 ) -> RpcResult<ReleaseResult>;
38
39 fn capabilities(&self) -> Vec<String> {
43 CAPABILITIES
44 .iter()
45 .map(|item| (*item).to_string())
46 .collect()
47 }
48
49 async fn set(&self, _context: RequestContext, _params: SetParams) -> RpcResult<SetResult> {
53 Err(RpcError::new(ErrorKind::MethodNotFound))
54 }
55
56 async fn delete(
59 &self,
60 _context: RequestContext,
61 _params: DeleteParams,
62 ) -> RpcResult<DeleteResult> {
63 Err(RpcError::new(ErrorKind::MethodNotFound))
64 }
65
66 async fn request_finished(&self, _request_id: crate::RequestId, _committed: bool) {}
67
68 async fn shutdown(&self) {}
69}
70
71struct ResolverApplication<H> {
72 handler: Arc<H>,
73}
74
75impl<H> ResolverApplication<H> {
76 fn new(handler: Arc<H>) -> Self {
77 Self { handler }
78 }
79}
80
81#[async_trait]
82impl<H: ResolverHandler> ApplicationHandler for ResolverApplication<H> {
83 fn protocol(&self) -> &'static str {
84 RESOLVER_PROTOCOL
85 }
86
87 fn capabilities(&self) -> Vec<String> {
88 self.handler.capabilities()
89 }
90
91 fn validate_capabilities(&self, capabilities: &[String]) -> RpcResult<()> {
96 validate_capabilities(capabilities).map_err(|_| RpcError::new(ErrorKind::Internal))
97 }
98
99 async fn initialize(&self, context: &RequestContext, application: Value) -> RpcResult<Value> {
100 let application: InitializeApplication = parse(application)?;
101 application.validate().map_err(invalid_params)?;
102 let initialized = self.handler.initialize(context, application).await?;
103 initialized
104 .validate()
105 .map_err(|_| RpcError::new(ErrorKind::OperationFailed))?;
106 serde_json::to_value(initialized).map_err(|_| RpcError::new(ErrorKind::Internal))
107 }
108
109 async fn call(&self, context: RequestContext, method: &str, params: Value) -> RpcResult<Value> {
110 match method {
111 method::GET => {
112 let params: GetParams = parse(params)?;
113 params.validate().map_err(invalid_params)?;
114 let result = self.handler.get(context, params).await?;
115 serde_json::to_value(result).map_err(|_| RpcError::new(ErrorKind::Internal))
116 }
117 method::RELEASE => {
118 let params: ReleaseParams = parse(params)?;
119 params.validate().map_err(invalid_params)?;
120 let result = self.handler.release(context, params).await?;
121 serde_json::to_value(result).map_err(|_| RpcError::new(ErrorKind::Internal))
122 }
123 method::SET => {
124 let params: SetParams = parse(params)?;
125 params.validate().map_err(invalid_params)?;
126 let result = self.handler.set(context, params).await?;
127 serde_json::to_value(result).map_err(|_| RpcError::new(ErrorKind::Internal))
128 }
129 method::DELETE => {
130 let params: DeleteParams = parse(params)?;
131 params.validate().map_err(invalid_params)?;
132 let result = self.handler.delete(context, params).await?;
133 serde_json::to_value(result).map_err(|_| RpcError::new(ErrorKind::Internal))
134 }
135 _ => Err(RpcError::new(ErrorKind::MethodNotFound)),
136 }
137 }
138
139 async fn request_finished(&self, request_id: crate::RequestId, committed: bool) {
140 self.handler.request_finished(request_id, committed).await;
141 }
142
143 async fn shutdown(&self) {
144 self.handler.shutdown().await;
145 }
146}
147
148pub async fn prompt(context: &RequestContext, params: &PromptParams) -> RpcResult<PromptResult> {
156 if !context.peer.supports(callback::method::PROMPT) {
157 return Err(RpcError::new(ErrorKind::InteractionRequired));
158 }
159 params
160 .validate()
161 .map_err(|_| RpcError::new(ErrorKind::Internal))?;
162 let result: PromptResult = context
163 .peer
164 .call(callback::method::PROMPT, params, context)
165 .await?;
166 result
170 .validate()
171 .map_err(|_| RpcError::new(ErrorKind::OperationFailed))?;
172 Ok(result)
173}
174
175fn parse<T: DeserializeOwned>(value: Value) -> RpcResult<T> {
176 serde_json::from_value(value).map_err(|_| RpcError::new(ErrorKind::InvalidParams))
177}
178
179fn invalid_params(_: crate::Error) -> RpcError {
180 RpcError::new(ErrorKind::InvalidParams)
181}
182
183pub async fn serve_resolver<R, W, H>(
185 reader: R,
186 writer: W,
187 handler: H,
188 config: ServerConfig,
189) -> crate::Result<()>
190where
191 R: tokio::io::AsyncRead + Unpin + Send + 'static,
192 W: tokio::io::AsyncWrite + Unpin + Send + 'static,
193 H: ResolverHandler,
194{
195 crate::server::serve(
196 reader,
197 writer,
198 Arc::new(ResolverApplication::new(Arc::new(handler))),
199 config,
200 )
201 .await
202}