#[macro_export]
macro_rules! file {
($file_name:expr, $body:expr) => {
$crate::file!($file_name, $body; [])
};
($file_name:expr, $body:expr; [ $( $header:expr),* $(,)? ]) => {{
let mime = $crate::fs::get_mime_or_octet_stream($file_name);
$crate::response!(
$crate::http::StatusCode::OK,
$crate::HttpBody::file($body);
[
($crate::headers::CONTENT_TYPE, mime.as_ref()),
($crate::headers::CONTENT_DISPOSITION, format!("attachment; filename=\"{}\"", $file_name)),
$( $header ),*
]
)
}};
}
#[cfg(test)]
mod tests {
use crate::test::{TempFile, utils::read_file_bytes};
use tokio::fs::File;
#[tokio::test]
async fn it_creates_file_with_ok_response() {
let file = TempFile::new("Hello, this is some file content!").await;
let file_name = file.file_name().to_string();
let file = File::open(file.path).await.unwrap();
let response = file!(&file_name, file);
assert!(response.is_ok());
let mut response = response.unwrap();
let body = read_file_bytes(&mut response).await;
assert_eq!(
String::from_utf8_lossy(body.as_slice()),
"Hello, this is some file content!"
);
assert_eq!(response.status(), 200);
}
#[tokio::test]
async fn it_creates_file_with_ok_and_custom_headers_response() {
let file = TempFile::new("Hello, this is some file content!").await;
let file_name = file.file_name().to_string();
let file = File::open(file.path).await.unwrap();
let response = file!(&file_name, file; [
("x-api-key", "some api key")
]);
assert!(response.is_ok());
let mut response = response.unwrap();
let body = read_file_bytes(&mut response).await;
assert_eq!(
String::from_utf8_lossy(body.as_slice()),
"Hello, this is some file content!"
);
assert_eq!(response.headers()["x-api-key"], "some api key");
assert_eq!(response.status(), 200);
}
}