1use diesel_async::AsyncPgConnection;
4use reqwest::StatusCode;
5use uuid::Uuid;
6
7use crate::model::dto::actions::{ActionType, RestoreDrawingLayerActionPayload};
8use crate::model::dto::drawings::DrawingDto;
9use crate::model::dto::layers::UpdateLayerDto;
10use crate::model::entity::drawings::Drawing;
11use crate::model::entity::Map;
12use crate::model::r#enum::layer_type::LayerType;
13use crate::{
14 config::data::SharedPool,
15 error::ServiceError,
16 model::{
17 dto::layers::{LayerDto, LayerSearchParameters},
18 entity::layers::Layer,
19 },
20};
21
22pub async fn find(
27 search_parameters: LayerSearchParameters,
28 pool: &SharedPool,
29) -> Result<Vec<LayerDto>, ServiceError> {
30 let mut conn = pool.get().await?;
31 let result = Layer::find(search_parameters, &mut conn).await?;
32 Ok(result)
33}
34
35pub async fn find_by_id(id: Uuid, pool: &SharedPool) -> Result<LayerDto, ServiceError> {
40 let mut conn = pool.get().await?;
41 let result = Layer::find_by_id(id, &mut conn).await?;
42 Ok(result.into())
43}
44
45pub async fn create(
50 map_id: i32,
51 new_layer: LayerDto,
52 pool: &SharedPool,
53) -> Result<LayerDto, ServiceError> {
54 let mut conn = pool.get().await?;
55 _ = Map::find_by_id(map_id, &mut conn).await?;
56 let result = Layer::create(map_id, new_layer, &mut conn).await?;
57 Ok(result)
58}
59
60async fn assert_layer_on_map(
65 map_id: i32,
66 layer_id: Uuid,
67 conn: &mut AsyncPgConnection,
68) -> Result<(), ServiceError> {
69 let layer = Layer::find_by_id(layer_id, conn).await?;
70 if layer.map_id != map_id {
71 return Err(ServiceError::new(
72 StatusCode::CONFLICT,
73 "map_id of path and dto doesn't match",
74 ));
75 }
76 Ok(())
77}
78
79async fn assert_all_layers_on_map(
85 map_id: i32,
86 layer_ids: &[Uuid],
87 conn: &mut AsyncPgConnection,
88) -> Result<(), ServiceError> {
89 let layer_ids_in_map: Vec<Uuid> = Layer::find(
90 LayerSearchParameters {
91 map_id: Some(map_id),
92 type_: None,
93 is_alternative: None,
94 only_non_deleted: Some(()),
95 },
96 conn,
97 )
98 .await?
99 .into_iter()
100 .map(|layer| layer.id)
101 .collect();
102
103 for layer_id in layer_ids {
104 if !layer_ids_in_map.contains(layer_id) {
105 return Err(ServiceError::new(
106 StatusCode::CONFLICT,
107 "map_id of path and dto doesn't match",
108 ));
109 }
110 }
111 Ok(())
112}
113
114pub async fn update(
122 map_id: i32,
123 update: UpdateLayerDto,
124 pool: &SharedPool,
125) -> Result<ActionType, ServiceError> {
126 let mut conn = pool.get().await?;
127
128 let action = match update {
129 UpdateLayerDto::Rename(dto) => {
130 assert_layer_on_map(map_id, dto.id, &mut conn).await?;
131 Layer::rename(dto.clone(), &mut conn).await?;
132 ActionType::RenameLayer(dto)
133 }
134 UpdateLayerDto::Reorder(new_order) => {
135 assert_all_layers_on_map(map_id, &new_order, &mut conn).await?;
136 Layer::reorder(new_order.clone(), &mut conn).await?;
137 ActionType::ReorderLayers(new_order)
138 }
139 UpdateLayerDto::RestoreDrawingLayer(dto) => {
140 assert_layer_on_map(map_id, dto.id, &mut conn).await?;
141 let layer = Layer::find_by_id(dto.id, &mut conn).await?;
142 if layer.marked_deleted.is_none() {
143 return Err(ServiceError::new(
144 StatusCode::CONFLICT,
145 "layer is not marked deleted",
146 ));
147 }
148 Layer::restore(map_id, dto.id, &mut conn).await?;
149 let drawings = Drawing::find_in_layer(dto.id, &mut conn).await?;
150 let drawing_dtos = drawings
151 .into_iter()
152 .map(DrawingDto::try_from)
153 .collect::<Result<Vec<DrawingDto>, ServiceError>>()?;
154 ActionType::RestoreDrawingLayer(RestoreDrawingLayerActionPayload::new(
155 dto.id,
156 drawing_dtos,
157 ))
158 }
159 };
160 Ok(action)
161}
162
163pub async fn delete_by_id(
168 map_id: i32,
169 layer_id: Uuid,
170 pool: &SharedPool,
171) -> Result<(), ServiceError> {
172 let mut conn = pool.get().await?;
173 let layer = Layer::find_by_id(layer_id, &mut conn).await?;
174 if layer.type_ != LayerType::Drawing {
175 return Err(ServiceError::new(
176 StatusCode::FORBIDDEN,
177 "can only delete drawing layer",
178 ));
179 }
180 Layer::delete(map_id, layer_id, &mut conn).await?;
181 Ok(())
182}