aboutsummaryrefslogtreecommitdiff
path: root/codeless/server/src/dispatch.rs
diff options
context:
space:
mode:
Diffstat (limited to 'codeless/server/src/dispatch.rs')
-rw-r--r--codeless/server/src/dispatch.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/codeless/server/src/dispatch.rs b/codeless/server/src/dispatch.rs
new file mode 100644
index 000000000..a9476acde
--- /dev/null
+++ b/codeless/server/src/dispatch.rs
@@ -0,0 +1,124 @@
1use std::marker::PhantomData;
2
3use serde::{
4 ser::Serialize,
5 de::DeserializeOwned,
6};
7use serde_json;
8use drop_bomb::DropBomb;
9
10use ::{
11 Result,
12 req::Request,
13 io::{Io, RawMsg, RawResponse, RawRequest},
14};
15
16pub struct Responder<R: Request> {
17 id: u64,
18 bomb: DropBomb,
19 ph: PhantomData<R>,
20}
21
22impl<R: Request> Responder<R>
23 where
24 R::Params: DeserializeOwned,
25 R::Result: Serialize,
26{
27 pub fn respond_with(self, io: &mut Io, f: impl FnOnce() -> Result<R::Result>) -> Result<()> {
28 match f() {
29 Ok(res) => self.result(io, res)?,
30 Err(e) => {
31 self.error(io)?;
32 return Err(e);
33 }
34 }
35 Ok(())
36 }
37
38 pub fn result(mut self, io: &mut Io, result: R::Result) -> Result<()> {
39 self.bomb.defuse();
40 io.send(RawMsg::Response(RawResponse {
41 id: Some(self.id),
42 result: serde_json::to_value(result)?,
43 error: serde_json::Value::Null,
44 }));
45 Ok(())
46 }
47
48 pub fn error(mut self, io: &mut Io) -> Result<()> {
49 self.bomb.defuse();
50 error(io, self.id, ErrorCode::InternalError, "internal error")
51 }
52}
53
54
55pub fn parse_as<R>(raw: RawRequest) -> Result<::std::result::Result<(R::Params, Responder<R>), RawRequest>>
56 where
57 R: Request,
58 R::Params: DeserializeOwned,
59 R::Result: Serialize,
60{
61 if raw.method != R::METHOD {
62 return Ok(Err(raw));
63 }
64
65 let params: R::Params = serde_json::from_value(raw.params)?;
66 let responder = Responder {
67 id: raw.id,
68 bomb: DropBomb::new("dropped request"),
69 ph: PhantomData,
70 };
71 Ok(Ok((params, responder)))
72}
73
74pub fn expect<R>(io: &mut Io, raw: RawRequest) -> Result<Option<(R::Params, Responder<R>)>>
75 where
76 R: Request,
77 R::Params: DeserializeOwned,
78 R::Result: Serialize,
79{
80 let ret = match parse_as::<R>(raw)? {
81 Ok(x) => Some(x),
82 Err(raw) => {
83 unknown_method(io, raw)?;
84 None
85 }
86 };
87 Ok(ret)
88}
89
90pub fn unknown_method(io: &mut Io, raw: RawRequest) -> Result<()> {
91 error(io, raw.id, ErrorCode::MethodNotFound, "unknown method")
92}
93
94fn error(io: &mut Io, id: u64, code: ErrorCode, message: &'static str) -> Result<()> {
95 #[derive(Serialize)]
96 struct Error {
97 code: i32,
98 message: &'static str,
99 }
100 io.send(RawMsg::Response(RawResponse {
101 id: Some(id),
102 result: serde_json::Value::Null,
103 error: serde_json::to_value(Error {
104 code: code as i32,
105 message,
106 })?,
107 }));
108 Ok(())
109}
110
111
112#[allow(unused)]
113enum ErrorCode {
114 ParseError = -32700,
115 InvalidRequest = -32600,
116 MethodNotFound = -32601,
117 InvalidParams = -32602,
118 InternalError = -32603,
119 ServerErrorStart = -32099,
120 ServerErrorEnd = -32000,
121 ServerNotInitialized = -32002,
122 UnknownErrorCode = -32001,
123 RequestCancelled = -32800,
124}