1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
//! All DTOs associated with [`PlantingDto`].

use chrono::{NaiveDate, NaiveDateTime};
use serde::{Deserialize, Serialize};
use typeshare::typeshare;
use utoipa::{IntoParams, ToSchema};
use uuid::Uuid;

/// Represents a plant on a map.
/// E.g. a user selects a plant from the search results and plants it on the map.
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct PlantingDto {
    /// The id of the planting.
    pub id: Uuid,
    /// The plant layer the plantings is on.
    pub layer_id: Uuid,
    /// The plant that is planted.
    pub plant_id: i32,
    /// The actual time the planting was added to the database. This is read-only.
    pub created_at: Option<NaiveDateTime>,
    /// When the planting was last modified on the database. This is read-only.
    pub modified_at: Option<NaiveDateTime>,
    /// The id of the user who planted the planting. This is read-only.
    pub created_by: Option<Uuid>,
    /// The id of the last user who touched the planting. This is read-only.
    pub modified_by: Option<Uuid>,
    /// The x coordinate of the position on the map.
    pub x: i32,
    /// The y coordinate of the position on the map.
    pub y: i32,
    /// The size of the planting on the map in x direction.
    pub size_x: i32,
    /// The size of the planting on the map in y direction.
    pub size_y: i32,
    /// The height of the planting in cm (z direction).
    pub height: Option<i32>,
    /// The rotation in degrees (0-360) of the plant on the map.
    pub rotation: f32,
    /// The date the planting was added to the map.
    /// If None, the planting always existed.
    pub add_date: Option<NaiveDate>,
    /// The date the planting was removed from the map.
    /// If None, the planting is still on the map.
    pub remove_date: Option<NaiveDate>,
    /// Plantings may be linked with a seed.
    pub seed_id: Option<i32>,
    /// Equivalent to the seed name.
    /// It is used to display the full plant name on a map
    /// even if a user does not have access to the seed.
    pub additional_name: Option<String>,
    /// Is the planting an area of plantings.
    pub is_area: bool,
    /// Notes about the planting in Markdown.
    pub notes: String,
}

/// Used to differentiate between different update operations on plantings.
///
/// Ordering of enum variants is important.
/// Serde will try to deserialize starting from the top.
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(tag = "type", content = "content")]
pub enum UpdatePlantingDto {
    /// Transform a planting.
    Transform(Vec<TransformPlantingDto>),
    /// Move a planting on the map.
    Move(Vec<MovePlantingDto>),
    /// Change the `add_date` of a planting.
    UpdateAddDate(Vec<UpdateAddDatePlantingDto>),
    /// Change the `remove_date` of a planting.
    UpdateRemoveDate(Vec<UpdateRemoveDatePlantingDto>),
    /// Update Markdown notes.
    UpdateNote(Vec<UpdatePlantingNoteDto>),
}

/// Used to transform an existing planting.
#[typeshare]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct TransformPlantingDto {
    /// The id of the planting.
    pub id: Uuid,
    /// The x coordinate of the position on the map.
    pub x: i32,
    /// The y coordinate of the position on the map.
    pub y: i32,
    /// The rotation of the plant on the map.
    pub rotation: f32,
    /// The x scale of the plant on the map.
    pub size_x: i32,
    /// The y scale of the plant on the map.
    pub size_y: i32,
    /// The height of the plant.
    pub height: Option<i32>,
}

/// Used to move an existing planting.
#[typeshare]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct MovePlantingDto {
    /// The id of the planting.
    pub id: Uuid,
    /// The x coordinate of the position on the map.
    pub x: i32,
    /// The y coordinate of the position on the map.
    pub y: i32,
}

/// Used to change the `add_date` of a planting.
#[typeshare]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct UpdateAddDatePlantingDto {
    /// The id of the planting.
    pub id: Uuid,
    /// The date the planting was added to the map.
    /// If None, the planting always existed.
    pub add_date: Option<NaiveDate>,
}

/// Used to change the `remove_date` of a planting.
#[typeshare]
#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct UpdateRemoveDatePlantingDto {
    /// The id of the planting.
    pub id: Uuid,
    /// The date the planting was removed from the map.
    /// If None, the planting is still on the map.
    pub remove_date: Option<NaiveDate>,
}

/// Update Markdown planting notes.
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct UpdatePlantingNoteDto {
    /// The id of the planting.
    pub id: Uuid,
    /// Notes about the planting in Markdown.
    pub notes: String,
}

/// Used to delete a planting.
#[typeshare]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct DeletePlantingDto {
    /// Id of the planting to delete.
    pub id: Uuid,
}

/// Query parameters for searching plantings.
#[typeshare]
#[derive(Debug, Deserialize, IntoParams)]
pub struct PlantingSearchParameters {
    /// The id of the plant the planting references.
    pub plant_id: Option<i32>,
    /// The id of the plants layer the planting is placed on.
    pub layer_id: Option<Uuid>,
    /// Plantings that exist around this date are returned.
    pub relative_to_date: NaiveDate,
}