avina_wire/user/
user.rs

1use std::{cmp::PartialEq, fmt::Display};
2
3use serde::{Deserialize, Serialize};
4#[cfg(feature = "sqlx")]
5use sqlx::FromRow;
6#[cfg(feature = "tabled")]
7use tabled::Tabled;
8
9use crate::user::ProjectMinimal;
10
11#[cfg_attr(feature = "sqlx", derive(FromRow))]
12#[cfg_attr(feature = "tabled", derive(Tabled))]
13#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
14pub struct User {
15    #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
16    pub id: u32,
17    pub name: String,
18    pub openstack_id: String, // UUIDv4 without dashes
19    #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
20    pub project: u32,
21    pub project_name: String,
22    pub role: u32,
23    pub is_staff: bool,
24    pub is_active: bool,
25}
26
27impl Display for User {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        f.write_str(&format!("User(id={}, name={}", self.id, self.name))
30    }
31}
32
33impl PartialEq<UserMinimal> for User {
34    fn eq(&self, other: &UserMinimal) -> bool {
35        self.id == other.id && self.name == other.name
36    }
37}
38
39impl PartialEq<UserDetailed> for User {
40    fn eq(&self, other: &UserDetailed) -> bool {
41        self.id == other.id
42            && self.name == other.name
43            && self.openstack_id == other.openstack_id
44            && self.project == other.project.id
45            && self.project_name == other.project_name
46            && self.project_name == other.project.name
47            && self.is_staff == other.is_staff
48            && self.is_active == other.is_active
49            && self.role == other.role
50    }
51}
52
53impl From<UserDetailed> for User {
54    fn from(value: UserDetailed) -> Self {
55        Self {
56            id: value.id,
57            name: value.name,
58            openstack_id: value.openstack_id,
59            project: value.project.id,
60            project_name: value.project_name,
61            role: value.role,
62            is_staff: value.is_staff,
63            is_active: value.is_active,
64        }
65    }
66}
67
68#[cfg_attr(feature = "sqlx", derive(FromRow))]
69#[cfg_attr(feature = "tabled", derive(Tabled))]
70#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
71pub struct UserMinimal {
72    #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
73    pub id: u32,
74    pub name: String,
75}
76
77impl PartialEq<User> for UserMinimal {
78    fn eq(&self, other: &User) -> bool {
79        self.id == other.id && self.name == other.name
80    }
81}
82
83impl PartialEq<UserDetailed> for UserMinimal {
84    fn eq(&self, other: &UserDetailed) -> bool {
85        self.id == other.id && self.name == other.name
86    }
87}
88
89impl Display for UserMinimal {
90    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91        f.write_str(&format!("User(id={}, name={}", self.id, self.name))
92    }
93}
94
95#[cfg_attr(feature = "sqlx", derive(FromRow))]
96#[cfg_attr(feature = "tabled", derive(Tabled))]
97#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
98pub struct UserDetailed {
99    #[cfg_attr(feature = "sqlx", sqlx(try_from = "i32"))]
100    pub id: u32,
101    pub name: String,
102    pub openstack_id: String, // UUIDv4 without dashes
103    #[cfg_attr(feature = "sqlx", sqlx(flatten))]
104    pub project: ProjectMinimal,
105    pub project_name: String,
106    pub role: u32,
107    pub is_staff: bool,
108    pub is_active: bool,
109}
110
111impl PartialEq<UserMinimal> for UserDetailed {
112    fn eq(&self, other: &UserMinimal) -> bool {
113        self.id == other.id && self.name == other.name
114    }
115}
116
117impl PartialEq<User> for UserDetailed {
118    fn eq(&self, other: &User) -> bool {
119        self.id == other.id
120            && self.name == other.name
121            && self.openstack_id == other.openstack_id
122            && self.project.id == other.project
123            && self.project.name == other.project_name
124            && self.project_name == other.project_name
125            && self.is_staff == other.is_staff
126            && self.is_active == other.is_active
127            && self.role == other.role
128    }
129}
130
131#[cfg_attr(feature = "tabled", derive(Tabled))]
132#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
133pub struct UserImport {
134    pub new_project_count: u32,
135    pub new_user_count: u32,
136}
137
138#[cfg_attr(feature = "tabled", derive(Tabled))]
139#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
140pub struct UserSync {
141    pub updated_project_count: u32,
142    pub updated_user_count: u32,
143}
144
145#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Default)]
146pub struct UserListParams {
147    pub all: Option<bool>,
148    pub project: Option<u32>,
149}
150
151#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
152pub struct UserCreateData {
153    pub name: String,
154    pub openstack_id: String, // UUIDv4
155    // TODO: can't this be optional?
156    pub project: u32,
157    #[serde(skip_serializing_if = "Option::is_none")]
158    // this could be an enum right
159    pub role: Option<u32>,
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub is_staff: Option<bool>,
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub is_active: Option<bool>,
164}
165
166impl UserCreateData {
167    pub fn new(name: String, openstack_id: String, project: u32) -> Self {
168        Self {
169            name,
170            openstack_id,
171            project,
172            role: None,
173            is_staff: None,
174            is_active: None,
175        }
176    }
177}
178
179#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
180pub struct UserModifyData {
181    pub id: u32,
182
183    #[serde(skip_serializing_if = "Option::is_none")]
184    pub name: Option<String>,
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub openstack_id: Option<String>, // UUIDv4
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub project: Option<u32>,
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub role: Option<u32>,
191    #[serde(skip_serializing_if = "Option::is_none")]
192    pub is_staff: Option<bool>,
193    #[serde(skip_serializing_if = "Option::is_none")]
194    pub is_active: Option<bool>,
195}
196
197impl UserModifyData {
198    pub fn new(id: u32) -> Self {
199        Self {
200            id,
201            name: None,
202            openstack_id: None,
203            project: None,
204            role: None,
205            is_staff: None,
206            is_active: None,
207        }
208    }
209}