mirror of
https://github.com/tuono-labs/tuono
synced 2026-07-25 12:52:47 -07:00
feat: create body extractor function (#561)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use axum::http::{HeaderMap, Uri};
|
||||
@@ -51,4 +51,94 @@ impl Request {
|
||||
pub fn location(&self) -> Location {
|
||||
Location::from(self.uri.to_owned())
|
||||
}
|
||||
|
||||
pub fn body<'de, T: Deserialize<'de>>(&'de self) -> Result<T, BodyParseError> {
|
||||
if let Some(body) = self.headers.get("body") {
|
||||
if let Ok(body) = body.to_str() {
|
||||
let body = serde_json::from_str::<T>(body)?;
|
||||
return Ok(body);
|
||||
}
|
||||
return Err(BodyParseError::Io(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"Failed to read body",
|
||||
)));
|
||||
}
|
||||
Err(BodyParseError::Io(std::io::Error::new(
|
||||
std::io::ErrorKind::InvalidData,
|
||||
"No body found",
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BodyParseError {
|
||||
Io(std::io::Error),
|
||||
Serde(serde_json::Error),
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for BodyParseError {
|
||||
fn from(err: serde_json::Error) -> BodyParseError {
|
||||
BodyParseError::Serde(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct FakeBody {
|
||||
field1: bool,
|
||||
field2: String,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_correctly_parse_the_body() {
|
||||
let mut request = Request::new(
|
||||
Uri::from_static("http://localhost:3000"),
|
||||
HeaderMap::new(),
|
||||
HashMap::new(),
|
||||
);
|
||||
|
||||
request.headers.insert(
|
||||
"body",
|
||||
r#"{"field1": true, "field2": "hello"}"#.parse().unwrap(),
|
||||
);
|
||||
|
||||
let body: FakeBody = request.body().expect("Failed to parse body");
|
||||
|
||||
assert!(body.field1);
|
||||
assert_eq!(body.field2, "hello".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_should_trigger_an_error_when_no_body_is_found() {
|
||||
let request = Request::new(
|
||||
Uri::from_static("http://localhost:3000"),
|
||||
HeaderMap::new(),
|
||||
HashMap::new(),
|
||||
);
|
||||
|
||||
let body: Result<FakeBody, BodyParseError> = request.body();
|
||||
|
||||
assert!(body.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_should_trigger_an_error_when_body_is_invalid() {
|
||||
let mut request = Request::new(
|
||||
Uri::from_static("http://localhost:3000"),
|
||||
HeaderMap::new(),
|
||||
HashMap::new(),
|
||||
);
|
||||
|
||||
request
|
||||
.headers
|
||||
.insert("body", r#"{"field1": true"#.parse().unwrap());
|
||||
|
||||
let body: Result<FakeBody, BodyParseError> = request.body();
|
||||
|
||||
assert!(body.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user