metabase_api_rs/core/models/
common.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
7#[serde(transparent)]
8pub struct MetabaseId(pub i64);
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(transparent)]
13pub struct UserId(pub i64);
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17#[serde(transparent)]
18pub struct CardId(pub i32);
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[serde(transparent)]
23pub struct CollectionId(pub i32);
24
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27#[serde(transparent)]
28pub struct DashboardId(pub i32);
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
32#[serde(transparent)]
33pub struct DatabaseId(pub i32);
34
35impl UserId {
36 pub fn new(id: i64) -> Self {
38 Self(id)
39 }
40
41 pub fn as_i64(&self) -> i64 {
43 self.0
44 }
45}
46
47impl fmt::Display for UserId {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(f, "{}", self.0)
50 }
51}
52
53impl MetabaseId {
54 pub fn new(id: i64) -> Self {
56 Self(id)
57 }
58
59 pub fn as_i64(&self) -> i64 {
61 self.0
62 }
63}
64
65impl fmt::Display for MetabaseId {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 write!(f, "{}", self.0)
68 }
69}
70
71#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
73#[serde(transparent)]
74pub struct MetabaseDateTime(DateTime<Utc>);
75
76impl MetabaseDateTime {
77 pub fn new(dt: DateTime<Utc>) -> Self {
79 Self(dt)
80 }
81
82 pub fn into_inner(self) -> DateTime<Utc> {
84 self.0
85 }
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
90pub struct Pagination {
91 limit: usize,
92 offset: usize,
93}
94
95impl Pagination {
96 pub fn new(limit: usize, offset: usize) -> Self {
98 Self { limit, offset }
99 }
100
101 pub fn with_page(limit: usize, page: usize) -> Self {
103 let offset = if page > 0 { (page - 1) * limit } else { 0 };
104 Self { limit, offset }
105 }
106
107 pub fn limit(&self) -> usize {
109 self.limit
110 }
111
112 pub fn offset(&self) -> usize {
114 self.offset
115 }
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
120#[serde(rename_all = "lowercase")]
121pub enum Visibility {
122 Public,
123 Private,
124 Limited,
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
129#[serde(rename_all = "lowercase")]
130pub enum ExportFormat {
131 Csv,
133 Json,
135 Xlsx,
137}
138
139impl ExportFormat {
140 pub fn as_str(&self) -> &str {
142 match self {
143 Self::Csv => "csv",
144 Self::Json => "json",
145 Self::Xlsx => "xlsx",
146 }
147 }
148}
149
150impl fmt::Display for ExportFormat {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
152 write!(f, "{}", self.as_str())
153 }
154}
155
156#[cfg(test)]
157mod tests {
158 use super::*;
159 use serde_json;
160
161 #[test]
162 fn test_metabase_id_serialize_deserialize() {
163 let id = MetabaseId::new(123);
164
165 let json = serde_json::to_string(&id).unwrap();
167 assert_eq!(json, "123");
168
169 let deserialized: MetabaseId = serde_json::from_str("456").unwrap();
171 assert_eq!(deserialized.as_i64(), 456);
172 }
173
174 #[test]
175 fn test_metabase_id_display() {
176 let id = MetabaseId::new(789);
177 assert_eq!(format!("{}", id), "789");
178 }
179
180 #[test]
181 fn test_metabase_datetime_serialize_deserialize() {
182 let dt_str = "2023-08-08T10:30:00Z";
183 let dt: MetabaseDateTime = serde_json::from_str(&format!("\"{}\"", dt_str)).unwrap();
184
185 let inner: DateTime<Utc> = dt.into_inner();
187 assert_eq!(inner.to_rfc3339(), "2023-08-08T10:30:00+00:00");
188 }
189
190 #[test]
191 fn test_pagination() {
192 let pagination = Pagination::new(10, 20);
193 assert_eq!(pagination.limit(), 10);
194 assert_eq!(pagination.offset(), 20);
195
196 let page_2 = Pagination::with_page(50, 2);
198 assert_eq!(page_2.limit(), 50);
199 assert_eq!(page_2.offset(), 50); }
201
202 #[test]
203 fn test_visibility_enum() {
204 let public = Visibility::Public;
205 let json = serde_json::to_string(&public).unwrap();
206 assert_eq!(json, "\"public\"");
207
208 let private: Visibility = serde_json::from_str("\"private\"").unwrap();
209 assert_eq!(private, Visibility::Private);
210 }
211
212 #[test]
213 fn test_export_format() {
214 let csv = ExportFormat::Csv;
216 let json_str = serde_json::to_string(&csv).unwrap();
217 assert_eq!(json_str, "\"csv\"");
218
219 let xlsx: ExportFormat = serde_json::from_str("\"xlsx\"").unwrap();
221 assert_eq!(xlsx, ExportFormat::Xlsx);
222
223 assert_eq!(ExportFormat::Csv.as_str(), "csv");
225 assert_eq!(ExportFormat::Json.as_str(), "json");
226 assert_eq!(ExportFormat::Xlsx.as_str(), "xlsx");
227
228 assert_eq!(format!("{}", ExportFormat::Json), "json");
230 }
231}