Improve RPC method return types (#1384)
This commit is contained in:
parent
c098fe3380
commit
f0eaf2bd19
7 changed files with 102 additions and 103 deletions
|
@ -571,6 +571,10 @@ impl Value {
|
||||||
matches!(self, Value::Object(_))
|
matches!(self, Value::Object(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_number(&self) -> bool {
|
||||||
|
matches!(self, Value::Number(_))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_int(&self) -> bool {
|
pub fn is_int(&self) -> bool {
|
||||||
matches!(self, Value::Number(Number::Int(_)))
|
matches!(self, Value::Number(Number::Int(_)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ use surrealdb::sql::Value;
|
||||||
use surrealdb::Auth;
|
use surrealdb::Auth;
|
||||||
use surrealdb::Session;
|
use surrealdb::Session;
|
||||||
|
|
||||||
pub async fn signin(session: &mut Session, vars: Object) -> Result<String, Error> {
|
pub async fn signin(session: &mut Session, vars: Object) -> Result<Value, Error> {
|
||||||
// Parse the specified variables
|
// Parse the specified variables
|
||||||
let ns = vars.get("NS").or_else(|| vars.get("ns"));
|
let ns = vars.get("NS").or_else(|| vars.get("ns"));
|
||||||
let db = vars.get("DB").or_else(|| vars.get("db"));
|
let db = vars.get("DB").or_else(|| vars.get("db"));
|
||||||
|
@ -26,9 +26,7 @@ pub async fn signin(session: &mut Session, vars: Object) -> Result<String, Error
|
||||||
let db = db.to_strand().as_string();
|
let db = db.to_strand().as_string();
|
||||||
let sc = sc.to_strand().as_string();
|
let sc = sc.to_strand().as_string();
|
||||||
// Attempt to signin to specified scope
|
// Attempt to signin to specified scope
|
||||||
let res = super::signin::sc(session, ns, db, sc, vars).await?;
|
super::signin::sc(session, ns, db, sc, vars).await
|
||||||
// Return the result to the client
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
(Some(ns), Some(db), None) => {
|
(Some(ns), Some(db), None) => {
|
||||||
// Get the provided user and pass
|
// Get the provided user and pass
|
||||||
|
@ -44,9 +42,7 @@ pub async fn signin(session: &mut Session, vars: Object) -> Result<String, Error
|
||||||
let user = user.to_strand().as_string();
|
let user = user.to_strand().as_string();
|
||||||
let pass = pass.to_strand().as_string();
|
let pass = pass.to_strand().as_string();
|
||||||
// Attempt to signin to database
|
// Attempt to signin to database
|
||||||
let res = super::signin::db(session, ns, db, user, pass).await?;
|
super::signin::db(session, ns, db, user, pass).await
|
||||||
// Return the result to the client
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
// There is no username or password
|
// There is no username or password
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
|
@ -65,9 +61,7 @@ pub async fn signin(session: &mut Session, vars: Object) -> Result<String, Error
|
||||||
let user = user.to_strand().as_string();
|
let user = user.to_strand().as_string();
|
||||||
let pass = pass.to_strand().as_string();
|
let pass = pass.to_strand().as_string();
|
||||||
// Attempt to signin to namespace
|
// Attempt to signin to namespace
|
||||||
let res = super::signin::ns(session, ns, user, pass).await?;
|
super::signin::ns(session, ns, user, pass).await
|
||||||
// Return the result to the client
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
// There is no username or password
|
// There is no username or password
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
|
@ -85,9 +79,7 @@ pub async fn signin(session: &mut Session, vars: Object) -> Result<String, Error
|
||||||
let user = user.to_strand().as_string();
|
let user = user.to_strand().as_string();
|
||||||
let pass = pass.to_strand().as_string();
|
let pass = pass.to_strand().as_string();
|
||||||
// Attempt to signin to namespace
|
// Attempt to signin to namespace
|
||||||
let res = super::signin::su(session, user, pass).await?;
|
super::signin::su(session, user, pass).await
|
||||||
// Return the result to the client
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
// There is no username or password
|
// There is no username or password
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
|
@ -103,7 +95,7 @@ pub async fn sc(
|
||||||
db: String,
|
db: String,
|
||||||
sc: String,
|
sc: String,
|
||||||
vars: Object,
|
vars: Object,
|
||||||
) -> Result<String, Error> {
|
) -> Result<Value, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Get local copy of options
|
// Get local copy of options
|
||||||
|
@ -160,7 +152,7 @@ pub async fn sc(
|
||||||
// Check the authentication token
|
// Check the authentication token
|
||||||
match enc {
|
match enc {
|
||||||
// The auth token was created successfully
|
// The auth token was created successfully
|
||||||
Ok(tk) => Ok(tk),
|
Ok(tk) => Ok(tk.into()),
|
||||||
// There was an error creating the token
|
// There was an error creating the token
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
}
|
}
|
||||||
|
@ -187,7 +179,7 @@ pub async fn db(
|
||||||
db: String,
|
db: String,
|
||||||
user: String,
|
user: String,
|
||||||
pass: String,
|
pass: String,
|
||||||
) -> Result<String, Error> {
|
) -> Result<Value, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Create a new readonly transaction
|
// Create a new readonly transaction
|
||||||
|
@ -223,7 +215,7 @@ pub async fn db(
|
||||||
// Check the authentication token
|
// Check the authentication token
|
||||||
match enc {
|
match enc {
|
||||||
// The auth token was created successfully
|
// The auth token was created successfully
|
||||||
Ok(tk) => Ok(tk),
|
Ok(tk) => Ok(tk.into()),
|
||||||
// There was an error creating the token
|
// There was an error creating the token
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
}
|
}
|
||||||
|
@ -242,7 +234,7 @@ pub async fn ns(
|
||||||
ns: String,
|
ns: String,
|
||||||
user: String,
|
user: String,
|
||||||
pass: String,
|
pass: String,
|
||||||
) -> Result<String, Error> {
|
) -> Result<Value, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Create a new readonly transaction
|
// Create a new readonly transaction
|
||||||
|
@ -276,7 +268,7 @@ pub async fn ns(
|
||||||
// Check the authentication token
|
// Check the authentication token
|
||||||
match enc {
|
match enc {
|
||||||
// The auth token was created successfully
|
// The auth token was created successfully
|
||||||
Ok(tk) => Ok(tk),
|
Ok(tk) => Ok(tk.into()),
|
||||||
// There was an error creating the token
|
// There was an error creating the token
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
}
|
}
|
||||||
|
@ -290,14 +282,14 @@ pub async fn ns(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn su(session: &mut Session, user: String, pass: String) -> Result<String, Error> {
|
pub async fn su(session: &mut Session, user: String, pass: String) -> Result<Value, Error> {
|
||||||
// Get the config options
|
// Get the config options
|
||||||
let opts = CF.get().unwrap();
|
let opts = CF.get().unwrap();
|
||||||
// Attempt to verify the root user
|
// Attempt to verify the root user
|
||||||
if let Some(root) = &opts.pass {
|
if let Some(root) = &opts.pass {
|
||||||
if user == opts.user && &pass == root {
|
if user == opts.user && &pass == root {
|
||||||
session.au = Arc::new(Auth::Kv);
|
session.au = Arc::new(Auth::Kv);
|
||||||
return Ok(String::from(""));
|
return Ok(Value::None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The specified user login does not exist
|
// The specified user login does not exist
|
||||||
|
|
|
@ -11,7 +11,7 @@ use surrealdb::sql::Value;
|
||||||
use surrealdb::Auth;
|
use surrealdb::Auth;
|
||||||
use surrealdb::Session;
|
use surrealdb::Session;
|
||||||
|
|
||||||
pub async fn signup(session: &mut Session, vars: Object) -> Result<String, Error> {
|
pub async fn signup(session: &mut Session, vars: Object) -> Result<Value, Error> {
|
||||||
// Parse the specified variables
|
// Parse the specified variables
|
||||||
let ns = vars.get("NS").or_else(|| vars.get("ns"));
|
let ns = vars.get("NS").or_else(|| vars.get("ns"));
|
||||||
let db = vars.get("DB").or_else(|| vars.get("db"));
|
let db = vars.get("DB").or_else(|| vars.get("db"));
|
||||||
|
@ -24,9 +24,7 @@ pub async fn signup(session: &mut Session, vars: Object) -> Result<String, Error
|
||||||
let db = db.to_strand().as_string();
|
let db = db.to_strand().as_string();
|
||||||
let sc = sc.to_strand().as_string();
|
let sc = sc.to_strand().as_string();
|
||||||
// Attempt to signin to specified scope
|
// Attempt to signin to specified scope
|
||||||
let res = super::signup::sc(session, ns, db, sc, vars).await?;
|
super::signup::sc(session, ns, db, sc, vars).await
|
||||||
// Return the result to the client
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
}
|
}
|
||||||
|
@ -38,7 +36,7 @@ pub async fn sc(
|
||||||
db: String,
|
db: String,
|
||||||
sc: String,
|
sc: String,
|
||||||
vars: Object,
|
vars: Object,
|
||||||
) -> Result<String, Error> {
|
) -> Result<Value, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Get local copy of options
|
// Get local copy of options
|
||||||
|
@ -95,7 +93,7 @@ pub async fn sc(
|
||||||
// Create the authentication token
|
// Create the authentication token
|
||||||
match enc {
|
match enc {
|
||||||
// The auth token was created successfully
|
// The auth token was created successfully
|
||||||
Ok(tk) => Ok(tk),
|
Ok(tk) => Ok(tk.into()),
|
||||||
// There was an error creating the token
|
// There was an error creating the token
|
||||||
_ => Err(Error::InvalidAuth),
|
_ => Err(Error::InvalidAuth),
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,10 @@ use crate::net::session;
|
||||||
use crate::net::LOG;
|
use crate::net::LOG;
|
||||||
use crate::rpc::args::Take;
|
use crate::rpc::args::Take;
|
||||||
use crate::rpc::paths::{ID, METHOD, PARAMS};
|
use crate::rpc::paths::{ID, METHOD, PARAMS};
|
||||||
|
use crate::rpc::res;
|
||||||
use crate::rpc::res::Failure;
|
use crate::rpc::res::Failure;
|
||||||
use crate::rpc::res::Response;
|
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
|
use serde::Serialize;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use surrealdb::channel;
|
use surrealdb::channel;
|
||||||
|
@ -127,24 +128,24 @@ impl Rpc {
|
||||||
// Convert the message
|
// Convert the message
|
||||||
let str = match msg.to_str() {
|
let str = match msg.to_str() {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
_ => return Response::failure(None, Failure::INTERNAL_ERROR).send(chn).await,
|
_ => return res::failure(None, Failure::INTERNAL_ERROR).send(chn).await,
|
||||||
};
|
};
|
||||||
// Parse the request
|
// Parse the request
|
||||||
let req = match surrealdb::sql::json(str) {
|
let req = match surrealdb::sql::json(str) {
|
||||||
Ok(v) if v.is_some() => v,
|
Ok(v) if v.is_some() => v,
|
||||||
_ => return Response::failure(None, Failure::PARSE_ERROR).send(chn).await,
|
_ => return res::failure(None, Failure::PARSE_ERROR).send(chn).await,
|
||||||
};
|
};
|
||||||
// Fetch the 'id' argument
|
// Fetch the 'id' argument
|
||||||
let id = match req.pick(&*ID) {
|
let id = match req.pick(&*ID) {
|
||||||
Value::Uuid(v) => Some(v.to_raw()),
|
v if v.is_uuid() || v.is_strand() || v.is_number() || v.is_none() || v.is_null() => {
|
||||||
Value::Strand(v) => Some(v.to_raw()),
|
Some(v)
|
||||||
Value::Number(v) => Some(v.to_string()),
|
}
|
||||||
_ => return Response::failure(None, Failure::INVALID_REQUEST).send(chn).await,
|
_ => return res::failure(None, Failure::INVALID_REQUEST).send(chn).await,
|
||||||
};
|
};
|
||||||
// Fetch the 'method' argument
|
// Fetch the 'method' argument
|
||||||
let method = match req.pick(&*METHOD) {
|
let method = match req.pick(&*METHOD) {
|
||||||
Value::Strand(v) => v.to_raw(),
|
Value::Strand(v) => v.to_raw(),
|
||||||
_ => return Response::failure(id, Failure::INVALID_REQUEST).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_REQUEST).send(chn).await,
|
||||||
};
|
};
|
||||||
// Fetch the 'params' argument
|
// Fetch the 'params' argument
|
||||||
let params = match req.pick(&*PARAMS) {
|
let params = match req.pick(&*PARAMS) {
|
||||||
|
@ -153,99 +154,111 @@ impl Rpc {
|
||||||
};
|
};
|
||||||
// Match the method to a function
|
// Match the method to a function
|
||||||
let res = match &method[..] {
|
let res = match &method[..] {
|
||||||
"ping" => Ok(Value::True),
|
"ping" => Ok(Value::None),
|
||||||
"info" => match params.len() {
|
"info" => match params.len() {
|
||||||
0 => rpc.read().await.info().await,
|
0 => rpc.read().await.info().await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"use" => match params.take_two() {
|
"use" => match params.take_two() {
|
||||||
(Value::Strand(ns), Value::Strand(db)) => rpc.write().await.yuse(ns, db).await,
|
(Value::Strand(ns), Value::Strand(db)) => rpc.write().await.yuse(ns, db).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"signup" => match params.take_one() {
|
"signup" => match params.take_one() {
|
||||||
Value::Object(v) => rpc.write().await.signup(v).await,
|
Value::Object(v) => rpc.write().await.signup(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"signin" => match params.take_one() {
|
"signin" => match params.take_one() {
|
||||||
Value::Object(v) => rpc.write().await.signin(v).await,
|
Value::Object(v) => rpc.write().await.signin(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"invalidate" => match params.len() {
|
"invalidate" => match params.len() {
|
||||||
0 => rpc.write().await.invalidate().await,
|
0 => rpc.write().await.invalidate().await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"authenticate" => match params.take_one() {
|
"authenticate" => match params.take_one() {
|
||||||
Value::None => rpc.write().await.invalidate().await,
|
Value::None => rpc.write().await.invalidate().await,
|
||||||
Value::Strand(v) => rpc.write().await.authenticate(v).await,
|
Value::Strand(v) => rpc.write().await.authenticate(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"kill" => match params.take_one() {
|
"kill" => match params.take_one() {
|
||||||
v if v.is_uuid() => rpc.read().await.kill(v).await,
|
v if v.is_uuid() => rpc.read().await.kill(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"live" => match params.take_one() {
|
"live" => match params.take_one() {
|
||||||
v if v.is_strand() => rpc.read().await.live(v).await,
|
v if v.is_strand() => rpc.read().await.live(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"let" => match params.take_two() {
|
"let" => match params.take_two() {
|
||||||
(Value::Strand(s), v) => rpc.write().await.set(s, v).await,
|
(Value::Strand(s), v) => rpc.write().await.set(s, v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"set" => match params.take_two() {
|
"set" => match params.take_two() {
|
||||||
(Value::Strand(s), v) => rpc.write().await.set(s, v).await,
|
(Value::Strand(s), v) => rpc.write().await.set(s, v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"query" => match params.take_two() {
|
"query" => match params.take_two() {
|
||||||
(Value::Strand(s), o) if o.is_none() => rpc.read().await.query(s).await,
|
(Value::Strand(s), o) if o.is_none() => {
|
||||||
(Value::Strand(s), Value::Object(o)) => rpc.read().await.query_with(s, o).await,
|
let res = rpc.read().await.query(s).await;
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
return match res {
|
||||||
|
Ok(v) => res::success(id, v).send(chn).await,
|
||||||
|
Err(e) => res::failure(id, Failure::custom(e.to_string())).send(chn).await,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(Value::Strand(s), Value::Object(o)) => {
|
||||||
|
let res = rpc.read().await.query_with(s, o).await;
|
||||||
|
return match res {
|
||||||
|
Ok(v) => res::success(id, v).send(chn).await,
|
||||||
|
Err(e) => res::failure(id, Failure::custom(e.to_string())).send(chn).await,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"select" => match params.take_one() {
|
"select" => match params.take_one() {
|
||||||
v if v.is_thing() => rpc.read().await.select(v).await,
|
v if v.is_thing() => rpc.read().await.select(v).await,
|
||||||
v if v.is_strand() => rpc.read().await.select(v).await,
|
v if v.is_strand() => rpc.read().await.select(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"create" => match params.take_two() {
|
"create" => match params.take_two() {
|
||||||
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.create(v, None).await,
|
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.create(v, None).await,
|
||||||
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.create(v, None).await,
|
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.create(v, None).await,
|
||||||
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.create(v, o).await,
|
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.create(v, o).await,
|
||||||
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.create(v, o).await,
|
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.create(v, o).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"update" => match params.take_two() {
|
"update" => match params.take_two() {
|
||||||
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.update(v, None).await,
|
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.update(v, None).await,
|
||||||
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.update(v, None).await,
|
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.update(v, None).await,
|
||||||
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.update(v, o).await,
|
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.update(v, o).await,
|
||||||
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.update(v, o).await,
|
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.update(v, o).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"change" => match params.take_two() {
|
"change" => match params.take_two() {
|
||||||
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.change(v, None).await,
|
(v, o) if v.is_thing() && o.is_none() => rpc.read().await.change(v, None).await,
|
||||||
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.change(v, None).await,
|
(v, o) if v.is_strand() && o.is_none() => rpc.read().await.change(v, None).await,
|
||||||
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.change(v, o).await,
|
(v, o) if v.is_thing() && o.is_object() => rpc.read().await.change(v, o).await,
|
||||||
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.change(v, o).await,
|
(v, o) if v.is_strand() && o.is_object() => rpc.read().await.change(v, o).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"modify" => match params.take_two() {
|
"modify" => match params.take_two() {
|
||||||
(v, o) if v.is_thing() && o.is_array() => rpc.read().await.modify(v, o).await,
|
(v, o) if v.is_thing() && o.is_array() => rpc.read().await.modify(v, o).await,
|
||||||
(v, o) if v.is_strand() && o.is_array() => rpc.read().await.modify(v, o).await,
|
(v, o) if v.is_strand() && o.is_array() => rpc.read().await.modify(v, o).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"delete" => match params.take_one() {
|
"delete" => match params.take_one() {
|
||||||
v if v.is_thing() => rpc.read().await.delete(v).await,
|
v if v.is_thing() => rpc.read().await.delete(v).await,
|
||||||
v if v.is_strand() => rpc.read().await.delete(v).await,
|
v if v.is_strand() => rpc.read().await.delete(v).await,
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
"version" => match params.len() {
|
"version" => match params.len() {
|
||||||
0 => Ok(format!("{}-{}", PKG_NAME, *PKG_VERS).into()),
|
0 => Ok(format!("{}-{}", PKG_NAME, *PKG_VERS).into()),
|
||||||
_ => return Response::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
_ => return res::failure(id, Failure::INVALID_PARAMS).send(chn).await,
|
||||||
},
|
},
|
||||||
_ => return Response::failure(id, Failure::METHOD_NOT_FOUND).send(chn).await,
|
_ => return res::failure(id, Failure::METHOD_NOT_FOUND).send(chn).await,
|
||||||
};
|
};
|
||||||
// Return the final response
|
// Return the final response
|
||||||
match res {
|
match res {
|
||||||
Ok(v) => Response::success(id, v).send(chn).await,
|
Ok(v) => res::success(id, v).send(chn).await,
|
||||||
Err(e) => Response::failure(id, Failure::custom(e.to_string())).send(chn).await,
|
Err(e) => res::failure(id, Failure::custom(e.to_string())).send(chn).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,17 +273,11 @@ impl Rpc {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn signup(&mut self, vars: Object) -> Result<Value, Error> {
|
async fn signup(&mut self, vars: Object) -> Result<Value, Error> {
|
||||||
crate::iam::signup::signup(&mut self.session, vars)
|
crate::iam::signup::signup(&mut self.session, vars).await.map_err(Into::into)
|
||||||
.await
|
|
||||||
.map(Into::into)
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn signin(&mut self, vars: Object) -> Result<Value, Error> {
|
async fn signin(&mut self, vars: Object) -> Result<Value, Error> {
|
||||||
crate::iam::signin::signin(&mut self.session, vars)
|
crate::iam::signin::signin(&mut self.session, vars).await.map_err(Into::into)
|
||||||
.await
|
|
||||||
.map(Into::into)
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn invalidate(&mut self) -> Result<Value, Error> {
|
async fn invalidate(&mut self) -> Result<Value, Error> {
|
||||||
|
@ -369,7 +376,7 @@ impl Rpc {
|
||||||
// Methods for querying
|
// Methods for querying
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
async fn query(&self, sql: Strand) -> Result<Value, Error> {
|
async fn query(&self, sql: Strand) -> Result<impl Serialize, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Get local copy of options
|
// Get local copy of options
|
||||||
|
@ -378,13 +385,11 @@ impl Rpc {
|
||||||
let var = Some(self.vars.clone());
|
let var = Some(self.vars.clone());
|
||||||
// Execute the query on the database
|
// Execute the query on the database
|
||||||
let res = kvs.execute(&sql, &self.session, var, opt.strict).await?;
|
let res = kvs.execute(&sql, &self.session, var, opt.strict).await?;
|
||||||
// Extract the first query result
|
|
||||||
let res = res.into_iter().collect::<Vec<Value>>().into();
|
|
||||||
// Return the result to the client
|
// Return the result to the client
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn query_with(&self, sql: Strand, mut vars: Object) -> Result<Value, Error> {
|
async fn query_with(&self, sql: Strand, mut vars: Object) -> Result<impl Serialize, Error> {
|
||||||
// Get a database reference
|
// Get a database reference
|
||||||
let kvs = DB.get().unwrap();
|
let kvs = DB.get().unwrap();
|
||||||
// Get local copy of options
|
// Get local copy of options
|
||||||
|
@ -393,8 +398,6 @@ impl Rpc {
|
||||||
let var = Some(mrg! { vars.0, &self.vars });
|
let var = Some(mrg! { vars.0, &self.vars });
|
||||||
// Execute the query on the database
|
// Execute the query on the database
|
||||||
let res = kvs.execute(&sql, &self.session, var, opt.strict).await?;
|
let res = kvs.execute(&sql, &self.session, var, opt.strict).await?;
|
||||||
// Extract the first query result
|
|
||||||
let res = res.into_iter().collect::<Vec<Value>>().into();
|
|
||||||
// Return the result to the client
|
// Return the result to the client
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,11 +57,11 @@ async fn handler(
|
||||||
Ok(Value::Object(vars)) => match crate::iam::signin::signin(&mut session, vars).await {
|
Ok(Value::Object(vars)) => match crate::iam::signin::signin(&mut session, vars).await {
|
||||||
// Authentication was successful
|
// Authentication was successful
|
||||||
Ok(v) => match output.as_deref() {
|
Ok(v) => match output.as_deref() {
|
||||||
Some("application/json") => Ok(output::json(&Success::new(v))),
|
Some("application/json") => Ok(output::json(&Success::new(v.as_string()))),
|
||||||
Some("application/cbor") => Ok(output::cbor(&Success::new(v))),
|
Some("application/cbor") => Ok(output::cbor(&Success::new(v.as_string()))),
|
||||||
Some("application/msgpack") => Ok(output::pack(&Success::new(v))),
|
Some("application/msgpack") => Ok(output::pack(&Success::new(v.as_string()))),
|
||||||
Some("text/plain") => Ok(output::text(v)),
|
Some("text/plain") => Ok(output::text(v.as_string())),
|
||||||
None => Ok(output::text(v)),
|
None => Ok(output::text(v.as_string())),
|
||||||
// An incorrect content-type was requested
|
// An incorrect content-type was requested
|
||||||
_ => Err(warp::reject::custom(Error::InvalidType)),
|
_ => Err(warp::reject::custom(Error::InvalidType)),
|
||||||
},
|
},
|
||||||
|
|
|
@ -57,11 +57,11 @@ async fn handler(
|
||||||
Ok(Value::Object(vars)) => match crate::iam::signup::signup(&mut session, vars).await {
|
Ok(Value::Object(vars)) => match crate::iam::signup::signup(&mut session, vars).await {
|
||||||
// Authentication was successful
|
// Authentication was successful
|
||||||
Ok(v) => match output.as_deref() {
|
Ok(v) => match output.as_deref() {
|
||||||
Some("application/json") => Ok(output::json(&Success::new(v))),
|
Some("application/json") => Ok(output::json(&Success::new(v.as_string()))),
|
||||||
Some("application/cbor") => Ok(output::cbor(&Success::new(v))),
|
Some("application/cbor") => Ok(output::cbor(&Success::new(v.as_string()))),
|
||||||
Some("application/msgpack") => Ok(output::pack(&Success::new(v))),
|
Some("application/msgpack") => Ok(output::pack(&Success::new(v.as_string()))),
|
||||||
Some("text/plain") => Ok(output::text(v)),
|
Some("text/plain") => Ok(output::text(v.as_string())),
|
||||||
None => Ok(output::text(v)),
|
None => Ok(output::text(v.as_string())),
|
||||||
// An incorrect content-type was requested
|
// An incorrect content-type was requested
|
||||||
_ => Err(warp::reject::custom(Error::InvalidType)),
|
_ => Err(warp::reject::custom(Error::InvalidType)),
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,41 +5,27 @@ use surrealdb::sql::Value;
|
||||||
use warp::ws::Message;
|
use warp::ws::Message;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
enum Content {
|
enum Content<T> {
|
||||||
#[serde(rename = "result")]
|
#[serde(rename = "result")]
|
||||||
Success(Value),
|
Success(T),
|
||||||
#[serde(rename = "error")]
|
#[serde(rename = "error")]
|
||||||
Failure(Failure),
|
Failure(Failure),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct Response {
|
pub struct Response<T> {
|
||||||
id: Option<String>,
|
id: Option<Value>,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
content: Content,
|
content: Content<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Response {
|
impl<T: Serialize> Response<T> {
|
||||||
// Send the response to the channel
|
// Send the response to the channel
|
||||||
pub async fn send(self, chn: Sender<Message>) {
|
pub async fn send(self, chn: Sender<Message>) {
|
||||||
let res = serde_json::to_string(&self).unwrap();
|
let res = serde_json::to_string(&self).unwrap();
|
||||||
let res = Message::text(res);
|
let res = Message::text(res);
|
||||||
let _ = chn.send(res).await;
|
let _ = chn.send(res).await;
|
||||||
}
|
}
|
||||||
// Create a JSON RPC result response
|
|
||||||
pub fn success(id: Option<String>, val: Value) -> Response {
|
|
||||||
Response {
|
|
||||||
id,
|
|
||||||
content: Content::Success(val),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create a JSON RPC failure response
|
|
||||||
pub fn failure(id: Option<String>, err: Failure) -> Response {
|
|
||||||
Response {
|
|
||||||
id,
|
|
||||||
content: Content::Failure(err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
#[derive(Clone, Debug, Serialize)]
|
||||||
|
@ -84,3 +70,19 @@ impl Failure {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a JSON RPC result response
|
||||||
|
pub fn success<S: Serialize>(id: Option<Value>, val: S) -> Response<S> {
|
||||||
|
Response {
|
||||||
|
id,
|
||||||
|
content: Content::Success(val),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a JSON RPC failure response
|
||||||
|
pub fn failure(id: Option<Value>, err: Failure) -> Response<Value> {
|
||||||
|
Response {
|
||||||
|
id,
|
||||||
|
content: Content::Failure(err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue