use reqwest::StatusCode;
use crate::{
error::ServiceError,
model::{
dto::areas::{AreaDto, AreaKind, AreaType, AreaUpdate, NewAreaDto, UpdateAreaDto},
entity::areas::{
Hydrology, Shading, SoilTexture, UpdateHydrology, UpdateShading, UpdateSoilTexture,
},
},
};
impl From<Shading> for AreaDto {
fn from(entity: Shading) -> Self {
Self {
id: entity.id,
layer_id: entity.layer_id,
area_type: AreaType::Shade(entity.shade),
geometry: entity.geometry,
add_date: entity.add_date,
remove_date: entity.remove_date,
notes: entity.notes,
}
}
}
impl From<Hydrology> for AreaDto {
fn from(entity: Hydrology) -> Self {
Self {
id: entity.id,
layer_id: entity.layer_id,
area_type: AreaType::Hydrology(entity.water_requirement),
geometry: entity.geometry,
add_date: entity.add_date,
remove_date: entity.remove_date,
notes: entity.notes,
}
}
}
impl From<SoilTexture> for AreaDto {
fn from(entity: SoilTexture) -> Self {
Self {
id: entity.id,
layer_id: entity.layer_id,
area_type: AreaType::SoilTexture(entity.soil_texture),
geometry: entity.geometry,
add_date: entity.add_date,
remove_date: entity.remove_date,
notes: entity.notes,
}
}
}
const INVALID_AREA_TYPE: &str = "invalid area type";
pub fn from_new_area_dto_to_shading(dtos: Vec<NewAreaDto>) -> Result<Vec<Shading>, ServiceError> {
dtos.into_iter()
.map(|dto| match dto.area_type {
AreaType::Shade(shade) => Ok(Shading {
id: dto.id,
layer_id: dto.layer_id,
shade,
geometry: dto.geometry,
add_date: dto.add_date,
remove_date: None,
notes: String::new(),
}),
_ => Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
)),
})
.collect()
}
pub fn from_new_area_dto_to_hydrology(
dtos: Vec<NewAreaDto>,
) -> Result<Vec<Hydrology>, ServiceError> {
dtos.into_iter()
.map(|dto| match dto.area_type {
AreaType::Hydrology(water_requirement) => Ok(Hydrology {
id: dto.id,
layer_id: dto.layer_id,
water_requirement,
geometry: dto.geometry,
add_date: dto.add_date,
remove_date: None,
notes: String::new(),
}),
_ => Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
)),
})
.collect()
}
pub fn from_new_area_dto_to_soil_texture(
dtos: Vec<NewAreaDto>,
) -> Result<Vec<SoilTexture>, ServiceError> {
dtos.into_iter()
.map(|dto| match dto.area_type {
AreaType::SoilTexture(soil_texture) => Ok(SoilTexture {
id: dto.id,
layer_id: dto.layer_id,
soil_texture,
geometry: dto.geometry,
add_date: dto.add_date,
remove_date: None,
notes: String::new(),
}),
_ => Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
)),
})
.collect()
}
pub fn from_update_area_dto_to_update_shading(
dto: UpdateAreaDto,
) -> Result<Vec<UpdateShading>, ServiceError> {
if dto.area_kind == AreaKind::Shade {
match dto.update {
AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
.into_iter()
.map(|v| UpdateShading {
id: v.id,
shade: match v.area_type {
AreaType::Shade(shade) => Some(shade),
_ => None,
},
..Default::default()
})
.collect()),
AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
.into_iter()
.map(|v| UpdateShading {
id: v.id,
add_date: Some(v.add_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
.into_iter()
.map(|v| UpdateShading {
id: v.id,
remove_date: Some(v.remove_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
.into_iter()
.map(|v| UpdateShading {
id: v.id,
notes: Some(v.notes),
..Default::default()
})
.collect()),
}
} else {
Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
))
}
}
pub fn from_update_area_dto_to_update_hydrology(
dto: UpdateAreaDto,
) -> Result<Vec<UpdateHydrology>, ServiceError> {
if dto.area_kind == AreaKind::Hydrology {
match dto.update {
AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
.into_iter()
.map(|v| UpdateHydrology {
id: v.id,
water_requirement: match v.area_type {
AreaType::Hydrology(water_requirement) => Some(water_requirement),
_ => None,
},
..Default::default()
})
.collect()),
AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
.into_iter()
.map(|v| UpdateHydrology {
id: v.id,
add_date: Some(v.add_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
.into_iter()
.map(|v| UpdateHydrology {
id: v.id,
remove_date: Some(v.remove_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
.into_iter()
.map(|v| UpdateHydrology {
id: v.id,
notes: Some(v.notes),
..Default::default()
})
.collect()),
}
} else {
Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
))
}
}
pub fn from_update_area_dto_to_update_soil_texture(
dto: UpdateAreaDto,
) -> Result<Vec<UpdateSoilTexture>, ServiceError> {
if dto.area_kind == AreaKind::SoilTexture {
match dto.update {
AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
.into_iter()
.map(|v| UpdateSoilTexture {
id: v.id,
soil_texture: match v.area_type {
AreaType::SoilTexture(soil_texture) => Some(soil_texture),
_ => None,
},
..Default::default()
})
.collect()),
AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
.into_iter()
.map(|v| UpdateSoilTexture {
id: v.id,
add_date: Some(v.add_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
.into_iter()
.map(|v| UpdateSoilTexture {
id: v.id,
remove_date: Some(v.remove_date),
..Default::default()
})
.collect()),
AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
.into_iter()
.map(|v| UpdateSoilTexture {
id: v.id,
notes: Some(v.notes),
..Default::default()
})
.collect()),
}
} else {
Err(ServiceError::new(
StatusCode::BAD_REQUEST,
INVALID_AREA_TYPE,
))
}
}