Skip to main content

eoka_server/
protocol.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Clone, Deserialize)]
5pub struct Request {
6    pub id: Value,
7    pub method: String,
8    #[serde(default)]
9    pub params: Value,
10}
11
12#[derive(Debug, Serialize)]
13pub struct Response {
14    id: Value,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    result: Option<Value>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    error: Option<ErrorBody>,
19}
20
21impl Response {
22    pub fn ok(id: Value, result: Value) -> Self {
23        Self {
24            id,
25            result: Some(result),
26            error: None,
27        }
28    }
29
30    pub fn err(id: Value, error: ServerError) -> Self {
31        Self {
32            id,
33            result: None,
34            error: Some(ErrorBody {
35                code: error.code,
36                message: error.message,
37            }),
38        }
39    }
40}
41
42#[derive(Debug, Serialize)]
43struct ErrorBody {
44    code: ErrorCode,
45    message: String,
46}
47
48#[derive(Debug, Clone, Copy, Serialize)]
49pub enum ErrorCode {
50    ElementNotFound,
51    ElementNotVisible,
52    Timeout,
53    RetryExhausted,
54    Cdp,
55    InvalidPage,
56    InvalidParams,
57    UnknownMethod,
58    Internal,
59}
60
61#[derive(Debug)]
62pub struct ServerError {
63    pub code: ErrorCode,
64    pub message: String,
65}
66
67impl ServerError {
68    pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
69        Self {
70            code,
71            message: message.into(),
72        }
73    }
74
75    pub fn invalid_params(message: impl Into<String>) -> Self {
76        Self::new(ErrorCode::InvalidParams, message)
77    }
78
79    pub fn invalid_page(page_id: &str) -> Self {
80        Self::new(
81            ErrorCode::InvalidPage,
82            format!("unknown pageId \"{page_id}\""),
83        )
84    }
85
86    pub fn unknown_method(method: &str) -> Self {
87        Self::new(
88            ErrorCode::UnknownMethod,
89            format!("unknown method \"{method}\""),
90        )
91    }
92
93    pub fn internal(message: impl Into<String>) -> Self {
94        Self::new(ErrorCode::Internal, message)
95    }
96}
97
98impl From<eoka::Error> for ServerError {
99    fn from(err: eoka::Error) -> Self {
100        let code = match &err {
101            eoka::Error::ElementNotFound(_) => ErrorCode::ElementNotFound,
102            eoka::Error::ElementNotVisible { .. } => ErrorCode::ElementNotVisible,
103            eoka::Error::Timeout(_) => ErrorCode::Timeout,
104            eoka::Error::RetryExhausted { .. } => ErrorCode::RetryExhausted,
105            eoka::Error::Cdp { .. } => ErrorCode::Cdp,
106            _ => ErrorCode::Internal,
107        };
108        Self {
109            code,
110            message: err.to_string(),
111        }
112    }
113}