backend/model/dto/
drawing_variant_impl.rs

1use uuid::Uuid;
2
3use crate::model::{
4    dto::drawings::{
5        EllipseProperties, FreeLineProperties, ImageProperties, LabelTextProperties,
6        PolygonProperties, RectangleProperties,
7    },
8    entity::drawing_properties::{
9        BezierPolygonEntity, BezierPolygonPointEntity, EllipseEntity, FreeLineEntity,
10        FreeLinePointEntity, ImageEntity, LabelTextEntity, RectangleEntity,
11    },
12};
13pub enum DrawingVariantEntity {
14    Rectangle(RectangleEntity),
15    Ellipse(EllipseEntity),
16    FreeLine(Freeline),
17    BezierPolygon(BezierPolygon),
18    LabelText(LabelTextEntity),
19    Image(ImageEntity),
20}
21
22pub struct Freeline {
23    pub freeline_props: FreeLineEntity,
24    pub freeline_points: Vec<FreeLinePointEntity>,
25}
26
27pub struct BezierPolygon {
28    pub bezier_props: BezierPolygonEntity,
29    pub bezier_points: Vec<BezierPolygonPointEntity>,
30}
31
32#[derive(Debug)]
33pub enum ConversionError {
34    InvalidPoint,
35    IndexOutOfRange,
36}
37
38impl From<(Uuid, RectangleProperties)> for RectangleEntity {
39    fn from((drawings_id, dto): (Uuid, RectangleProperties)) -> Self {
40        Self {
41            drawings_id,
42            width: dto.width,
43            height: dto.height,
44            color: dto.color,
45            fill_pattern: dto.fill_pattern,
46            stroke_width: dto.stroke_width,
47        }
48    }
49}
50
51impl From<(Uuid, EllipseProperties)> for EllipseEntity {
52    fn from((drawings_id, dto): (Uuid, EllipseProperties)) -> Self {
53        Self {
54            drawings_id,
55            axis_x: dto.radius_x,
56            axis_y: dto.radius_y,
57            color: dto.color,
58            fill_pattern: dto.fill_pattern,
59            stroke_width: dto.stroke_width,
60        }
61    }
62}
63
64impl TryFrom<(Uuid, FreeLineProperties)> for Freeline {
65    type Error = ConversionError;
66
67    fn try_from((drawings_id, dto): (Uuid, FreeLineProperties)) -> Result<Self, Self::Error> {
68        let freeline_props = FreeLineEntity {
69            drawings_id,
70            color: dto.color,
71            fill_pattern: dto.fill_pattern,
72            stroke_width: dto.stroke_width,
73        };
74
75        let freeline_points = dto
76            .points
77            .into_iter()
78            .enumerate()
79            .map(|(idx, p)| {
80                let idx = i32::try_from(idx).map_err(|_| ConversionError::IndexOutOfRange)?;
81                match p.as_slice() {
82                    [x, y] => Ok(FreeLinePointEntity {
83                        id: drawings_id,
84                        idx,
85                        x: *x,
86                        y: *y,
87                    }),
88                    _ => Err(ConversionError::InvalidPoint),
89                }
90            })
91            .collect::<Result<Vec<_>, _>>()?;
92        Ok(Self {
93            freeline_props,
94            freeline_points,
95        })
96    }
97}
98
99impl TryFrom<(Uuid, PolygonProperties)> for BezierPolygon {
100    type Error = ConversionError;
101
102    fn try_from((drawings_id, dto): (Uuid, PolygonProperties)) -> Result<Self, Self::Error> {
103        let bezier_props = BezierPolygonEntity {
104            drawings_id,
105            color: dto.color,
106            fill_pattern: dto.fill_pattern,
107            stroke_width: dto.stroke_width,
108        };
109
110        let bezier_points = dto
111            .points
112            .into_iter()
113            .enumerate()
114            .map(|(idx, p)| {
115                let idx = i32::try_from(idx).map_err(|_| ConversionError::IndexOutOfRange)?;
116                match p.as_slice() {
117                    [x, y] => Ok(BezierPolygonPointEntity {
118                        id: drawings_id,
119                        idx,
120                        x: *x,
121                        y: *y,
122                    }),
123
124                    _ => Err(ConversionError::InvalidPoint),
125                }
126            })
127            .collect::<Result<Vec<_>, _>>()?;
128
129        Ok(Self {
130            bezier_props,
131            bezier_points,
132        })
133    }
134}
135
136impl From<(Uuid, LabelTextProperties)> for LabelTextEntity {
137    fn from((drawings_id, dto): (Uuid, LabelTextProperties)) -> Self {
138        Self {
139            drawings_id,
140            label_text: dto.text,
141            width: dto.width,
142            height: dto.height,
143            color: dto.color,
144        }
145    }
146}
147
148impl From<(Uuid, ImageProperties)> for ImageEntity {
149    fn from((drawings_id, dto): (Uuid, ImageProperties)) -> Self {
150        Self {
151            drawings_id,
152            file_path: dto.path,
153        }
154    }
155}
156
157impl From<RectangleEntity> for RectangleProperties {
158    fn from(p: RectangleEntity) -> Self {
159        Self {
160            width: p.width,
161            height: p.height,
162            color: p.color,
163            fill_pattern: p.fill_pattern,
164            stroke_width: p.stroke_width,
165        }
166    }
167}
168
169impl From<EllipseEntity> for EllipseProperties {
170    fn from(p: EllipseEntity) -> Self {
171        Self {
172            radius_x: p.axis_x,
173            radius_y: p.axis_y,
174            color: p.color,
175            fill_pattern: p.fill_pattern,
176            stroke_width: p.stroke_width,
177        }
178    }
179}
180
181impl From<LabelTextEntity> for LabelTextProperties {
182    fn from(p: LabelTextEntity) -> Self {
183        Self {
184            text: p.label_text,
185            width: p.width,
186            height: p.height,
187            color: p.color,
188        }
189    }
190}
191
192impl From<ImageEntity> for ImageProperties {
193    fn from(p: ImageEntity) -> Self {
194        Self { path: p.file_path }
195    }
196}
197
198impl From<Freeline> for FreeLineProperties {
199    fn from(f: Freeline) -> Self {
200        let Freeline {
201            freeline_props,
202            mut freeline_points,
203        } = f;
204
205        freeline_points.sort_by_key(|pt| pt.idx);
206
207        let points: Vec<Vec<i32>> = freeline_points
208            .into_iter()
209            .map(|pt| vec![pt.x, pt.y])
210            .collect();
211
212        Self {
213            points,
214            color: freeline_props.color,
215            fill_pattern: freeline_props.fill_pattern,
216            stroke_width: freeline_props.stroke_width,
217        }
218    }
219}
220
221impl From<BezierPolygon> for PolygonProperties {
222    fn from(b: BezierPolygon) -> Self {
223        let BezierPolygon {
224            bezier_props,
225            mut bezier_points,
226        } = b;
227
228        bezier_points.sort_by_key(|pt| pt.idx);
229
230        let points: Vec<Vec<i32>> = bezier_points
231            .into_iter()
232            .map(|pt| vec![pt.x, pt.y])
233            .collect();
234
235        Self {
236            points,
237            color: bezier_props.color,
238            fill_pattern: bezier_props.fill_pattern,
239            stroke_width: bezier_props.stroke_width,
240        }
241    }
242}