use bytes::Bytes;
use std::{
ops::{Deref, DerefMut},
path::Path,
};
use tokio::io::{AsyncWriteExt, BufWriter};
use super::error::MultipartError;
use crate::error::Error;
#[derive(Debug)]
pub struct Field(pub(super) multer::Field<'static>);
impl Field {
#[inline]
pub fn try_get_file_name(&self) -> Result<&str, Error> {
self.0
.file_name()
.or(self.name())
.ok_or(MultipartError::missing_file_name())
}
#[inline]
pub async fn text(self) -> Result<String, Error> {
self.0.text().await.map_err(MultipartError::read_error)
}
#[inline]
pub async fn chunk(&mut self) -> Result<Option<Bytes>, Error> {
self.0.chunk().await.map_err(MultipartError::read_error)
}
#[inline]
pub async fn save(self, path: impl AsRef<Path>) -> Result<(), std::io::Error> {
let file_name = self.try_get_file_name()?;
let file_path = path.as_ref().join(file_name);
self.save_as(file_path).await
}
#[inline]
pub async fn save_as(mut self, path: impl AsRef<Path>) -> Result<(), std::io::Error> {
let file = tokio::fs::File::create(path).await?;
let mut writer = BufWriter::new(file);
while let Some(ref chunk) = self.chunk().await? {
writer.write_all(chunk).await?
}
writer.flush().await
}
}
impl Deref for Field {
type Target = multer::Field<'static>;
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Field {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}