1use std::fmt::Display;
2
3use serde::{Deserialize, Serialize};
4
5use crate::filter::FilterNode;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[serde(untagged)]
9pub enum Id {
10 I32(i32),
11 I64(i64),
12 String(String),
13 #[cfg(feature = "with-uuid")]
14 Uuid(uuid::Uuid),
15}
16
17impl Display for Id {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 match self {
20 Id::I32(id) => write!(f, "{id}"),
21 Id::I64(id) => write!(f, "{id}"),
22 Id::String(id) => write!(f, "{id}"),
23 #[cfg(feature = "with-uuid")]
24 Id::Uuid(id) => write!(f, "{id}"),
25 }
26 }
27}
28
29impl Id {
30 pub fn to_filter_node(&self, col: &str) -> FilterNode {
31 match self {
32 Id::I32(id) => (col, *id).into(),
33 Id::I64(id) => (col, *id).into(),
34 Id::String(id) => (col, id.to_string()).into(),
35 #[cfg(feature = "with-uuid")]
36 Id::Uuid(id) => (col, id).into(),
37 }
38 }
39}
40
41#[cfg(feature = "with-sea-query")]
48impl From<Id> for sea_query::SimpleExpr {
49 fn from(value: Id) -> Self {
50 match value {
51 Id::I32(id) => sea_query::SimpleExpr::Value(id.into()),
52 Id::I64(id) => sea_query::SimpleExpr::Value(id.into()),
53 Id::String(id) => sea_query::SimpleExpr::Value(id.into()),
54 #[cfg(feature = "with-uuid")]
55 Id::Uuid(id) => sea_query::SimpleExpr::Value(id.into()),
56 }
57 }
58}
59
60impl From<i32> for Id {
61 fn from(value: i32) -> Self {
62 Id::I32(value)
63 }
64}
65
66impl From<i64> for Id {
67 fn from(value: i64) -> Self {
68 Id::I64(value)
69 }
70}
71
72impl From<String> for Id {
73 fn from(value: String) -> Self {
74 Id::String(value)
75 }
76}
77
78impl From<&str> for Id {
79 fn from(value: &str) -> Self {
80 Id::String(value.to_string())
81 }
82}
83
84#[cfg(feature = "with-uuid")]
85impl From<uuid::Uuid> for Id {
86 fn from(value: uuid::Uuid) -> Self {
87 Id::Uuid(value)
88 }
89}
90
91#[cfg(feature = "with-uuid")]
92impl From<&uuid::Uuid> for Id {
93 fn from(value: &uuid::Uuid) -> Self {
94 Id::Uuid(*value)
95 }
96}
97
98pub fn to_vec_id<V, I>(ids: I) -> Vec<Id>
99where
100 V: Into<Id>,
101 I: IntoIterator<Item = V>,
102{
103 ids.into_iter().map(|v| v.into()).collect()
104}
105
106#[cfg(test)]
107mod tests {
108 use super::*;
109
110 #[cfg(feature = "with-uuid")]
111 use uuid::Uuid;
112
113 #[derive(PartialEq, Serialize, Deserialize)]
114 struct TestModel {
115 pub role_id: i32,
116 pub user_id: i64,
117 #[cfg(feature = "with-uuid")]
118 pub order_id: Uuid,
119 #[cfg(not(feature = "with-uuid"))]
120 pub order_id: String,
121 pub dict_id: String,
122 }
123
124 #[test]
125 fn test_id() {
126 let id = Id::I32(32);
127 println!("id is {id:?}");
128
129 #[cfg(feature = "with-uuid")]
130 let order_id = Uuid::now_v7();
131 #[cfg(not(feature = "with-uuid"))]
132 let order_id = "1234567890".to_ascii_lowercase();
133 assert_eq!("32", serde_json::to_string(&id).unwrap());
134 assert_eq!(serde_json::to_string(&Id::String("abcdefg".into())).unwrap(), r#""abcdefg""#);
135
136 let tm = TestModel { role_id: 53, user_id: 2309457238947, order_id, dict_id: "system.run.mode".to_string() };
137
138 let v = serde_json::to_value(tm).unwrap();
139 let role_id: i32 = serde_json::from_value(v.get("role_id").unwrap().clone()).unwrap();
140 assert_eq!(role_id, 53);
141 }
142}