1use std::fmt::{self, Display, Formatter};
2
3use crate::collation::Collation;
4use crate::protocol::text::{ColumnDefinition, ColumnFlags, ColumnType};
5pub(crate) use sqlx_core::type_info::*;
6
7#[derive(Debug, Clone)]
9#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
10pub struct MySqlTypeInfo {
11 pub(crate) r#type: ColumnType,
12 pub(crate) flags: ColumnFlags,
13 pub(crate) collation: Collation,
14
15 #[cfg_attr(feature = "offline", serde(default))]
17 pub(crate) max_size: Option<u32>,
18}
19
20impl MySqlTypeInfo {
21 pub(crate) const fn binary(ty: ColumnType) -> Self {
22 Self {
23 r#type: ty,
24 flags: ColumnFlags::BINARY,
25 collation: Collation::BINARY,
26 max_size: None,
27 }
28 }
29
30 #[doc(hidden)]
31 pub const fn __enum() -> Self {
32 Self {
41 r#type: ColumnType::String,
42 flags: ColumnFlags::ENUM,
43 collation: Collation::UTF8MB4_GENERAL_CI,
44 max_size: None,
45 }
46 }
47
48 #[doc(hidden)]
49 pub fn __type_feature_gate(&self) -> Option<&'static str> {
50 match self.r#type {
51 ColumnType::Date | ColumnType::Time | ColumnType::Timestamp | ColumnType::Datetime => {
52 Some("time")
53 }
54
55 ColumnType::Json => Some("json"),
56 ColumnType::NewDecimal => Some("bigdecimal"),
57
58 _ => None,
59 }
60 }
61
62 pub(crate) fn from_column(column: &ColumnDefinition) -> Self {
63 Self {
64 r#type: column.r#type,
65 flags: column.flags,
66 collation: column.collation,
67 max_size: Some(column.max_size),
68 }
69 }
70}
71
72impl Display for MySqlTypeInfo {
73 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
74 f.pad(self.name())
75 }
76}
77
78impl TypeInfo for MySqlTypeInfo {
79 fn is_null(&self) -> bool {
80 matches!(self.r#type, ColumnType::Null)
81 }
82
83 fn name(&self) -> &str {
84 self.r#type.name(self.flags, self.max_size)
85 }
86}
87
88impl PartialEq<MySqlTypeInfo> for MySqlTypeInfo {
89 fn eq(&self, other: &MySqlTypeInfo) -> bool {
90 if self.r#type != other.r#type {
91 return false;
92 }
93
94 match self.r#type {
95 ColumnType::Tiny
96 | ColumnType::Short
97 | ColumnType::Long
98 | ColumnType::Int24
99 | ColumnType::LongLong => {
100 return self.flags.contains(ColumnFlags::UNSIGNED)
101 == other.flags.contains(ColumnFlags::UNSIGNED);
102 }
103
104 ColumnType::VarChar
106 | ColumnType::Blob
107 | ColumnType::TinyBlob
108 | ColumnType::MediumBlob
109 | ColumnType::LongBlob
110 | ColumnType::String
111 | ColumnType::VarString
112 | ColumnType::Enum => {
113 return self.flags == other.flags;
114 }
115 _ => {}
116 }
117
118 true
119 }
120}
121
122impl Eq for MySqlTypeInfo {}