parent
f06b284b85
commit
2b4be3dab8
30
src/lib.rs
30
src/lib.rs
|
@ -1,14 +1,26 @@
|
||||||
use axum::{
|
use std::sync::{Arc, Mutex};
|
||||||
routing::{get, post},
|
|
||||||
Router,
|
use axum::{routing::post, Router};
|
||||||
};
|
use routes::challenge;
|
||||||
use routes::{echo, root};
|
|
||||||
|
|
||||||
pub mod messages;
|
pub mod messages;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
pub fn app() -> Router {
|
type AppState = Arc<Mutex<IdCounter>>;
|
||||||
Router::new()
|
|
||||||
.route("/", get(root))
|
#[derive(Debug, Default)]
|
||||||
.route("/echo", post(echo))
|
pub struct IdCounter {
|
||||||
|
value: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IdCounter {
|
||||||
|
fn next(&mut self) -> u64 {
|
||||||
|
let current = self.value;
|
||||||
|
self.value += 1;
|
||||||
|
current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn app() -> Router {
|
||||||
|
let state = AppState::default();
|
||||||
|
Router::new().route("/", post(challenge)).with_state(state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use echo::app;
|
use echo::app;
|
||||||
|
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let binding = "0.0.0.0:3000";
|
let binding = "0.0.0.0:3000";
|
||||||
info!("Creating Axum at: {binding}");
|
info!("Creating Axum at: {binding}");
|
||||||
let listener = tokio::net::TcpListener::bind(&binding).await?;
|
let listener = tokio::net::TcpListener::bind(&binding).await?;
|
||||||
|
|
|
@ -1,30 +1,68 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct EchoRequest {
|
pub enum MessageBody {
|
||||||
pub src: String,
|
EchoRequest(EchoRequest),
|
||||||
pub dest: String,
|
EchoResponse(EchoResponse),
|
||||||
pub body: BodyRequest,
|
GenerateRequest(GenerateRequest),
|
||||||
|
GenerateResponse(GenerateResponse),
|
||||||
|
Default,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct BodyRequest {
|
pub struct Message {
|
||||||
pub r#type: String,
|
|
||||||
pub msg_id: u32,
|
|
||||||
pub echo: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
|
||||||
pub struct EchoResponse {
|
|
||||||
pub src: String,
|
pub src: String,
|
||||||
pub dest: String,
|
pub dest: String,
|
||||||
pub body: BodyResponse,
|
pub body: MessageBody,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
impl Default for Message {
|
||||||
pub struct BodyResponse {
|
fn default() -> Self {
|
||||||
pub r#type: String,
|
let src = "".to_string();
|
||||||
pub msg_id: u32,
|
let dest = "".to_string();
|
||||||
pub in_reply_to: u32,
|
let body = MessageBody::Default;
|
||||||
|
Message { src, dest, body }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct EchoRequest {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub response_type: String,
|
||||||
|
pub msg_id: u64,
|
||||||
pub echo: String,
|
pub echo: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl EchoRequest {
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
"EchoRequest".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct EchoResponse {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub response_type: String,
|
||||||
|
pub msg_id: u64,
|
||||||
|
pub in_reply_to: u64,
|
||||||
|
pub echo: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GenerateRequest {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub response_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GenerateRequest {
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
"GenerateRequest".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GenerateResponse {
|
||||||
|
#[serde(rename = "type")]
|
||||||
|
pub response_type: String,
|
||||||
|
pub id: u64,
|
||||||
|
}
|
||||||
|
|
|
@ -1,35 +1,89 @@
|
||||||
use axum::{http::StatusCode, Json};
|
use axum::{extract::State, http::StatusCode, Json};
|
||||||
use tracing::{debug, error};
|
use tracing::error;
|
||||||
|
|
||||||
use crate::messages::{BodyResponse, EchoRequest, EchoResponse};
|
use crate::{
|
||||||
|
messages::{EchoResponse, GenerateResponse, Message, MessageBody},
|
||||||
|
AppState,
|
||||||
|
};
|
||||||
|
|
||||||
pub async fn root() -> &'static str {
|
pub async fn root() -> &'static str {
|
||||||
"Hello, World!"
|
"Hello, World!"
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn echo(Json(payload): Json<EchoRequest>) -> (StatusCode, Json<EchoResponse>) {
|
pub async fn challenge(
|
||||||
if payload.body.r#type != "echo" {
|
State(state): State<AppState>,
|
||||||
error!("Error.");
|
Json(payload): Json<Message>,
|
||||||
return (StatusCode::BAD_REQUEST, Json(EchoResponse::default()));
|
) -> (StatusCode, Json<Message>) {
|
||||||
}
|
let response: Message = {
|
||||||
let response: EchoResponse = {
|
|
||||||
let src = payload.dest;
|
let src = payload.dest;
|
||||||
let dest = payload.src;
|
let dest = payload.src;
|
||||||
let body = {
|
let body: MessageBody = match payload.body {
|
||||||
let r#type = "echo_ok".to_string();
|
MessageBody::EchoRequest(r) => {
|
||||||
let msg_id = payload.body.msg_id;
|
if r.response_type != "echo" {
|
||||||
let in_reply_to = payload.body.msg_id;
|
error!(
|
||||||
let echo = payload.body.echo;
|
"Invalid response_type {} for {}",
|
||||||
BodyResponse {
|
&r.response_type,
|
||||||
r#type,
|
r.name()
|
||||||
msg_id,
|
);
|
||||||
in_reply_to,
|
return (StatusCode::BAD_REQUEST, Json(Message::default()));
|
||||||
echo,
|
}
|
||||||
|
|
||||||
|
let response_type = "echo_ok".to_string();
|
||||||
|
let msg_id = r.msg_id;
|
||||||
|
let in_reply_to = r.msg_id;
|
||||||
|
let echo = r.echo;
|
||||||
|
|
||||||
|
MessageBody::EchoResponse(EchoResponse {
|
||||||
|
response_type,
|
||||||
|
msg_id,
|
||||||
|
in_reply_to,
|
||||||
|
echo,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
MessageBody::GenerateRequest(r) => {
|
||||||
|
if r.response_type != "generate" {
|
||||||
|
error!(
|
||||||
|
"Invalid response_type {} for {}",
|
||||||
|
&r.response_type,
|
||||||
|
r.name()
|
||||||
|
);
|
||||||
|
return (StatusCode::BAD_REQUEST, Json(Message::default()));
|
||||||
|
}
|
||||||
|
let response_type = "generate_ok".to_string();
|
||||||
|
let id = { state.lock().unwrap().next() };
|
||||||
|
MessageBody::GenerateResponse(GenerateResponse { response_type, id })
|
||||||
|
}
|
||||||
|
MessageBody::EchoResponse(_r) => {
|
||||||
|
return (StatusCode::BAD_REQUEST, Json(Message::default()))
|
||||||
|
}
|
||||||
|
MessageBody::GenerateResponse(_r) => {
|
||||||
|
return (StatusCode::BAD_REQUEST, Json(Message::default()))
|
||||||
|
}
|
||||||
|
MessageBody::Default => return (StatusCode::BAD_REQUEST, Json(Message::default())),
|
||||||
};
|
};
|
||||||
EchoResponse { src, dest, body }
|
|
||||||
|
Message { src, dest, body }
|
||||||
};
|
};
|
||||||
let json = serde_json::to_string_pretty(&response).unwrap();
|
|
||||||
debug!("Response: {json}");
|
|
||||||
(StatusCode::OK, Json(response))
|
(StatusCode::OK, Json(response))
|
||||||
|
|
||||||
|
// let response: MessageResponse = {
|
||||||
|
// let src = payload.dest;
|
||||||
|
// let dest = payload.src;
|
||||||
|
// let body = {
|
||||||
|
// let r#type = "echo_ok".to_string();
|
||||||
|
// let msg_id = payload.body.msg_id;
|
||||||
|
// let in_reply_to = payload.body.msg_id;
|
||||||
|
// let echo = payload.body.echo;
|
||||||
|
// BodyResponse {
|
||||||
|
// r#type,
|
||||||
|
// msg_id,
|
||||||
|
// in_reply_to,
|
||||||
|
// echo,
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
// MessageResponse { src, dest, body }
|
||||||
|
// };
|
||||||
|
// let json = serde_json::to_string_pretty(&response).unwrap();
|
||||||
|
// debug!("Response: {json}");
|
||||||
|
// (StatusCode::OK, Json(response))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use axum::http::{self, Request, StatusCode};
|
use axum::http::{self, Request, StatusCode};
|
||||||
use echo::{
|
use echo::{
|
||||||
app,
|
app,
|
||||||
messages::{BodyRequest, EchoRequest},
|
messages::{EchoRequest, Message, MessageBody},
|
||||||
};
|
};
|
||||||
use http_body_util::BodyExt;
|
use http_body_util::BodyExt;
|
||||||
use serde_json::{json, Value};
|
use serde_json::{json, Value};
|
||||||
|
@ -11,18 +11,18 @@ use tracing::info;
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn specification() {
|
async fn specification() {
|
||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
let request = {
|
let request: Message = {
|
||||||
let src = "c1".to_string();
|
let src = "c1".to_string();
|
||||||
let dest = "n1".to_string();
|
let dest = "n1".to_string();
|
||||||
let r#type = "echo".to_string();
|
let response_type = "echo".to_string();
|
||||||
let msg_id = 1;
|
let msg_id = 1;
|
||||||
let echo = "Please echo 35".to_string();
|
let echo = "Please echo 35".to_string();
|
||||||
let body = BodyRequest {
|
let body = MessageBody::EchoRequest(EchoRequest {
|
||||||
r#type,
|
response_type,
|
||||||
msg_id,
|
msg_id,
|
||||||
echo,
|
echo,
|
||||||
};
|
});
|
||||||
EchoRequest { src, dest, body }
|
Message { src, dest, body }
|
||||||
};
|
};
|
||||||
let body = serde_json::to_string_pretty(&request).unwrap();
|
let body = serde_json::to_string_pretty(&request).unwrap();
|
||||||
info!("Request: {body}");
|
info!("Request: {body}");
|
Loading…
Reference in New Issue