almost reworked errors, cli rpc methods build macro

4-update-check
plazmoid 4 years ago
parent cb0c10e064
commit 6ad5c306e4
  1. 1
      bin/u_server/src/main.rs
  2. 2
      build_static_docker.sh
  3. 8
      cargo_static_docker.sh
  4. 11
      lib/u_lib/src/client/client.rs
  5. 109
      lib/u_lib/src/client/network.rs
  6. 61
      lib/u_lib/src/contracts/jobs.rs
  7. 5
      lib/u_lib/src/contracts/messaging.rs
  8. 11
      lib/u_lib/src/contracts/mod.rs
  9. 76
      lib/u_lib/src/errors.rs
  10. 5
      lib/u_lib/src/utils.rs

@ -37,7 +37,6 @@ async fn main() {
.and_then(handlers::listing);
let auth_token = warp::header::exact("authorization", "Bearer 123qwe");
//.and_then(handlers::check_token);
let auth_zone = auth_token.and(ls);

@ -1,2 +0,0 @@
#!/bin/bash
docker run -v $PWD:/volume -w /volume -it clux/muslrust cargo build

@ -0,0 +1,8 @@
#!/bin/bash
docker run \
-v $PWD:/volume \
-v cargo-cache:/root/.cargo/registry \
-w /volume \
-it \
clux/muslrust \
cargo $@

@ -1,6 +1,5 @@
use std::{
collections::HashMap,
fmt
collections::HashMap
};
use serde::{
@ -39,7 +38,7 @@ impl ClientInfo {
let job_result = exec_job(&mut job_meta);
let job_data = match job_result.data {
Ok(output) => output.multiline(),
Err(e) => e.description()
Err(e) => e.to_string()
};
info.insert(job.0.into(), job_data);
}
@ -67,14 +66,16 @@ const DEFAULT_JOBS: &[(&str, &str)] = &[
#[cfg(test)]
mod tests {
use super::*;
use crate::utils::vec_to_string;
#[test]
fn test_gather() {
let cli_info = ClientInfo::gather();
let field = cli_info.get_field("username").unwrap();
let stdout = JobOutput::from_multiline(field).unwrap().stdout;
assert_eq!(
JobOutput::from_multiline(field).unwrap().stdout,
b"plazmoid".to_vec()
&vec_to_string(&stdout),
"plazmoid"
)
}

@ -2,6 +2,7 @@ use crate::{
MASTER_SERVER,
MASTER_PORT,
contracts::*,
UResult
};
use reqwest::{
Client,
@ -11,13 +12,24 @@ use reqwest::{
};
use std::{
net::Ipv4Addr,
str::FromStr
str::FromStr,
any::Any
};
pub struct Paths;
impl Paths {
pub const LIST: &'static str = "list";
pub const NEW: &'static str = "new";
//pub const DEL: &'static str = "del";
pub const JOB_REQ: &'static str = "job_req";
pub const JOB_ANS: &'static str = "job_ans";
}
pub struct ClientHandler {
base_url: Url,
client: Client,
cli_info: ClientInfo,
password: Option<String>
}
@ -28,7 +40,6 @@ impl ClientHandler {
.unwrap_or(MASTER_SERVER);
Self {
client: Client::new(),
cli_info: ClientInfo::gather(),
base_url: Url::parse(
&format!("http://{}:{}", master_server, MASTER_PORT)
).unwrap(),
@ -58,28 +69,90 @@ impl ClientHandler {
self.set_pwd(rb)
}
pub async fn init(&self) -> RawMsg { // move to result
let response: Response = self.build_post("/new")
.json(&self.cli_info.as_message())
pub async fn init(&self, param: &ClientInfo) -> UResult<RawMsg> {
let response: Response = self.build_post(Paths::NEW)
.json(&param.as_message())
.send()
.await
.unwrap();
.await?;
let msg = response
.json::<Message<RawMsg>>()
.await
.unwrap();
msg.into_item().into_owned()
.await?;
Ok(msg.into_item().into_owned())
}
pub async fn list(&self) -> Vec<ClientInfo> {
let response: Response = self.build_get("/ls")
pub async fn list(&self) -> UResult<Vec<ClientInfo>> {
let response: Response = self.build_get(Paths::LIST)
.send()
.await
.unwrap();
.await?;
let msg = response
.json::<Message<Vec<ClientInfo>>>()
.await
.unwrap();
msg.into_item().into_owned()
.await?;
Ok(msg.into_item().into_owned())
}
/*
pub async fn del(&self) -> UResult<()> {
self.build_post(Paths::DEL).send().await?;
Ok(())
}*/
}
// build_handler![path = new, method = "post", param = ClientInfo, result = RawMsg]
// param and result must impl ToMsg
macro_rules! build_handler {
(
path = $path:tt,
method = $method:literal,
param = $param:ty,
result = $result:ty
) => {
impl ClientHandler {
pub async fn $path(&self, param: &$param) -> UResult<$result> {
let builder = match $method {
"post" => ClientHandler::build_post,
"get" => ClientHandler::build_get,
_ => panic!("Method '{}' is not allowed", $method)
};
let base_request = builder(self, stringify!($path));
let request = if let Some(p) = (param as &dyn Any).downcast_ref::<EmptyMsg>() {
base_request
} else {
base_request.json(&param.as_message())
};
let response = request.send().await?;
let msg = response
.json::<Message<$result>>()
.await?;
Ok(msg.into_item().into_owned())
}
}
impl Paths {
pub const $path: &'static str = stringify!($path);
}
};
(
path = $path:tt,
method = $method:literal
) => (
build_handler!(path = $path, method = $method, param = EmptyMsg, result = EmptyMsg);
);
(
path = $path:tt,
method = $method:literal,
param = $param:ty
) => (
build_handler!(path = $path, method = $method, param = $param, result = EmptyMsg);
);
(
path = $path:tt,
method = $method:literal,
result = $result:ty
) => (
build_handler!(path = $path, method = $method, param = EmptyMsg, result = $result);
);
}
build_handler!(path = del, method = "post");

@ -10,7 +10,7 @@ use serde::{
use uuid::Uuid;
//use tokio::process::Command;
use super::*;
use crate::UError;
use crate::{UError, UErrType};
#[derive(Serialize, Deserialize, Clone, Debug)]
@ -61,10 +61,9 @@ pub struct JobMeta {
impl JobMeta {
pub fn from_shell(shell_cmd: String) -> Self {
let uid = Uuid::new_v4();
let job_name = shell_cmd.split(" ").nth(0).unwrap();
Self {
id: uid.clone(),
id: Uuid::new_v4(),
name: job_name.to_string(),
created: SystemTime::now(),
updated: SystemTime::now(),
@ -154,8 +153,8 @@ impl ToMsg for JobResult {}
pub struct Job<'meta> {
pub result: JobResult,
pub meta: &'meta mut JobMeta,
result: JobResult,
meta: &'meta mut JobMeta,
}
impl<'meta> Job<'meta> {
@ -210,7 +209,7 @@ impl<'meta> Job<'meta> {
}
Err(e) => {
self.result.data = Err(
UError::Raw(e.to_string())
UError::new(UErrType::JobError, Some(e))
);
self.result.retcode = None;
}
@ -248,7 +247,10 @@ impl<'meta> Job<'meta> {
#[cfg(test)]
mod tests {
use super::*;
use crate::execute_jobs;
use crate::{
execute_jobs,
utils::vec_to_string
};
#[test]
fn test_shell_job() {
@ -257,8 +259,8 @@ mod tests {
execute_jobs(&mut jobs);
let job_result = jobs.pop().unwrap().into_result();
assert_eq!(
job_result.data.unwrap().stdout,
b"plazmoid\n".to_vec()
&vec_to_string(&job_result.data.unwrap().stdout),
"plazmoid"
);
}
@ -271,4 +273,45 @@ mod tests {
assert!(job_result.data.is_err());
assert_eq!(job_result.retcode, None);
}
#[test]
fn test_to_multiline() {
let mut output = JobOutput::new();
output.stdout = b"lol".to_vec();
output.stderr = b"kek".to_vec();
assert_eq!(
output.multiline(),
String::from(
"*** STDOUT ***\n\
lol\n\
*** STDERR ***\n\
kek\n"
)
)
}
#[test]
fn test_to_multiline_stderr_only() {
let mut output = JobOutput::new();
output.stderr = b"kek".to_vec();
assert_eq!(
output.multiline(),
String::from(
"*** STDERR ***\n\
kek\n"
)
)
}
#[test]
fn test_from_multiline() {
let txt = "*** STDOUT ***\n\
puk\n".to_string();
let output = JobOutput::from_multiline(&txt).unwrap();
assert_eq!(
output.stdout,
b"puk".to_vec()
);
assert_eq!(output.stderr.len(), 0);
}
}

@ -54,7 +54,10 @@ where I: Clone {
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RawMsg(pub String);
impl ToMsg for RawMsg {}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct EmptyMsg;
/*
#[cfg(test)]

@ -13,9 +13,11 @@ use std::{
borrow::Cow
};
macro_rules! to_message {
($($type:ty),+) => { $(
impl ToMsg for $type {}
macro_rules! to_cow {
($type:ty) => {
impl<'cow> From<$type> for Cow<'cow, $type> {
#[inline]
fn from(obj: $type) -> Cow<'cow, $type> {
@ -28,9 +30,8 @@ macro_rules! to_cow {
fn from(obj: &'cow $type) -> Cow<'cow, $type> {
Cow::Borrowed(obj)
}
}
} )+
}
}
to_cow!(ClientInfo);
to_cow!(RawMsg);
to_message!(ClientInfo, RawMsg, EmptyMsg);

@ -1,27 +1,87 @@
use std::fmt;
use std::error::Error as StdError;
use reqwest::Error as ReqError;
use serde::{
Serialize,
Deserialize
};
#[derive(Serialize, Deserialize, Clone)]
pub enum UError {
pub type BoxError = Box<(dyn StdError + Send + Sync + 'static)>;
pub type UResult<T> = std::result::Result<T, UError>;
#[derive(Serialize, Deserialize, Clone, Debug)]
pub enum UErrType {
ConnectionError,
ParseError,
JobError,
Unknown,
Raw(String)
}
#[derive(Serialize, Deserialize, Clone, Debug)]
struct Inner {
err_type: UErrType,
source: Option<BoxError>
}
#[derive(Serialize, Deserialize, Clone)]
pub struct UError {
inner: Box<Inner>
}
impl UError {
pub fn description(&self) -> String {
match self {
UError::Raw(msg) => msg.clone()
pub fn new<E: Into<BoxError>>(err_type: UErrType, source: Option<E>) -> Self {
Self {
inner: Box::new(Inner {
source: source.map(Into::into),
err_type
})
}
}
}
impl fmt::Debug for UError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match self {
UError::Raw(msg) => msg
let mut builder = f.debug_struct("errors::UError");
builder.field("kind", &self.inner.err_type);
if let Some(ref source) = self.inner.source {
builder.field("source", source);
}
builder.finish()
}
}
impl fmt::Display for UError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let e_type = match self.inner.err_type {
UErrType::Raw(ref msg) => msg,
UErrType::ConnectionError => "Connection error",
UErrType::ParseError => "Parse error",
UErrType::JobError => "Job error",
UErrType::Unknown => "Unknown error",
};
f.write_str(e_type)?;
if let Some(ref e) = self.inner.source {
write!(f, ": {}", e)
} else {
Ok(())
}
}
}
impl From<ReqError> for UError {
fn from(e: ReqError) -> Self {
let err_type = if e.is_request() {
UErrType::ConnectionError
} else if e.is_decode() {
UErrType::ParseError
} else {
UErrType::Unknown
};
write!(f, "{}", msg)
UError::new(err_type, Some(e))
}
}

@ -45,6 +45,11 @@ pub fn setsig(sig: Signal, hnd: SigHandler) {
signal(sig, hnd).unwrap();
}
}
pub fn vec_to_string(v: &Vec<u8>) -> String {
String::from_utf8_lossy(v).to_string()
}
/*
pub fn generate_auth_token() -> String {

Loading…
Cancel
Save