avina_wire/resources/
flavor_group.rs

1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4#[cfg(feature = "sqlx")]
5use sqlx::{FromRow, Row, mysql::MySqlRow};
6#[cfg(feature = "tabled")]
7use tabled::Tabled;
8
9use crate::{resources::FlavorMinimal, user::ProjectMinimal};
10
11#[cfg_attr(feature = "tabled", derive(Tabled))]
12#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
13pub struct FlavorGroup {
14    pub id: u32,
15    pub name: String,
16    #[cfg_attr(feature = "tabled", tabled(skip))]
17    pub flavors: Vec<u32>,
18    pub project: u32,
19}
20
21#[cfg(feature = "sqlx")]
22impl<'r> FromRow<'r, MySqlRow> for FlavorGroup {
23    fn from_row(row: &'r MySqlRow) -> Result<Self, sqlx::Error> {
24        Ok(Self {
25            id: row.try_get::<i32, _>("id")?.try_into().unwrap(),
26            name: row.try_get("name")?,
27            flavors: {
28                let flavors: Option<String> = row.try_get("flavors")?;
29                // TODO: can we get rid of this unwrap here
30                match flavors {
31                    Some(flavors) => flavors
32                        .split(',')
33                        .map(|f| f.parse::<i32>().unwrap().try_into().unwrap())
34                        .collect(),
35                    None => Vec::new(),
36                }
37            },
38            project: row.try_get::<i32, _>("project")?.try_into().unwrap(),
39        })
40    }
41}
42
43impl Display for FlavorGroup {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        f.write_str(&format!("FlavorGroup(id={}, name={})", self.id, self.name))
46    }
47}
48
49#[cfg_attr(feature = "sqlx", derive(FromRow))]
50#[cfg_attr(feature = "tabled", derive(Tabled))]
51#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
52pub struct FlavorGroupMinimal {
53    pub id: u32,
54    pub name: String,
55}
56
57// TODO: maybe rethink the Display implementations
58impl Display for FlavorGroupMinimal {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        f.write_str(&format!("FlavorGroup(id={}, name={})", self.id, self.name))
61    }
62}
63
64#[cfg_attr(feature = "tabled", derive(Tabled))]
65#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
66pub struct FlavorGroupDetailed {
67    pub id: u32,
68    pub name: String,
69    #[cfg_attr(feature = "tabled", tabled(skip))]
70    pub flavors: Vec<FlavorMinimal>,
71    pub project: ProjectMinimal,
72}
73
74impl Display for FlavorGroupDetailed {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        f.write_str(&format!("FlavorGroup(id={}, name={})", self.id, self.name))
77    }
78}
79
80#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)]
81pub struct FlavorGroupListParams {
82    pub all: Option<bool>,
83}
84
85#[cfg_attr(feature = "tabled", derive(Tabled))]
86#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
87pub struct FlavorGroupCreated {
88    pub id: u32,
89    pub name: String,
90    #[cfg_attr(feature = "tabled", tabled(skip))]
91    pub flavors: Vec<FlavorMinimal>,
92    pub project: u32,
93}
94
95impl Display for FlavorGroupCreated {
96    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97        f.write_str(&format!("FlavorGroup(id={}, name={})", self.id, self.name))
98    }
99}
100
101#[cfg_attr(feature = "tabled", derive(Tabled))]
102#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
103pub struct FlavorGroupInitialize {
104    pub new_flavor_group_count: u32,
105    pub new_flavor_count: u32,
106}
107
108#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
109pub struct FlavorGroupCreateData {
110    pub name: String,
111    pub flavors: Vec<u32>,
112}
113
114impl FlavorGroupCreateData {
115    pub fn new(name: String) -> Self {
116        Self {
117            name,
118            flavors: vec![],
119        }
120    }
121}
122
123#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
124pub struct FlavorGroupModifyData {
125    pub id: u32,
126
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub name: Option<String>,
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub project: Option<u32>,
131}
132
133impl FlavorGroupModifyData {
134    pub fn new(id: u32) -> Self {
135        Self {
136            id,
137            name: None,
138            project: None,
139        }
140    }
141}
142
143#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
144pub struct FlavorGroupUsageParams {
145    #[serde(skip_serializing_if = "Option::is_none")]
146    pub user: Option<u32>,
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub project: Option<u32>,
149    #[serde(skip_serializing_if = "Option::is_none")]
150    pub all: Option<bool>,
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub aggregate: Option<bool>,
153}
154
155#[cfg_attr(feature = "tabled", derive(Tabled))]
156#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
157pub struct FlavorGroupUsageSimple {
158    pub user_id: u32,
159    pub user_name: String,
160    pub flavorgroup_id: u32,
161    pub flavorgroup_name: String,
162    pub usage: u32,
163}
164
165#[cfg_attr(feature = "tabled", derive(Tabled))]
166#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
167pub struct FlavorGroupUsageAggregate {
168    pub flavorgroup_id: u32,
169    pub flavorgroup_name: String,
170    pub usage: u32,
171}