A lot of stuff, too lazy to name it all
This commit is contained in:
parent
ceadd2d76d
commit
83d712b930
15 changed files with 273 additions and 0 deletions
0
src/hashes.rs
Normal file
0
src/hashes.rs
Normal file
16
src/protocol/error.rs
Normal file
16
src/protocol/error.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
use std::num::ParseFloatError;
|
||||
use nom::error::VerboseError;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum Error<I: std::fmt::Debug> {
|
||||
#[error("Oops it blew up")]
|
||||
NomError(#[from] nom::Err<VerboseError<I>>),
|
||||
|
||||
#[error("Oops it blew up")]
|
||||
TimestampParseError(ParseFloatError),
|
||||
|
||||
#[error("Oops it blew up")]
|
||||
UnknownUnit(I)
|
||||
}
|
0
src/protocol/mod.rs
Normal file
0
src/protocol/mod.rs
Normal file
42
src/protocol/packet_types.rs
Normal file
42
src/protocol/packet_types.rs
Normal file
|
@ -0,0 +1,42 @@
|
|||
use std::borrow::Cow;
|
||||
use std::collections::HashSet;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use hifitime::Epoch;
|
||||
use rust_decimal::Decimal;
|
||||
use crate::hashes::SupportedUnit;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NarodMonValues<'a> {
|
||||
pub mac: Cow<'a, str>,
|
||||
pub value: Decimal,
|
||||
pub time: Option<Epoch>,
|
||||
pub unit: Option<SupportedUnit>,
|
||||
pub name: Option<Cow<'a, str>>,
|
||||
}
|
||||
|
||||
impl<'a> Hash for NarodMonValues<'a> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.mac.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PartialEq for NarodMonValues<'a> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.mac == other.mac
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Eq for NarodMonValues<'a> {
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct NarodMonPacket<'a> {
|
||||
pub mac: [u8; 6],
|
||||
pub name: Option<Cow<'a, str>>,
|
||||
pub values: HashSet<NarodMonValues<'a>>,
|
||||
pub owner: Option<Cow<'a, str>>,
|
||||
pub lat: Option<Decimal>,
|
||||
pub lon: Option<Decimal>,
|
||||
pub alt: Option<Decimal>
|
||||
}
|
0
src/protocol/parser.rs
Normal file
0
src/protocol/parser.rs
Normal file
0
src/protocol/server.rs
Normal file
0
src/protocol/server.rs
Normal file
88
src/web_server/app_error.rs
Normal file
88
src/web_server/app_error.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
use std::borrow::Cow;
|
||||
use axum::headers::HeaderValue;
|
||||
use axum::http::StatusCode;
|
||||
use axum::Json;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use fred::prelude::*;
|
||||
|
||||
|
||||
use rust_decimal::Decimal;
|
||||
use serde_json::json;
|
||||
use thiserror::Error;
|
||||
use ufmt::derive::uDebug;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AppError {
|
||||
#[error("IDK")]
|
||||
JsonError(#[from] serde_json::Error),
|
||||
|
||||
#[error("IDK")]
|
||||
ServerRedisError(#[from] RedisError),
|
||||
|
||||
#[error("Fuck")]
|
||||
UnknownMethod(String),
|
||||
|
||||
#[error("Fuck")]
|
||||
RequestTooLarge,
|
||||
|
||||
#[error("Fuck")]
|
||||
UnitValidationFailed {
|
||||
max: Option<Decimal>,
|
||||
min: Option<Decimal>
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoResponse for AppError {
|
||||
fn into_response(self) -> Response {
|
||||
|
||||
|
||||
let (status, error_message) = match self {
|
||||
AppError::JsonError(_) => {
|
||||
(StatusCode::BAD_REQUEST, "Invalid JSON")
|
||||
},
|
||||
AppError::UnknownMethod(_) => {
|
||||
(StatusCode::BAD_REQUEST, "Unknown command")
|
||||
},
|
||||
AppError::UnitValidationFailed { .. } => {
|
||||
(StatusCode::BAD_REQUEST, "Unknown command")
|
||||
},
|
||||
AppError::RequestTooLarge => {
|
||||
(StatusCode::PAYLOAD_TOO_LARGE, "Request is too large")
|
||||
},
|
||||
AppError::ServerRedisError(_) => {
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, "Internal server error")
|
||||
}
|
||||
};
|
||||
|
||||
let body = Json(json!({
|
||||
"errno": status.as_u16(),
|
||||
"error": error_message,
|
||||
}));
|
||||
|
||||
let mut resp = (status, body).into_response();
|
||||
let headers = resp.headers_mut();
|
||||
|
||||
let error_as_string= format!("{:?}", &self);
|
||||
|
||||
match self {
|
||||
AppError::JsonError(json_err) => {
|
||||
headers.insert("X-Error-Line", HeaderValue::from(json_err.line()));
|
||||
headers.insert("X-Error-Column", HeaderValue::from(json_err.column()));
|
||||
headers.insert("X-Error-Description", HeaderValue::try_from(json_err.to_string().escape_default().collect::<String>()).unwrap());
|
||||
},
|
||||
AppError::UnknownMethod(method) => {
|
||||
headers.insert("X-Unknown-Cmd", HeaderValue::try_from(method.escape_default().collect::<String>()).unwrap());
|
||||
},
|
||||
AppError::RequestTooLarge => {
|
||||
headers.insert("X-Max-Request-Size", HeaderValue::try_from("10 KiB = 10240 bytes").unwrap());
|
||||
},
|
||||
_ => {}
|
||||
};
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
headers.insert("X-Full-Error", HeaderValue::try_from(error_as_string).unwrap());
|
||||
}
|
||||
|
||||
resp
|
||||
}
|
||||
}
|
18
src/web_server/mod.rs
Normal file
18
src/web_server/mod.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use std::time::Duration;
|
||||
use tokio;
|
||||
use axum::{
|
||||
routing::get,
|
||||
Router,
|
||||
};
|
||||
use axum::error_handling::{HandleError, HandleErrorLayer};
|
||||
use axum::http::StatusCode;
|
||||
use crate::server::old_app_api::old_api_handler;
|
||||
|
||||
pub mod old_app_api;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct NMAppState {
|
||||
redis_client: RedisClient
|
||||
}
|
||||
|
||||
async fn main()
|
35
src/web_server/old_app_api/config_app.rs
Normal file
35
src/web_server/old_app_api/config_app.rs
Normal file
|
@ -0,0 +1,35 @@
|
|||
use std::borrow::Cow;
|
||||
use axum::body::{Body, Bytes, HttpBody};
|
||||
use axum::http::Request;
|
||||
use axum::Json;
|
||||
use axum::response::{IntoResponse, Response};
|
||||
use nom::AsBytes;
|
||||
use serde_json::Value;
|
||||
use crate::server::old_app_api::app_error::AppError;
|
||||
use crate::server::old_app_api::handlers::app_init;
|
||||
use crate::server::old_app_api::types::{AppInitRequest, MandatoryParams};
|
||||
|
||||
|
||||
pub async fn old_api_handler(
|
||||
body_bytes: Bytes,
|
||||
) -> Result<impl IntoResponse, AppError> {
|
||||
if body_bytes.len() > 10 * 1024 { // 10 KiB
|
||||
return Err(AppError::RequestTooLarge)
|
||||
}
|
||||
|
||||
let mandatory_params: MandatoryParams<'_> = serde_json::from_slice(body_bytes.as_bytes())?;
|
||||
|
||||
return match mandatory_params.cmd.as_ref() {
|
||||
"appInit" => {
|
||||
let body: AppInitRequest = serde_json::from_slice(body_bytes.as_bytes())?;
|
||||
|
||||
Ok(app_init(body).await)
|
||||
}
|
||||
_ => {
|
||||
Err(AppError::UnknownMethod(mandatory_params.cmd.to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
//Ok("fuck")
|
||||
}
|
||||
|
17
src/web_server/old_app_api/handlers/methods.rs
Normal file
17
src/web_server/old_app_api/handlers/methods.rs
Normal file
|
@ -0,0 +1,17 @@
|
|||
use axum::body::Body;
|
||||
use axum::extract::State;
|
||||
use axum::http::Request;
|
||||
use axum::Json;
|
||||
use axum::response::IntoResponse;
|
||||
|
||||
use serde_json::Value as JsonValue;
|
||||
use crate::server::old_app_api::types::AppInitRequest;
|
||||
use heapless::String as HeaplessString;
|
||||
use ufmt::uwrite;
|
||||
|
||||
|
||||
pub async fn app_init(body: AppInitRequest<'_>, State(appState): State<>) -> impl IntoResponse {
|
||||
|
||||
|
||||
"Hello, World!"
|
||||
}
|
10
src/web_server/old_app_api/handlers/mod.rs
Normal file
10
src/web_server/old_app_api/handlers/mod.rs
Normal file
|
@ -0,0 +1,10 @@
|
|||
mod methods;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use axum::Json;
|
||||
use axum::response::IntoResponse;
|
||||
use phf::phf_map;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::hashes::SupportedUnit;
|
||||
pub use methods::*;
|
||||
|
7
src/web_server/old_app_api/mod.rs
Normal file
7
src/web_server/old_app_api/mod.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
mod types;
|
||||
mod handlers;
|
||||
mod config_app;
|
||||
mod app_error;
|
||||
|
||||
pub use config_app::old_api_handler;
|
||||
|
40
src/web_server/old_app_api/types/mod.rs
Normal file
40
src/web_server/old_app_api/types/mod.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
use std::borrow::Cow;
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use crate::hashes::SupportedUnit;
|
||||
|
||||
// fn<'de, D>(D) -> Result<T, D::Error> where D: Deserializer<'de>
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AppInitRequest<'a> {
|
||||
#[serde(borrow)]
|
||||
pub version: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub platform: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub model: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub width: Cow<'a, str>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct AddLikeRequest {
|
||||
pub version: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct MandatoryParams<'a> {
|
||||
#[serde(borrow)]
|
||||
pub cmd: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub lang: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub uuid: Cow<'a, str>,
|
||||
|
||||
#[serde(borrow)]
|
||||
pub api_key: Cow<'a, str>
|
||||
}
|
0
src/web_server/utils/mod.rs
Normal file
0
src/web_server/utils/mod.rs
Normal file
0
src/web_server/utils/redis.rs
Normal file
0
src/web_server/utils/redis.rs
Normal file
Loading…
Reference in a new issue