surreal_simple_client/response.rs
1use serde::Deserialize;
2use serde::Serialize;
3use serde_json::Value;
4
5/// A raw, unparsed, response from the SurrealDB instance.
6///
7/// A surreal response always looks like the following:
8/// ```json
9/// // SELECT ->manage->Project as projects, * from Account;
10/// [
11/// { // <-- SurrealQueryResult: one object for each query passed in the request
12/// "time": "229.2µs",
13/// "status": "OK",
14/// "result": [
15/// { // <-- one object for each returned row
16/// "projects": [...],
17///
18/// // ... the rest of the fields from the Account node and returned by the
19/// // * selector:
20/// "id": "...",
21/// "username": "..."
22/// }
23///
24/// ]
25/// },
26/// ]
27/// ```
28///
29/// The [`SurrealResponseData::result`] field holds a `serde::Value` that represents
30/// such JSON. However it is recommended to use the [SurrealResponseData] methods
31/// to make retrieving data easier.
32#[derive(Serialize, Deserialize, Debug)]
33pub struct SurrealResponseData {
34 pub id: String,
35
36 pub result: SurrealResponseResult,
37}
38
39impl SurrealResponseData {
40 /// Get the result of the `n`-th query out of the resulting JSON. Refer to the
41 /// [SurrealResponseData] description to understand what the resulting JSON
42 /// looks like and what object will be returned by this function.
43 ///
44 /// If the response doesn't contain any data then [None] is immediately returned
45 pub fn get_nth_query_result(&self, n: usize) -> Option<&SurrealQueryResult> {
46 match &self.result {
47 SurrealResponseResult::Data(results) => results.get(n),
48 _ => None,
49 }
50 }
51}
52
53#[derive(Serialize, Deserialize, Debug)]
54#[serde(untagged)]
55pub enum SurrealResponseResult {
56 String(String),
57 Data(Vec<SurrealQueryResult>),
58 Null,
59}
60
61/// A raw, unparsed response from the SurrealDB instance for a single statement.
62///
63/// A surreal response always looks like the following:
64/// ```json
65/// // SELECT ->manage->Project as projects, * from Account;
66/// [
67/// { // <-- SurrealQueryResult: one object for each query passed in the request
68/// "time": "229.2µs",
69/// "status": "OK",
70/// "result": [
71/// { // <-- one object for each returned row
72/// "projects": [...],
73///
74/// // ... the rest of the fields from the Account node and returned by the
75/// // * selector:
76/// "id": "...",
77/// "username": "..."
78/// }
79///
80/// ]
81/// },
82/// ]
83/// ```
84///
85#[derive(Serialize, Deserialize, Debug)]
86pub struct SurrealQueryResult {
87 pub time: String,
88 pub status: String,
89
90 result: Vec<Value>,
91}
92
93impl SurrealQueryResult {
94 pub fn results(&self) -> &Vec<Value> {
95 &self.result
96 }
97
98 /// Get the inner results and extract the
99 /// [Value] out of the `key` for each row.
100 ///
101 /// The function filters out the rows where `key` returned [None]
102 pub fn results_key(&self, key: &str) -> Vec<&Value> {
103 self.results().iter().filter_map(|v| v.get(key)).collect()
104 }
105}