(rust) **very** basic restapi with axum

This commit is contained in:
scbj
2025-09-18 10:39:50 +02:00
parent 1e7c7d7cba
commit 28a1d3dada
2 changed files with 50 additions and 67 deletions
+1
View File
@@ -5,6 +5,7 @@ edition = "2021"
[dependencies]
anyhow = "1.0"
axum = "0.8.4"
chrono = { version = "0.4.41", features = ["serde"] }
ciborium = "0.2.2"
clap = { version = "4.5.0", features = ["derive"] }
+43 -61
View File
@@ -1,81 +1,63 @@
#![allow(dead_code, unused)]
use axum::{extract::{Extension, Json, Path}, routing::{get, post}, Router};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tokio::{fs, net::TcpListener, sync::mpsc};
fn main() -> anyhow::Result<()> {
let test_address: MacAddress = MacAddress::from_array([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]);
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Status {
pub id: u64,
pub name: String,
pub data: Vec<u8>,
}
println!("as string: {}", test_address.to_string());
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let (log_sender, mut log_receiver): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel(4);
let listener: TcpListener = TcpListener::bind("127.0.0.1:8080").await?;
let service: Router = Router::new()
.route("/", get(|| async {"hier ist nichts"}))
.route("/status", get(get_status).post(create_status))
.layer(Extension(log_sender));
tokio::spawn(log_task(log_receiver));
axum::serve(listener, service).await.unwrap();
Ok(())
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MacAddress {
bytes: [u8;6],
}
impl MacAddress {
pub fn new() -> Self {
Self {
bytes: [0u8;6],
}
}
pub fn from_array(bytes: [u8;6]) -> Self {
Self {
bytes: bytes,
}
}
pub fn from_str(string: &str) -> std::io::Result<Self> {
let mut address: Self = Self::new();
let bytes: Vec<&str> = string.split(":").collect();
if bytes.len() != address.bytes.len() {
return Err(std::io::Error::other("invalid length or format for mac address"));
}
for (index, byte) in bytes.iter().enumerate() {
address.bytes[index] = match u8::from_str_radix(byte, 16) {
async fn get_status(Extension(logger): Extension<mpsc::Sender<String>>) -> Json<String> {
let input: String = match fs::read_to_string("./test_status.json").await {
Ok(value) => value,
Err(error) => return Err(std::io::Error::other(error.to_string())),
Err(error) => {
_ = logger.send(format!("no file `test_status.json` found")).await;
return Json(format!("failed to read status: {}", error));
}
};
}
Ok(address)
}
pub fn from_string(string: &String) -> std::io::Result<Self> {
let mut address: Self = Self::new();
let bytes: Vec<&str> = string.split(":").collect();
println!("debug: {:#?}", bytes);
if bytes.len() != address.bytes.len() {
return Err(std::io::Error::other("invalid length or format for mac address"));
}
for (index, byte) in bytes.iter().enumerate() {
address.bytes[index] = match u8::from_str_radix(byte, 16) {
let mut status: Vec<Status> = match serde_json::from_str(&input) {
Ok(value) => value,
Err(error) => return Err(std::io::Error::other(error.to_string())),
Err(error) => {
_ = logger.send(format!("can't parse file `test_status.json`")).await;
return Json(format!("failed to parse 'json' file: {}", error));
}
};
Json(serde_json::to_string_pretty(&status).unwrap())
}
Ok(address)
async fn create_status(Extension(logger): Extension<mpsc::Sender<String>>) -> Json<String> {
_ = logger.send(format!("BLARGH?")).await;
Json(format!("PATIENCE!"))
}
pub fn to_string(&self) -> String {
let mut string: String = String::new();
for (index, byte) in self.bytes.iter().enumerate() {
string.push_str(&format!("{:02x?}", byte));
if index < self.bytes.len() - 1 {
string.push_str(":");
async fn log_task(mut receiver: mpsc::Receiver<String>) -> () {
while !receiver.is_closed() {
match receiver.recv().await {
Some(log) => println!("{log}"),
None => break,
}
}
string
}
}