backend/model/dto/
drawings_impl.rs

1use reqwest::StatusCode;
2
3use super::drawings::{
4    DrawingDto, DrawingVariant, UpdateAddDateDrawingDto, UpdateDrawingsDto, UpdateNotesDrawingDto,
5    UpdateRemoveDateDrawingDto,
6};
7use crate::{
8    error::ServiceError,
9    model::{
10        entity::drawings::{Drawing, UpdateDrawing},
11        r#enum::drawing_shape_type::DrawingShapeType,
12    },
13};
14
15/// In case of a logic bug: If the JSON in the db
16/// doesn't match `DrawingVariant`, we return 500.
17fn _internal_server_error_mismatch_json(_: serde_json::Error) -> ServiceError {
18    ServiceError::new(
19        StatusCode::INTERNAL_SERVER_ERROR,
20        "mismatch between database json and drawings properties",
21    )
22}
23
24impl TryFrom<(DrawingShapeType, serde_json::Value)> for DrawingVariant {
25    type Error = serde_json::Error;
26
27    fn try_from(value: (DrawingShapeType, serde_json::Value)) -> Result<Self, Self::Error> {
28        let (shape_type, val) = value;
29        match shape_type {
30            DrawingShapeType::Rectangle => serde_json::from_value(val).map(Self::Rectangle),
31            DrawingShapeType::Ellipse => serde_json::from_value(val).map(Self::Ellipse),
32            DrawingShapeType::FreeLine => serde_json::from_value(val).map(Self::FreeLine),
33            DrawingShapeType::BezierPolygon => serde_json::from_value(val).map(Self::BezierPolygon),
34            DrawingShapeType::LabelText => serde_json::from_value(val).map(Self::LabelText),
35            DrawingShapeType::Image => serde_json::from_value(val).map(Self::Image),
36        }
37    }
38}
39
40impl TryFrom<DrawingVariant> for (DrawingShapeType, serde_json::Value) {
41    type Error = serde_json::Error;
42
43    fn try_from(drawing_variant: DrawingVariant) -> Result<Self, Self::Error> {
44        Ok(match drawing_variant {
45            DrawingVariant::Rectangle(x) => (DrawingShapeType::Rectangle, serde_json::to_value(x)?),
46            DrawingVariant::Ellipse(x) => (DrawingShapeType::Ellipse, serde_json::to_value(x)?),
47            DrawingVariant::FreeLine(x) => (DrawingShapeType::FreeLine, serde_json::to_value(x)?),
48            DrawingVariant::BezierPolygon(x) => {
49                (DrawingShapeType::BezierPolygon, serde_json::to_value(x)?)
50            }
51            DrawingVariant::LabelText(x) => (DrawingShapeType::LabelText, serde_json::to_value(x)?),
52            DrawingVariant::Image(x) => (DrawingShapeType::Image, serde_json::to_value(x)?),
53        })
54    }
55}
56
57impl TryFrom<Drawing> for DrawingDto {
58    type Error = ServiceError;
59
60    fn try_from(drawing: Drawing) -> Result<Self, Self::Error> {
61        let drawing_variant = DrawingVariant::try_from((drawing.shape_type, drawing.properties))
62            .map_err(_internal_server_error_mismatch_json)?;
63        Ok(Self {
64            id: drawing.id,
65            variant: drawing_variant,
66            layer_id: drawing.layer_id,
67            add_date: drawing.add_date,
68            remove_date: drawing.remove_date,
69            rotation: drawing.rotation,
70            scale_x: drawing.scale_x,
71            scale_y: drawing.scale_y,
72            x: drawing.x,
73            y: drawing.y,
74            notes: drawing.notes,
75        })
76    }
77}
78
79impl TryFrom<DrawingDto> for Drawing {
80    type Error = ServiceError;
81
82    fn try_from(drawing_dto: DrawingDto) -> Result<Self, Self::Error> {
83        let (shape_type, properties) = drawing_dto
84            .variant
85            .try_into()
86            .map_err(_internal_server_error_mismatch_json)?;
87        Ok(Self {
88            id: drawing_dto.id,
89            shape_type,
90            layer_id: drawing_dto.layer_id,
91            add_date: drawing_dto.add_date,
92            remove_date: drawing_dto.remove_date,
93            rotation: drawing_dto.rotation,
94            scale_x: drawing_dto.scale_x,
95            scale_y: drawing_dto.scale_y,
96            x: drawing_dto.x,
97            y: drawing_dto.y,
98            properties,
99            notes: drawing_dto.notes,
100        })
101    }
102}
103
104impl TryFrom<DrawingDto> for UpdateDrawing {
105    type Error = ServiceError;
106
107    fn try_from(drawing_dto: DrawingDto) -> Result<Self, Self::Error> {
108        let (shape_type, properties) = drawing_dto
109            .variant
110            .try_into()
111            .map_err(_internal_server_error_mismatch_json)?;
112
113        Ok(Self {
114            id: drawing_dto.id,
115            shape_type: Some(shape_type),
116            layer_id: Some(drawing_dto.layer_id),
117            add_date: Some(drawing_dto.add_date),
118            remove_date: Some(drawing_dto.remove_date),
119            rotation: Some(drawing_dto.rotation),
120            scale_x: Some(drawing_dto.scale_x),
121            scale_y: Some(drawing_dto.scale_y),
122            x: Some(drawing_dto.x),
123            y: Some(drawing_dto.y),
124            properties: Some(properties),
125            notes: Some(drawing_dto.notes),
126        })
127    }
128}
129
130impl From<UpdateAddDateDrawingDto> for UpdateDrawing {
131    fn from(dto: UpdateAddDateDrawingDto) -> Self {
132        Self {
133            id: dto.id,
134            add_date: Some(dto.add_date),
135            ..Default::default()
136        }
137    }
138}
139
140impl From<UpdateRemoveDateDrawingDto> for UpdateDrawing {
141    fn from(dto: UpdateRemoveDateDrawingDto) -> Self {
142        Self {
143            id: dto.id,
144            remove_date: Some(dto.remove_date),
145            ..Default::default()
146        }
147    }
148}
149
150impl From<UpdateNotesDrawingDto> for UpdateDrawing {
151    fn from(dto: UpdateNotesDrawingDto) -> Self {
152        Self {
153            id: dto.id,
154            notes: Some(dto.notes),
155            ..Default::default()
156        }
157    }
158}
159
160impl TryFrom<UpdateDrawingsDto> for Vec<UpdateDrawing> {
161    type Error = ServiceError;
162
163    fn try_from(dto: UpdateDrawingsDto) -> Result<Self, Self::Error> {
164        match dto {
165            UpdateDrawingsDto::Update(vec) => vec.into_iter().map(DrawingDto::try_into).collect(),
166            UpdateDrawingsDto::UpdateAddDate(vec) => Ok(vec.into_iter().map(Into::into).collect()),
167            UpdateDrawingsDto::UpdateRemoveDate(vec) => {
168                Ok(vec.into_iter().map(Into::into).collect())
169            }
170            UpdateDrawingsDto::UpdateNotes(vec) => Ok(vec.into_iter().map(Into::into).collect()),
171        }
172    }
173}