sqlx_rxqlite/
type_info.rs1use std::fmt::{self, Display, Formatter};
2use std::str::FromStr;
3
4use crate::error::BoxDynError;
7
8pub(crate) use sqlx_core::type_info::*;
9
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
11#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
12pub(crate) enum DataType {
13 Null,
14 Int,
15 Float,
16 Text,
17 Blob,
18
19 #[allow(dead_code)]
21 Numeric,
22
23 Bool,
25 Int64,
26 Date,
27 Time,
28 Datetime,
29}
30
31#[derive(Debug, Clone, Eq, PartialEq, Hash)]
33#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
34pub struct RXQLiteTypeInfo(pub(crate) DataType);
35
36impl Display for RXQLiteTypeInfo {
37 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
38 f.pad(self.name())
39 }
40}
41
42impl TypeInfo for RXQLiteTypeInfo {
43 fn is_null(&self) -> bool {
44 matches!(self.0, DataType::Null)
45 }
46
47 fn name(&self) -> &str {
48 match self.0 {
49 DataType::Null => "NULL",
50 DataType::Text => "TEXT",
51 DataType::Float => "REAL",
52 DataType::Blob => "BLOB",
53 DataType::Int | DataType::Int64 => "INTEGER",
54 DataType::Numeric => "NUMERIC",
55
56 DataType::Bool => "BOOLEAN",
58 DataType::Date => "DATE",
59 DataType::Time => "TIME",
60 DataType::Datetime => "DATETIME",
61 }
62 }
63}
64
65impl FromStr for DataType {
69 type Err = BoxDynError;
70
71 fn from_str(s: &str) -> Result<Self, Self::Err> {
72 let s = s.to_ascii_lowercase();
73 Ok(match &*s {
74 "int4" => DataType::Int,
75 "int8" => DataType::Int64,
76 "boolean" | "bool" => DataType::Bool,
77
78 "date" => DataType::Date,
79 "time" => DataType::Time,
80 "datetime" | "timestamp" => DataType::Datetime,
81
82 _ if s.contains("int") => DataType::Int64,
83
84 _ if s.contains("char") || s.contains("clob") || s.contains("text") => DataType::Text,
85
86 _ if s.contains("blob") => DataType::Blob,
87
88 _ if s.contains("real") || s.contains("floa") || s.contains("doub") => DataType::Float,
89
90 _ => {
91 return Err(format!("unknown type: `{s}`").into());
92 }
93 })
94 }
95}
96
97#[test]
106fn test_data_type_from_str() -> Result<(), BoxDynError> {
107 assert_eq!(DataType::Int, "INT4".parse()?);
108
109 assert_eq!(DataType::Int64, "INT".parse()?);
110 assert_eq!(DataType::Int64, "INTEGER".parse()?);
111 assert_eq!(DataType::Int64, "INTBIG".parse()?);
112 assert_eq!(DataType::Int64, "MEDIUMINT".parse()?);
113
114 assert_eq!(DataType::Int64, "BIGINT".parse()?);
115 assert_eq!(DataType::Int64, "UNSIGNED BIG INT".parse()?);
116 assert_eq!(DataType::Int64, "INT8".parse()?);
117
118 assert_eq!(DataType::Text, "CHARACTER(20)".parse()?);
119 assert_eq!(DataType::Text, "NCHAR(55)".parse()?);
120 assert_eq!(DataType::Text, "TEXT".parse()?);
121 assert_eq!(DataType::Text, "CLOB".parse()?);
122
123 assert_eq!(DataType::Blob, "BLOB".parse()?);
124
125 assert_eq!(DataType::Float, "REAL".parse()?);
126 assert_eq!(DataType::Float, "FLOAT".parse()?);
127 assert_eq!(DataType::Float, "DOUBLE PRECISION".parse()?);
128
129 assert_eq!(DataType::Bool, "BOOLEAN".parse()?);
130 assert_eq!(DataType::Bool, "BOOL".parse()?);
131
132 assert_eq!(DataType::Datetime, "DATETIME".parse()?);
133 assert_eq!(DataType::Time, "TIME".parse()?);
134 assert_eq!(DataType::Date, "DATE".parse()?);
135
136 Ok(())
137}