forked from github-starred/komodo
work to make backend Req -> Res typesafe using Resolve trait
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
extern crate log;
|
||||
|
||||
use anyhow::{anyhow, Context};
|
||||
use monitor_types::{HasResponse, periphery_api::requests};
|
||||
use monitor_types::api::{periphery::requests, HasResponse};
|
||||
use reqwest::StatusCode;
|
||||
use serde_json::json;
|
||||
|
||||
|
||||
@@ -8,8 +8,11 @@ license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
axum.workspace = true
|
||||
diff-struct.workspace = true
|
||||
typeshare.workspace = true
|
||||
strum.workspace = true
|
||||
strum_macros.workspace = true
|
||||
async-trait.workspace = true
|
||||
async-trait.workspace = true
|
||||
anyhow.workspace = true
|
||||
41
lib/types/src/api/mod.rs
Normal file
41
lib/types/src/api/mod.rs
Normal file
@@ -0,0 +1,41 @@
|
||||
use anyhow::Context;
|
||||
use axum::{headers::ContentType, http::StatusCode, TypedHeader};
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
pub mod core;
|
||||
pub mod periphery;
|
||||
|
||||
pub trait HasResponse: Serialize + DeserializeOwned + std::fmt::Debug + Send + 'static {
|
||||
type Response: Serialize + DeserializeOwned + std::fmt::Debug;
|
||||
fn req_type() -> &'static str;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait Resolve<Req: HasResponse> {
|
||||
async fn resolve(&self, req: Req) -> anyhow::Result<Req::Response>;
|
||||
async fn resolve_to_response(
|
||||
&self,
|
||||
req: Req,
|
||||
) -> Result<(TypedHeader<ContentType>, String), (StatusCode, String)> {
|
||||
let res = self
|
||||
.resolve(req)
|
||||
.await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:#?}")))?;
|
||||
let res = serde_json::to_string(&res)
|
||||
.context("failed at serializing response")
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("{e:#?}")))?;
|
||||
Ok((TypedHeader(ContentType::json()), res))
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_has_response {
|
||||
($req:ty, $res:ty) => {
|
||||
impl $crate::api::HasResponse for $req {
|
||||
type Response = $res;
|
||||
fn req_type() -> &'static str {
|
||||
stringify!($req)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::SystemCommand;
|
||||
use crate::entities::SystemCommand;
|
||||
|
||||
use self::requests::{GetHealth, GetVersion, GetSystemInformation, GetBasicSystemStats, GetDiskUsage, GetNetworkUsage, GetSystemProcesses, GetAllSystemStats, GetSystemComponents, GetCpuUsage};
|
||||
use self::requests::{
|
||||
GetAllSystemStats, GetBasicSystemStats, GetCpuUsage, GetDiskUsage, GetHealth, GetNetworkUsage,
|
||||
GetSystemComponents, GetSystemInformation, GetSystemProcesses, GetVersion,
|
||||
};
|
||||
|
||||
pub mod requests;
|
||||
|
||||
@@ -1,2 +1,129 @@
|
||||
use diff::Diff;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::{Display, EnumString};
|
||||
use typeshare::typeshare;
|
||||
|
||||
pub mod server;
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, Diff)]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub struct SystemCommand {
|
||||
#[serde(default)]
|
||||
pub path: String,
|
||||
#[serde(default)]
|
||||
pub command: String,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Debug,
|
||||
Display,
|
||||
EnumString,
|
||||
PartialEq,
|
||||
Hash,
|
||||
Eq,
|
||||
Clone,
|
||||
Copy,
|
||||
Diff,
|
||||
Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub enum Timelength {
|
||||
#[serde(rename = "1-sec")]
|
||||
#[strum(serialize = "1-sec")]
|
||||
OneSecond,
|
||||
#[serde(rename = "5-sec")]
|
||||
#[strum(serialize = "5-sec")]
|
||||
FiveSeconds,
|
||||
#[serde(rename = "10-sec")]
|
||||
#[strum(serialize = "10-sec")]
|
||||
TenSeconds,
|
||||
#[serde(rename = "15-sec")]
|
||||
#[strum(serialize = "15-sec")]
|
||||
FifteenSeconds,
|
||||
#[serde(rename = "30-sec")]
|
||||
#[strum(serialize = "30-sec")]
|
||||
ThirtySeconds,
|
||||
#[default]
|
||||
#[serde(rename = "1-min")]
|
||||
#[strum(serialize = "1-min")]
|
||||
OneMinute,
|
||||
#[serde(rename = "2-min")]
|
||||
#[strum(serialize = "2-min")]
|
||||
TwoMinutes,
|
||||
#[serde(rename = "5-min")]
|
||||
#[strum(serialize = "5-min")]
|
||||
FiveMinutes,
|
||||
#[serde(rename = "10-min")]
|
||||
#[strum(serialize = "10-min")]
|
||||
TenMinutes,
|
||||
#[serde(rename = "15-min")]
|
||||
#[strum(serialize = "15-min")]
|
||||
FifteenMinutes,
|
||||
#[serde(rename = "30-min")]
|
||||
#[strum(serialize = "30-min")]
|
||||
ThirtyMinutes,
|
||||
#[serde(rename = "1-hr")]
|
||||
#[strum(serialize = "1-hr")]
|
||||
OneHour,
|
||||
#[serde(rename = "2-hr")]
|
||||
#[strum(serialize = "2-hr")]
|
||||
TwoHours,
|
||||
#[serde(rename = "6-hr")]
|
||||
#[strum(serialize = "6-hr")]
|
||||
SixHours,
|
||||
#[serde(rename = "8-hr")]
|
||||
#[strum(serialize = "8-hr")]
|
||||
EightHours,
|
||||
#[serde(rename = "12-hr")]
|
||||
#[strum(serialize = "12-hr")]
|
||||
TwelveHours,
|
||||
#[serde(rename = "1-day")]
|
||||
#[strum(serialize = "1-day")]
|
||||
OneDay,
|
||||
#[serde(rename = "3-day")]
|
||||
#[strum(serialize = "3-day")]
|
||||
ThreeDay,
|
||||
#[serde(rename = "1-wk")]
|
||||
#[strum(serialize = "1-wk")]
|
||||
OneWeek,
|
||||
#[serde(rename = "2-wk")]
|
||||
#[strum(serialize = "2-wk")]
|
||||
TwoWeeks,
|
||||
#[serde(rename = "30-day")]
|
||||
#[strum(serialize = "30-day")]
|
||||
ThirtyDays,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Debug,
|
||||
Display,
|
||||
EnumString,
|
||||
Hash,
|
||||
Clone,
|
||||
Copy,
|
||||
Diff,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub enum PermissionLevel {
|
||||
#[default]
|
||||
None,
|
||||
Read,
|
||||
Execute,
|
||||
Update,
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use typeshare::typeshare;
|
||||
|
||||
use crate::{I64, Timelength};
|
||||
use crate::I64;
|
||||
|
||||
use super::Timelength;
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||
@@ -119,4 +121,4 @@ pub struct SystemComponent {
|
||||
pub max: f32,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub critical: Option<f32>,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,157 +1,7 @@
|
||||
use diff::Diff;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use strum_macros::{Display, EnumString};
|
||||
use typeshare::typeshare;
|
||||
|
||||
pub mod core_api;
|
||||
pub mod api;
|
||||
pub mod entities;
|
||||
pub mod periphery_api;
|
||||
|
||||
#[typeshare(serialized_as = "number")]
|
||||
pub type I64 = i64;
|
||||
|
||||
#[typeshare]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Default, PartialEq, Eq, Diff)]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub struct SystemCommand {
|
||||
#[serde(default)]
|
||||
pub path: String,
|
||||
#[serde(default)]
|
||||
pub command: String,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Debug,
|
||||
Display,
|
||||
EnumString,
|
||||
PartialEq,
|
||||
Hash,
|
||||
Eq,
|
||||
Clone,
|
||||
Copy,
|
||||
Diff,
|
||||
Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub enum Timelength {
|
||||
#[serde(rename = "1-sec")]
|
||||
#[strum(serialize = "1-sec")]
|
||||
OneSecond,
|
||||
#[serde(rename = "5-sec")]
|
||||
#[strum(serialize = "5-sec")]
|
||||
FiveSeconds,
|
||||
#[serde(rename = "10-sec")]
|
||||
#[strum(serialize = "10-sec")]
|
||||
TenSeconds,
|
||||
#[serde(rename = "15-sec")]
|
||||
#[strum(serialize = "15-sec")]
|
||||
FifteenSeconds,
|
||||
#[serde(rename = "30-sec")]
|
||||
#[strum(serialize = "30-sec")]
|
||||
ThirtySeconds,
|
||||
#[default]
|
||||
#[serde(rename = "1-min")]
|
||||
#[strum(serialize = "1-min")]
|
||||
OneMinute,
|
||||
#[serde(rename = "2-min")]
|
||||
#[strum(serialize = "2-min")]
|
||||
TwoMinutes,
|
||||
#[serde(rename = "5-min")]
|
||||
#[strum(serialize = "5-min")]
|
||||
FiveMinutes,
|
||||
#[serde(rename = "10-min")]
|
||||
#[strum(serialize = "10-min")]
|
||||
TenMinutes,
|
||||
#[serde(rename = "15-min")]
|
||||
#[strum(serialize = "15-min")]
|
||||
FifteenMinutes,
|
||||
#[serde(rename = "30-min")]
|
||||
#[strum(serialize = "30-min")]
|
||||
ThirtyMinutes,
|
||||
#[serde(rename = "1-hr")]
|
||||
#[strum(serialize = "1-hr")]
|
||||
OneHour,
|
||||
#[serde(rename = "2-hr")]
|
||||
#[strum(serialize = "2-hr")]
|
||||
TwoHours,
|
||||
#[serde(rename = "6-hr")]
|
||||
#[strum(serialize = "6-hr")]
|
||||
SixHours,
|
||||
#[serde(rename = "8-hr")]
|
||||
#[strum(serialize = "8-hr")]
|
||||
EightHours,
|
||||
#[serde(rename = "12-hr")]
|
||||
#[strum(serialize = "12-hr")]
|
||||
TwelveHours,
|
||||
#[serde(rename = "1-day")]
|
||||
#[strum(serialize = "1-day")]
|
||||
OneDay,
|
||||
#[serde(rename = "3-day")]
|
||||
#[strum(serialize = "3-day")]
|
||||
ThreeDay,
|
||||
#[serde(rename = "1-wk")]
|
||||
#[strum(serialize = "1-wk")]
|
||||
OneWeek,
|
||||
#[serde(rename = "2-wk")]
|
||||
#[strum(serialize = "2-wk")]
|
||||
TwoWeeks,
|
||||
#[serde(rename = "30-day")]
|
||||
#[strum(serialize = "30-day")]
|
||||
ThirtyDays,
|
||||
}
|
||||
|
||||
#[typeshare]
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Debug,
|
||||
Display,
|
||||
EnumString,
|
||||
Hash,
|
||||
Clone,
|
||||
Copy,
|
||||
Diff,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Default,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
#[diff(attr(#[derive(Debug, PartialEq, Serialize)]))]
|
||||
pub enum PermissionLevel {
|
||||
#[default]
|
||||
None,
|
||||
Read,
|
||||
Execute,
|
||||
Update,
|
||||
}
|
||||
|
||||
pub trait HasResponse: Serialize + std::fmt::Debug {
|
||||
type Response: DeserializeOwned + std::fmt::Debug;
|
||||
fn req_type() -> &'static str;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait Resolve<Req: HasResponse> {
|
||||
async fn resolve(&self, req: Req) -> Req::Response;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_has_response {
|
||||
($req:ty, $res:ty) => {
|
||||
impl $crate::HasResponse for $req {
|
||||
type Response = $res;
|
||||
fn req_type() -> &'static str {
|
||||
stringify!($req)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user