sea_orm/entity/
identity.rs

1use crate::{ColumnTrait, EntityTrait, IdenStatic};
2use sea_query::{Alias, DynIden, Iden, IntoIden, SeaRc};
3use std::fmt;
4
5/// List of column identifier
6#[derive(Debug, Clone)]
7pub enum Identity {
8    /// Column identifier consists of 1 column
9    Unary(DynIden),
10    /// Column identifier consists of 2 columns
11    Binary(DynIden, DynIden),
12    /// Column identifier consists of 3 columns
13    Ternary(DynIden, DynIden, DynIden),
14    /// Column identifier consists of more than 3 columns
15    Many(Vec<DynIden>),
16}
17
18impl IntoIterator for Identity {
19    type Item = DynIden;
20    type IntoIter = std::vec::IntoIter<Self::Item>;
21
22    fn into_iter(self) -> Self::IntoIter {
23        match self {
24            Identity::Unary(ident1) => vec![ident1].into_iter(),
25            Identity::Binary(ident1, ident2) => vec![ident1, ident2].into_iter(),
26            Identity::Ternary(ident1, ident2, ident3) => vec![ident1, ident2, ident3].into_iter(),
27            Identity::Many(vec) => vec.into_iter(),
28        }
29    }
30}
31
32impl Iden for Identity {
33    fn unquoted(&self, s: &mut dyn fmt::Write) {
34        match self {
35            Identity::Unary(iden) => {
36                write!(s, "{}", iden.to_string()).unwrap();
37            }
38            Identity::Binary(iden1, iden2) => {
39                write!(s, "{}", iden1.to_string()).unwrap();
40                write!(s, "{}", iden2.to_string()).unwrap();
41            }
42            Identity::Ternary(iden1, iden2, iden3) => {
43                write!(s, "{}", iden1.to_string()).unwrap();
44                write!(s, "{}", iden2.to_string()).unwrap();
45                write!(s, "{}", iden3.to_string()).unwrap();
46            }
47            Identity::Many(vec) => {
48                for iden in vec.iter() {
49                    write!(s, "{}", iden.to_string()).unwrap();
50                }
51            }
52        }
53    }
54}
55
56/// Performs a conversion into an [Identity]
57pub trait IntoIdentity {
58    /// Method to perform the conversion
59    fn into_identity(self) -> Identity;
60}
61
62/// Check the [Identity] of an Entity
63pub trait IdentityOf<E>
64where
65    E: EntityTrait,
66{
67    /// Method to call to perform this check
68    fn identity_of(self) -> Identity;
69}
70
71impl IntoIdentity for Identity {
72    fn into_identity(self) -> Identity {
73        self
74    }
75}
76
77impl IntoIdentity for String {
78    fn into_identity(self) -> Identity {
79        self.as_str().into_identity()
80    }
81}
82
83impl IntoIdentity for &str {
84    fn into_identity(self) -> Identity {
85        Identity::Unary(SeaRc::new(Alias::new(self)))
86    }
87}
88
89impl<T> IntoIdentity for T
90where
91    T: IdenStatic,
92{
93    fn into_identity(self) -> Identity {
94        Identity::Unary(self.into_iden())
95    }
96}
97
98impl<T, C> IntoIdentity for (T, C)
99where
100    T: IdenStatic,
101    C: IdenStatic,
102{
103    fn into_identity(self) -> Identity {
104        Identity::Binary(self.0.into_iden(), self.1.into_iden())
105    }
106}
107
108impl<T, C, R> IntoIdentity for (T, C, R)
109where
110    T: IdenStatic,
111    C: IdenStatic,
112    R: IdenStatic,
113{
114    fn into_identity(self) -> Identity {
115        Identity::Ternary(self.0.into_iden(), self.1.into_iden(), self.2.into_iden())
116    }
117}
118
119macro_rules! impl_into_identity {
120    ( $($T:ident : $N:tt),+ $(,)? ) => {
121        impl< $($T),+ > IntoIdentity for ( $($T),+ )
122        where
123            $($T: IdenStatic),+
124        {
125            fn into_identity(self) -> Identity {
126                Identity::Many(vec![
127                    $(self.$N.into_iden()),+
128                ])
129            }
130        }
131    };
132}
133
134#[rustfmt::skip]
135mod impl_into_identity {
136    use super::*;
137
138    impl_into_identity!(T0:0, T1:1, T2:2, T3:3);
139    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4);
140    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5);
141    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6);
142    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7);
143    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8);
144    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9);
145    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10);
146    impl_into_identity!(T0:0, T1:1, T2:2, T3:3, T4:4, T5:5, T6:6, T7:7, T8:8, T9:9, T10:10, T11:11);
147}
148
149impl<E, C> IdentityOf<E> for C
150where
151    E: EntityTrait<Column = C>,
152    C: ColumnTrait,
153{
154    fn identity_of(self) -> Identity {
155        self.into_identity()
156    }
157}
158
159macro_rules! impl_identity_of {
160    ( $($T:ident),+ $(,)? ) => {
161        impl<E, C> IdentityOf<E> for ( $($T),+ )
162        where
163            E: EntityTrait<Column = C>,
164            C: ColumnTrait,
165        {
166            fn identity_of(self) -> Identity {
167                self.into_identity()
168            }
169        }
170    };
171}
172
173#[rustfmt::skip]
174mod impl_identity_of {
175    use super::*;
176
177    impl_identity_of!(C, C);
178    impl_identity_of!(C, C, C);
179    impl_identity_of!(C, C, C, C);
180    impl_identity_of!(C, C, C, C, C);
181    impl_identity_of!(C, C, C, C, C, C);
182    impl_identity_of!(C, C, C, C, C, C, C);
183    impl_identity_of!(C, C, C, C, C, C, C, C);
184    impl_identity_of!(C, C, C, C, C, C, C, C, C);
185    impl_identity_of!(C, C, C, C, C, C, C, C, C, C);
186    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C);
187    impl_identity_of!(C, C, C, C, C, C, C, C, C, C, C, C);
188}