Skip to main content

actrpc_core/
convert.rs

1use crate::{
2    error::{ActRpcError, CodecError, ProtocolError},
3    interception::{InterceptionRequest, InterceptionResponse},
4    json_rpc::{
5        JsonRpcId, JsonRpcParams, JsonRpcRequest, JsonRpcResponse, JsonRpcSuccessResponse,
6        JsonRpcVersion,
7    },
8};
9
10pub const INTERCEPT_METHOD: &str = "intercept";
11
12impl From<(JsonRpcId, InterceptionRequest)> for JsonRpcRequest {
13    fn from((id, req): (JsonRpcId, InterceptionRequest)) -> Self {
14        let value =
15            serde_json::to_value(req).expect("InterceptionRequest must always serialize to JSON");
16
17        let serde_json::Value::Object(map) = value else {
18            unreachable!("InterceptionRequest must always serialize to a JSON object");
19        };
20
21        JsonRpcRequest {
22            jsonrpc: JsonRpcVersion::V2_0,
23            id,
24            method: INTERCEPT_METHOD.to_string(),
25            params: Some(JsonRpcParams::Object(map)),
26        }
27    }
28}
29
30impl TryFrom<JsonRpcResponse> for (JsonRpcId, InterceptionResponse) {
31    type Error = ActRpcError;
32
33    fn try_from(resp: JsonRpcResponse) -> Result<Self, Self::Error> {
34        match resp {
35            JsonRpcResponse::Success(success) => {
36                let payload: InterceptionResponse = serde_json::from_value(success.result)
37                    .map_err(|source| {
38                        ActRpcError::Codec(CodecError::Deserialize(source.to_string()))
39                    })?;
40
41                Ok((success.id, payload))
42            }
43
44            JsonRpcResponse::Error(err) => Err(ActRpcError::RemoteJsonRpc(err.error)),
45        }
46    }
47}
48
49impl TryFrom<JsonRpcRequest> for (JsonRpcId, InterceptionRequest) {
50    type Error = ActRpcError;
51
52    fn try_from(req: JsonRpcRequest) -> Result<Self, Self::Error> {
53        if req.method != INTERCEPT_METHOD {
54            return Err(ActRpcError::Protocol(ProtocolError::UnexpectedMethod {
55                expected: INTERCEPT_METHOD.to_string(),
56                actual: req.method,
57            }));
58        }
59
60        let params = match req.params {
61            Some(JsonRpcParams::Object(map)) => map,
62            Some(JsonRpcParams::Array(_)) | None => {
63                return Err(ActRpcError::Protocol(ProtocolError::InvalidRequestParams));
64            }
65        };
66
67        let payload = serde_json::from_value(serde_json::Value::Object(params))
68            .map_err(|source| ActRpcError::Codec(CodecError::Deserialize(source.to_string())))?;
69
70        Ok((req.id, payload))
71    }
72}
73
74impl From<(JsonRpcId, InterceptionResponse)> for JsonRpcResponse {
75    fn from((id, resp): (JsonRpcId, InterceptionResponse)) -> Self {
76        let result =
77            serde_json::to_value(resp).expect("InterceptionResponse must always serialize to JSON");
78
79        JsonRpcResponse::Success(JsonRpcSuccessResponse {
80            jsonrpc: JsonRpcVersion::V2_0,
81            id,
82            result,
83        })
84    }
85}