1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_repr::{Deserialize_repr, Serialize_repr};
4use std::fmt::Display;
5use tsync::tsync;
6
7#[derive(Deserialize_repr, Serialize_repr, Debug, Clone, Copy, PartialEq, Eq, Default)]
10#[repr(u8)]
11#[tsync]
12pub enum TenantKind {
13 #[default]
14 Personal = 0,
15 Organization = 1,
16}
17
18impl Display for TenantKind {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 match self {
21 TenantKind::Personal => write!(f, "personal"),
22 TenantKind::Organization => write!(f, "organization"),
23 }
24 }
25}
26
27#[derive(Deserialize_repr, Serialize_repr, Debug, Clone, Copy, PartialEq, Eq)]
30#[repr(u8)]
31#[tsync]
32pub enum TenantRole {
33 Owner = 0,
34 Admin = 1,
35 Member = 2,
36}
37
38impl Display for TenantRole {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 match self {
41 TenantRole::Owner => write!(f, "owner"),
42 TenantRole::Admin => write!(f, "admin"),
43 TenantRole::Member => write!(f, "member"),
44 }
45 }
46}
47
48#[derive(Serialize, Deserialize, Debug, Clone)]
49#[tsync]
50pub struct TenantProject {
51 pub id: i32,
52 pub name: String,
53}
54
55#[derive(Serialize, Deserialize, Debug, Clone)]
56#[tsync]
57pub struct Tenant {
58 pub id: i64,
59 pub name: String,
60 pub slug: String,
61 pub kind: TenantKind,
62 pub role: TenantRole,
64 pub projects_count: i64,
65 pub default_project: Option<TenantProject>,
66 #[serde(default)]
68 pub current: bool,
69 pub created_at: DateTime<Utc>,
70}
71
72impl Display for Tenant {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 write!(f, "ID: {}, Name: {}", self.id, self.name)
75 }
76}
77
78#[derive(Serialize, Deserialize, Debug, Clone)]
81#[tsync]
82pub struct TenantCreate {
83 pub name: String,
84}
85
86#[derive(Serialize, Deserialize, Debug, Clone, Default)]
87#[tsync]
88pub struct TenantUpdate {
89 #[serde(skip_serializing_if = "Option::is_none")]
90 pub name: Option<String>,
91}
92
93impl TenantUpdate {
94 pub fn is_empty(&self) -> bool {
95 self.name.is_none()
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102 use serde_json::json;
103
104 #[test]
105 fn test_tenant_create() {
106 let tenant_create = TenantCreate {
107 name: "Acme".to_owned(),
108 };
109 let json = json!({ "name": "Acme" });
110 assert_eq!(serde_json::to_value(tenant_create).unwrap(), json);
111 }
112
113 #[test]
114 fn test_tenant_update_is_empty() {
115 assert!(TenantUpdate::default().is_empty());
116 assert!(!TenantUpdate {
117 name: Some("Acme".to_owned())
118 }
119 .is_empty());
120 }
121}