dogy_backend_api/service/pets/
models.rs

1use chrono::NaiveDateTime;
2use serde::{Deserialize, Serialize};
3use sqlx::{prelude::FromRow, Type};
4use uuid::Uuid;
5
6#[derive(Serialize, Type, Deserialize)]
7#[serde(rename_all = "lowercase")]
8#[sqlx(type_name = "pet_gender", rename_all = "lowercase")]
9pub enum Gender {
10    Male,
11    Female,
12}
13
14#[derive(Serialize, Type, Deserialize)]
15#[serde(rename_all = "lowercase")]
16#[sqlx(type_name = "pet_size", rename_all = "lowercase")]
17pub enum PetSize {
18    Small,
19    Medium,
20    Large,
21}
22
23#[derive(Serialize, Type, Deserialize)]
24#[serde(rename_all = "lowercase")]
25#[sqlx(type_name = "weight_unit", rename_all = "lowercase")]
26pub enum WeightUnit {
27    Kg,
28    Lbs,
29}
30
31#[derive(Serialize, Type, Deserialize)]
32#[serde(rename_all = "lowercase")]
33#[sqlx(type_name = "pet_aggression_level")]
34pub enum PetAggressionLevel {
35    #[serde(rename = "Non-aggressive")]
36    #[sqlx(rename = "Non-aggressive")]
37    NonAggressive,
38
39    #[serde(rename = "Guarding behavior")]
40    #[sqlx(rename = "Guarding behavior")]
41    GuardingBehavior,
42
43    #[serde(rename = "Mild aggression under specific circumstances")]
44    #[sqlx(rename = "Mild aggression under specific circumstances")]
45    MildAggression,
46
47    #[serde(rename = "Known history of aggression")]
48    #[sqlx(rename = "Known history of aggression")]
49    KnownHistoryAggression,
50}
51
52#[derive(Serialize, Type, Deserialize)]
53#[sqlx(type_name = "pet_allergy")]
54pub enum PetAllergy {
55    None,
56    Beef,
57    Chicken,
58    Lamb,
59    Pork,
60    Fish,
61    Eggs,
62    Milk,
63    Cheese,
64    Barley,
65    Wheat,
66    Corn,
67    Soy,
68    Peanuts,
69    Sesame,
70    Millet,
71    Rice,
72    Oats,
73    #[serde(rename = "Tree Nuts")]
74    #[sqlx(rename = "Tree Nuts")]
75    TreeNuts,
76    Yeast,
77    Fruits,
78}
79
80#[derive(Serialize, Type, Deserialize)]
81#[sqlx(type_name = "pet_behavior")]
82pub enum PetBehavior {
83    Obedient,
84    Stubborn,
85    Curious,
86    Alert,
87    Relaxed,
88    Anxious,
89    Fearful,
90    Confident,
91    Aggressive,
92    Timid,
93    Dominant,
94    Submissive,
95}
96
97#[derive(Serialize, Type, Deserialize)]
98#[sqlx(type_name = "pet_interaction")]
99pub enum PetInteraction {
100    #[serde(rename = "Loves other dogs")]
101    #[sqlx(rename = "Loves other dogs")]
102    LovesOtherDogs,
103
104    #[serde(rename = "Prefers human company")]
105    #[sqlx(rename = "Prefers human company")]
106    PrefersHumanCompany,
107
108    #[serde(rename = "Good with children")]
109    #[sqlx(rename = "Good with children")]
110    GoodWithChildren,
111
112    #[serde(rename = "Good with cats/other pets")]
113    #[sqlx(rename = "Good with cats/other pets")]
114    GoodWithCats,
115
116    #[serde(rename = "Enjoys large groups")]
117    #[sqlx(rename = "Enjoys large groups")]
118    EnjoysLargeGroups,
119
120    #[serde(rename = "Prefers one-on-one interactions")]
121    #[sqlx(rename = "Prefers one-on-one interactions")]
122    PrefersOneToOne,
123}
124
125#[derive(Serialize, Type, Deserialize)]
126#[sqlx(type_name = "pet_personality")]
127pub enum PetPersonality {
128    Playful,
129    Energetic,
130    Shy,
131    Outgoing,
132    Calm,
133    Reserved,
134    Affectionate,
135    Independent,
136}
137
138#[derive(Serialize, Type, Deserialize)]
139#[sqlx(type_name = "pet_reactivity")]
140pub enum PetReactivity {
141    #[serde(rename = "Non-reactive")]
142    #[sqlx(rename = "Non-reactive")]
143    NonReactive,
144
145    #[serde(rename = "Reactive to strangers")]
146    #[sqlx(rename = "Reactive to strangers")]
147    Strangers,
148
149    #[serde(rename = "Reactive to noises")]
150    #[sqlx(rename = "Reactive to noises")]
151    Noises,
152
153    #[serde(rename = "Reactive to moving objects")]
154    #[sqlx(rename = "Reactive to moving objects")]
155    MovingObjects,
156
157    #[serde(rename = "Reactive to specific situations")]
158    #[sqlx(rename = "Reactive to specific situations")]
159    SpecificSituations,
160
161    #[serde(rename = "Reactive to same gender dogs")]
162    #[sqlx(rename = "Reactive to same gender dogs")]
163    SameGenderDogs,
164}
165
166#[derive(Serialize, Deserialize, Type)]
167#[serde(rename_all = "camelCase")]
168pub struct PetBase {
169    #[serde(rename = "petID", skip_deserializing)]
170    pub pet_id: Uuid,
171    pub name: String,
172    pub age: i16,
173    pub gender: Gender,
174    pub size: PetSize,
175    pub photo_url: String,
176    pub weight: f32,
177    pub weight_unit: WeightUnit,
178}
179
180#[derive(Serialize, Deserialize, Type)]
181#[serde(rename_all = "camelCase")]
182pub struct UpdatePetBase {
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub name: Option<String>,
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub age: Option<i16>,
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub gender: Option<Gender>,
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub size: Option<PetSize>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub photo_url: Option<String>,
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub weight: Option<f32>,
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub weight_unit: Option<WeightUnit>,
197}
198
199#[derive(Serialize, Deserialize, Type)]
200#[serde(rename_all = "camelCase")]
201pub struct PetAttributes {
202    pub aggression_levels: Vec<PetAggressionLevel>,
203    pub allergies: Vec<PetAllergy>,
204    pub breeds: Vec<String>,
205    pub behaviors: Vec<PetBehavior>,
206    pub interactions: Vec<PetInteraction>,
207    pub personalities: Vec<PetPersonality>,
208    pub reactivities: Vec<PetReactivity>,
209    pub sterilized: bool,
210}
211
212#[derive(Serialize, Deserialize, Type)]
213#[serde(rename_all = "camelCase")]
214pub struct UpdatePetAttributes {
215    #[serde(skip_serializing_if = "Option::is_none")]
216    pub aggression_levels: Option<Vec<PetAggressionLevel>>,
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub allergies: Option<Vec<PetAllergy>>,
219    #[serde(skip_serializing_if = "Option::is_none")]
220    pub breeds: Option<Vec<String>>,
221    #[serde(skip_serializing_if = "Option::is_none")]
222    pub behaviors: Option<Vec<PetBehavior>>,
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub interactions: Option<Vec<PetInteraction>>,
225    #[serde(skip_serializing_if = "Option::is_none")]
226    pub personalities: Option<Vec<PetPersonality>>,
227    #[serde(skip_serializing_if = "Option::is_none")]
228    pub reactivities: Option<Vec<PetReactivity>>,
229    #[serde(skip_serializing_if = "Option::is_none")]
230    pub sterilized: Option<bool>,
231}
232
233#[derive(Serialize, Deserialize)]
234pub struct FullPet {
235    #[serde(flatten)]
236    pub base: PetBase,
237    pub attributes: PetAttributes,
238}
239
240// This struct should only be used for querying in db and not for JSON response.
241#[derive(Type, FromRow)]
242pub struct JoinedFullPet {
243    pub id: Uuid,
244    pub created_at: NaiveDateTime,
245    pub updated_at: NaiveDateTime,
246    pub name: String,
247    pub age: i16,
248    pub photo_url: String,
249    pub gender: Gender,
250    pub size: PetSize,
251    pub weight: f32,
252    pub weight_unit: WeightUnit,
253    pub is_sterilized: bool,
254    pub aggression_levels: Vec<PetAggressionLevel>,
255    pub allergies: Vec<PetAllergy>,
256    pub behaviors: Vec<PetBehavior>,
257    pub breeds: Vec<String>,
258    pub interactions: Vec<PetInteraction>,
259    pub personalities: Vec<PetPersonality>,
260    pub reactivities: Vec<PetReactivity>,
261}
262
263#[derive(Serialize)]
264pub struct AllFullPet {
265    pub pets: Vec<FullPet>,
266}