#![allow(clippy::missing_docs_in_private_items)]
#![allow(clippy::missing_const_for_fn)]
use chrono::NaiveDate;
use postgis_diesel::types::{Point, Polygon};
use serde::Serialize;
use typeshare::typeshare;
use uuid::Uuid;
use crate::model::{
dto::{
base_layer_images::BaseLayerImageDto,
drawings::DrawingDto,
layers::{LayerDto, LayerRenameDto},
plantings::{
DeletePlantingDto, MovePlantingDto, PlantingDto, TransformPlantingDto,
UpdateAddDatePlantingDto, UpdatePlantingNoteDto, UpdateRemoveDatePlantingDto,
},
shadings::{
DeleteShadingDto, ShadingDto, UpdateAddDateShadingDto, UpdateNotesShadingDto,
UpdateRemoveDateShadingDto, UpdateValuesShadingDto,
},
UpdateMapGeometryDto,
},
r#enum::shade::Shade,
};
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Action {
pub action_id: Uuid,
pub user_id: Uuid,
pub action: ActionType,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(tag = "type", content = "payload")]
pub enum ActionType {
CreateLayer(LayerDto),
DeleteLayer(Uuid),
RestoreDrawingLayer(RestoreDrawingLayerActionPayload),
RenameLayer(LayerRenameDto),
ReorderLayers(Vec<Uuid>),
CreatePlanting(Vec<PlantingDto>),
DeletePlanting(Vec<DeletePlantingActionPayload>),
MovePlanting(Vec<MovePlantingActionPayload>),
TransformPlanting(Vec<TransformPlantingActionPayload>),
UpdatePlantingAddDate(Vec<UpdateAddDateActionPayload>),
UpdatePlantingRemoveDate(Vec<UpdateRemoveDateActionPayload>),
UpdatePlantingNotes(Vec<UpdatePlantingNotesActionPayload>),
CreateShading(Vec<CreateShadingActionPayload>),
DeleteShading(Vec<DeleteShadingActionPayload>),
UpdateShading(Vec<UpdateShadingActionPayload>),
UpdateShadingAddDate(Vec<UpdateShadingAddDateActionPayload>),
UpdateShadingRemoveDate(Vec<UpdateShadingRemoveDateActionPayload>),
UpdateShadingNotes(Vec<UpdateShadingNotesActionPayload>),
CreateBaseLayerImage(CreateBaseLayerImageActionPayload),
UpdateBaseLayerImage(UpdateBaseLayerImageActionPayload),
DeleteBaseLayerImage(DeleteBaseLayerImageActionPayload),
UpdateMapGeometry(UpdateMapGeometryActionPayload),
UpdatePlantingAdditionalName(UpdatePlantingAdditionalNamePayload),
CreateDrawing(Vec<DrawingDto>),
DeleteDrawing(Vec<Uuid>),
UpdateDrawing(Vec<DrawingDto>),
UpdateDrawingAddDate(Vec<DrawingDto>),
UpdateDrawingRemoveDate(Vec<DrawingDto>),
UpdateDrawingNotes(Vec<UpdateDrawingNotesActionPayload>),
}
impl Action {
#[must_use]
pub fn new_create_planting_action(
dtos: Vec<PlantingDto>,
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::CreatePlanting(dtos),
}
}
#[must_use]
pub fn new_delete_planting_action(
dtos: &[DeletePlantingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::DeletePlanting(
dtos.iter()
.map(|dto| DeletePlantingActionPayload { id: dto.id })
.collect(),
),
}
}
#[must_use]
pub fn new_move_planting_action(
dtos: &[MovePlantingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::MovePlanting(
dtos.iter()
.map(|dto| MovePlantingActionPayload {
id: dto.id,
x: dto.x,
y: dto.y,
})
.collect(),
),
}
}
#[must_use]
pub fn new_transform_planting_action(
dtos: &[TransformPlantingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::TransformPlanting(
dtos.iter()
.map(|dto| TransformPlantingActionPayload {
id: dto.id,
x: dto.x,
y: dto.y,
rotation: dto.rotation,
size_x: dto.size_x,
size_y: dto.size_y,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_planting_add_date_action(
dtos: &[UpdateAddDatePlantingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdatePlantingAddDate(
dtos.iter()
.map(|dto| UpdateAddDateActionPayload {
id: dto.id,
add_date: dto.add_date,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_planting_remove_date_action(
dtos: &[UpdateRemoveDatePlantingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdatePlantingRemoveDate(
dtos.iter()
.map(|dto| UpdateRemoveDateActionPayload {
id: dto.id,
remove_date: dto.remove_date,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_planting_note_action(
dtos: &[UpdatePlantingNoteDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdatePlantingNotes(
dtos.iter()
.map(|dto| UpdatePlantingNotesActionPayload {
id: dto.id,
notes: dto.notes.clone(),
})
.collect(),
),
}
}
#[must_use]
pub fn new_create_shading_action(dtos: &[ShadingDto], user_id: Uuid, action_id: Uuid) -> Self {
Self {
action_id,
user_id,
action: ActionType::CreateShading(
dtos.iter()
.map(|dto| CreateShadingActionPayload {
id: dto.id,
layer_id: dto.layer_id,
shade: dto.shade,
add_date: dto.add_date,
remove_date: dto.remove_date,
geometry: dto.geometry.clone(),
notes: dto.notes.clone(),
})
.collect(),
),
}
}
#[must_use]
pub fn new_delete_shading_action(
dtos: &[DeleteShadingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::DeleteShading(
dtos.iter()
.map(|dto| DeleteShadingActionPayload { id: dto.id })
.collect(),
),
}
}
#[must_use]
pub fn new_update_shading_action(
dtos: &[UpdateValuesShadingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdateShading(
dtos.iter()
.map(|dto| UpdateShadingActionPayload {
id: dto.id,
shade: dto.shade,
geometry: dto.clone().geometry,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_shading_remove_date_action(
dtos: &[UpdateRemoveDateShadingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdateShadingRemoveDate(
dtos.iter()
.map(|dto| UpdateShadingRemoveDateActionPayload {
id: dto.id,
remove_date: dto.remove_date,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_shading_add_date_action(
dtos: &[UpdateAddDateShadingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdateShadingAddDate(
dtos.iter()
.map(|dto| UpdateShadingAddDateActionPayload {
id: dto.id,
add_date: dto.add_date,
})
.collect(),
),
}
}
#[must_use]
pub fn new_update_shading_add_notes(
dtos: &[UpdateNotesShadingDto],
user_id: Uuid,
action_id: Uuid,
) -> Self {
Self {
action_id,
user_id,
action: ActionType::UpdateShadingNotes(
dtos.iter()
.map(|dto| UpdateShadingNotesActionPayload {
id: dto.id,
notes: dto.notes.clone(),
})
.collect(),
),
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct RestoreDrawingLayerActionPayload {
id: Uuid,
drawings: Vec<DrawingDto>,
}
impl RestoreDrawingLayerActionPayload {
#[must_use]
pub fn new(id: Uuid, drawings: Vec<DrawingDto>) -> Self {
Self { id, drawings }
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CreatePlantActionPayload {
id: Uuid,
layer_id: Uuid,
plant_id: i32,
x: i32,
y: i32,
rotation: f32,
size_x: i32,
size_y: i32,
add_date: Option<NaiveDate>,
remove_date: Option<NaiveDate>,
seed_id: Option<i32>,
additional_name: Option<String>,
is_area: bool,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DeletePlantingActionPayload {
id: Uuid,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct MovePlantingActionPayload {
id: Uuid,
x: i32,
y: i32,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct TransformPlantingActionPayload {
id: Uuid,
x: i32,
y: i32,
rotation: f32,
size_x: i32,
size_y: i32,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CreateShadingActionPayload {
id: Uuid,
layer_id: Uuid,
shade: Shade,
geometry: Polygon<Point>,
add_date: Option<NaiveDate>,
remove_date: Option<NaiveDate>,
notes: String,
}
impl CreateShadingActionPayload {
#[must_use]
pub fn new(payload: ShadingDto) -> Self {
Self {
id: payload.id,
layer_id: payload.layer_id,
shade: payload.shade,
geometry: payload.geometry,
add_date: payload.add_date,
remove_date: payload.remove_date,
notes: payload.notes,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateShadingActionPayload {
id: Uuid,
shade: Option<Shade>,
geometry: Option<Polygon<Point>>,
}
impl UpdateShadingActionPayload {
#[must_use]
pub fn new(payload: ShadingDto) -> Self {
Self {
id: payload.id,
shade: Some(payload.shade),
geometry: Some(payload.geometry),
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DeleteShadingActionPayload {
id: Uuid,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateShadingAddDateActionPayload {
id: Uuid,
add_date: Option<NaiveDate>,
}
impl UpdateShadingAddDateActionPayload {
#[must_use]
pub fn new(payload: &ShadingDto) -> Self {
Self {
id: payload.id,
add_date: payload.add_date,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateShadingRemoveDateActionPayload {
id: Uuid,
remove_date: Option<NaiveDate>,
}
impl UpdateShadingRemoveDateActionPayload {
#[must_use]
pub fn new(payload: &ShadingDto) -> Self {
Self {
id: payload.id,
remove_date: payload.remove_date,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
pub struct UpdateShadingNotesActionPayload {
id: Uuid,
notes: String,
}
impl UpdateShadingNotesActionPayload {
#[must_use]
pub fn new(payload: &ShadingDto) -> Self {
Self {
id: payload.id,
notes: payload.notes.clone(),
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePlantingNotesActionPayload {
id: Uuid,
notes: String,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CreateBaseLayerImageActionPayload {
id: Uuid,
layer_id: Uuid,
rotation: f32,
scale: f32,
path: String,
}
impl CreateBaseLayerImageActionPayload {
#[must_use]
pub fn new(payload: BaseLayerImageDto) -> Self {
Self {
id: payload.id,
layer_id: payload.layer_id,
rotation: payload.rotation,
scale: payload.scale,
path: payload.path,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct DeleteBaseLayerImageActionPayload {
id: Uuid,
}
impl DeleteBaseLayerImageActionPayload {
#[must_use]
pub fn new(id: Uuid) -> Self {
Self { id }
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateBaseLayerImageActionPayload {
id: Uuid,
layer_id: Uuid,
rotation: f32,
scale: f32,
path: String,
x: i32,
y: i32,
}
impl UpdateBaseLayerImageActionPayload {
#[must_use]
pub fn new(payload: BaseLayerImageDto) -> Self {
Self {
id: payload.id,
layer_id: payload.layer_id,
rotation: payload.rotation,
scale: payload.scale,
path: payload.path,
x: payload.x,
y: payload.y,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateAddDateActionPayload {
id: Uuid,
add_date: Option<NaiveDate>,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateRemoveDateActionPayload {
id: Uuid,
remove_date: Option<NaiveDate>,
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateMapGeometryActionPayload {
map_id: i32,
#[typeshare(serialized_as = "object")]
geometry: Polygon<Point>,
}
impl UpdateMapGeometryActionPayload {
#[must_use]
pub fn new(payload: UpdateMapGeometryDto, map_id: i32) -> Self {
Self {
map_id,
geometry: payload.geometry,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePlantingAdditionalNamePayload {
id: Uuid,
additional_name: Option<String>,
}
impl UpdatePlantingAdditionalNamePayload {
#[must_use]
pub fn new(payload: &PlantingDto, new_additional_name: Option<String>) -> Self {
Self {
id: payload.id,
additional_name: new_additional_name,
}
}
}
#[typeshare]
#[derive(Debug, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct UpdateDrawingNotesActionPayload {
id: Uuid,
notes: String,
}
impl UpdateDrawingNotesActionPayload {
#[must_use]
pub fn new(drawing: DrawingDto) -> Self {
Self {
id: drawing.id,
notes: drawing.notes,
}
}
}