surrealdb_core/rpc/
request.rs1use crate::rpc::format::cbor::Cbor;
2use crate::rpc::format::msgpack::Pack;
3use crate::rpc::Method;
4use crate::rpc::RpcError;
5use crate::sql::Array;
6use crate::sql::Number;
7use crate::sql::Part;
8use crate::sql::Value;
9use std::sync::LazyLock;
10
11pub static ID: LazyLock<[Part; 1]> = LazyLock::new(|| [Part::from("id")]);
12pub static METHOD: LazyLock<[Part; 1]> = LazyLock::new(|| [Part::from("method")]);
13pub static PARAMS: LazyLock<[Part; 1]> = LazyLock::new(|| [Part::from("params")]);
14pub static VERSION: LazyLock<[Part; 1]> = LazyLock::new(|| [Part::from("version")]);
15
16#[derive(Debug)]
17pub struct Request {
18 pub id: Option<Value>,
19 pub version: Option<u8>,
20 pub method: Method,
21 pub params: Array,
22}
23
24impl TryFrom<Cbor> for Request {
25 type Error = RpcError;
26 fn try_from(val: Cbor) -> Result<Self, RpcError> {
27 <Cbor as TryInto<Value>>::try_into(val).map_err(|_| RpcError::InvalidRequest)?.try_into()
28 }
29}
30
31impl TryFrom<Pack> for Request {
32 type Error = RpcError;
33 fn try_from(val: Pack) -> Result<Self, RpcError> {
34 <Pack as TryInto<Value>>::try_into(val).map_err(|_| RpcError::InvalidRequest)?.try_into()
35 }
36}
37
38impl TryFrom<Value> for Request {
39 type Error = RpcError;
40 fn try_from(val: Value) -> Result<Self, RpcError> {
41 let id = match val.pick(&*ID) {
43 v if v.is_none() => None,
44 v if v.is_null() => Some(v),
45 v if v.is_uuid() => Some(v),
46 v if v.is_number() => Some(v),
47 v if v.is_strand() => Some(v),
48 v if v.is_datetime() => Some(v),
49 _ => return Err(RpcError::InvalidRequest),
50 };
51 let version = match val.pick(&*VERSION) {
53 v if v.is_none() => None,
54 v if v.is_null() => None,
55 Value::Number(v) => match v {
56 Number::Int(1) => Some(1),
57 Number::Int(2) => Some(2),
58 _ => return Err(RpcError::InvalidRequest),
59 },
60 _ => return Err(RpcError::InvalidRequest),
61 };
62 let method = match val.pick(&*METHOD) {
64 Value::Strand(v) => v.to_raw(),
65 _ => return Err(RpcError::InvalidRequest),
66 };
67 let params = match val.pick(&*PARAMS) {
69 Value::Array(v) => v,
70 _ => Array::new(),
71 };
72 let method = Method::parse_case_sensitive(&method);
74 Ok(Request {
76 id,
77 method,
78 params,
79 version,
80 })
81 }
82}