75 lines
2.6 KiB
Rust
75 lines
2.6 KiB
Rust
use axum::extract::Multipart;
|
|
use bytes::Bytes;
|
|
use domain::errors::DomainError;
|
|
use domain::value_objects::SystemId;
|
|
|
|
use crate::constants::DEFAULT_DEVICE_ID;
|
|
use crate::errors::AppError;
|
|
|
|
pub struct UploadedAsset {
|
|
pub filename: String,
|
|
pub data: Bytes,
|
|
pub target_path_id: SystemId,
|
|
pub client_device_id: String,
|
|
}
|
|
|
|
impl UploadedAsset {
|
|
pub async fn from_multipart(mut multipart: Multipart) -> Result<Self, AppError> {
|
|
let mut file_data: Option<Bytes> = None;
|
|
let mut filename: Option<String> = None;
|
|
let mut target_path_id: Option<uuid::Uuid> = None;
|
|
let mut client_device_id = DEFAULT_DEVICE_ID.to_string();
|
|
|
|
while let Some(field) = multipart
|
|
.next_field()
|
|
.await
|
|
.map_err(|e| AppError::from(DomainError::Validation(e.to_string())))?
|
|
{
|
|
let name = field.name().unwrap_or("").to_string();
|
|
match name.as_str() {
|
|
"file" => {
|
|
filename = field.file_name().map(|s| s.to_string());
|
|
file_data = Some(
|
|
field
|
|
.bytes()
|
|
.await
|
|
.map_err(|e| AppError::from(DomainError::Internal(e.to_string())))?,
|
|
);
|
|
}
|
|
"target_path_id" => {
|
|
let text = field
|
|
.text()
|
|
.await
|
|
.map_err(|e| AppError::from(DomainError::Validation(e.to_string())))?;
|
|
target_path_id = Some(
|
|
text.parse::<uuid::Uuid>()
|
|
.map_err(|e| AppError::from(DomainError::Validation(e.to_string())))?,
|
|
);
|
|
}
|
|
"client_device_id" => {
|
|
client_device_id = field
|
|
.text()
|
|
.await
|
|
.map_err(|e| AppError::from(DomainError::Validation(e.to_string())))?;
|
|
}
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
let data = file_data
|
|
.ok_or_else(|| AppError::from(DomainError::Validation("Missing file field".into())))?;
|
|
let fname = filename
|
|
.ok_or_else(|| AppError::from(DomainError::Validation("Missing filename".into())))?;
|
|
let path_id = target_path_id.ok_or_else(|| {
|
|
AppError::from(DomainError::Validation("Missing target_path_id".into()))
|
|
})?;
|
|
|
|
Ok(Self {
|
|
filename: fname,
|
|
data,
|
|
target_path_id: SystemId::from_uuid(path_id),
|
|
client_device_id,
|
|
})
|
|
}
|
|
}
|