use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MetabaseId(pub i64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct UserId(pub i64);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct CardId(pub i32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct CollectionId(pub i32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct DashboardId(pub i32);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct DatabaseId(pub i32);
impl UserId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn as_i64(&self) -> i64 {
self.0
}
}
impl fmt::Display for UserId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl MetabaseId {
pub fn new(id: i64) -> Self {
Self(id)
}
pub fn as_i64(&self) -> i64 {
self.0
}
}
impl fmt::Display for MetabaseId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MetabaseDateTime(DateTime<Utc>);
impl MetabaseDateTime {
pub fn new(dt: DateTime<Utc>) -> Self {
Self(dt)
}
pub fn into_inner(self) -> DateTime<Utc> {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pagination {
limit: usize,
offset: usize,
}
impl Pagination {
pub fn new(limit: usize, offset: usize) -> Self {
Self { limit, offset }
}
pub fn with_page(limit: usize, page: usize) -> Self {
let offset = if page > 0 { (page - 1) * limit } else { 0 };
Self { limit, offset }
}
pub fn limit(&self) -> usize {
self.limit
}
pub fn offset(&self) -> usize {
self.offset
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum Visibility {
Public,
Private,
Limited,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum ExportFormat {
Csv,
Json,
Xlsx,
}
impl ExportFormat {
pub fn as_str(&self) -> &str {
match self {
Self::Csv => "csv",
Self::Json => "json",
Self::Xlsx => "xlsx",
}
}
}
impl fmt::Display for ExportFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn test_metabase_id_serialize_deserialize() {
let id = MetabaseId::new(123);
let json = serde_json::to_string(&id).unwrap();
assert_eq!(json, "123");
let deserialized: MetabaseId = serde_json::from_str("456").unwrap();
assert_eq!(deserialized.as_i64(), 456);
}
#[test]
fn test_metabase_id_display() {
let id = MetabaseId::new(789);
assert_eq!(format!("{}", id), "789");
}
#[test]
fn test_metabase_datetime_serialize_deserialize() {
let dt_str = "2023-08-08T10:30:00Z";
let dt: MetabaseDateTime = serde_json::from_str(&format!("\"{}\"", dt_str)).unwrap();
let inner: DateTime<Utc> = dt.into_inner();
assert_eq!(inner.to_rfc3339(), "2023-08-08T10:30:00+00:00");
}
#[test]
fn test_pagination() {
let pagination = Pagination::new(10, 20);
assert_eq!(pagination.limit(), 10);
assert_eq!(pagination.offset(), 20);
let page_2 = Pagination::with_page(50, 2);
assert_eq!(page_2.limit(), 50);
assert_eq!(page_2.offset(), 50); }
#[test]
fn test_visibility_enum() {
let public = Visibility::Public;
let json = serde_json::to_string(&public).unwrap();
assert_eq!(json, "\"public\"");
let private: Visibility = serde_json::from_str("\"private\"").unwrap();
assert_eq!(private, Visibility::Private);
}
#[test]
fn test_export_format() {
let csv = ExportFormat::Csv;
let json_str = serde_json::to_string(&csv).unwrap();
assert_eq!(json_str, "\"csv\"");
let xlsx: ExportFormat = serde_json::from_str("\"xlsx\"").unwrap();
assert_eq!(xlsx, ExportFormat::Xlsx);
assert_eq!(ExportFormat::Csv.as_str(), "csv");
assert_eq!(ExportFormat::Json.as_str(), "json");
assert_eq!(ExportFormat::Xlsx.as_str(), "xlsx");
assert_eq!(format!("{}", ExportFormat::Json), "json");
}
}