@@ -2,29 +2,22 @@ use std::fs::File;
2
2
use std:: io:: { Write , BufWriter } ;
3
3
use std:: path:: Path ;
4
4
use phf_codegen;
5
-
6
- use snake_to_camel;
5
+ use linked_hash_map:: LinkedHashMap ;
7
6
8
7
const ERRCODES_TXT : & ' static str = include_str ! ( "errcodes.txt" ) ;
9
8
10
- struct Code {
11
- code : String ,
12
- variant : String ,
13
- }
14
-
15
9
pub fn build ( path : & Path ) {
16
10
let mut file = BufWriter :: new ( File :: create ( path. join ( "error/sqlstate.rs" ) ) . unwrap ( ) ) ;
17
11
18
12
let codes = parse_codes ( ) ;
19
13
20
- make_header ( & mut file) ;
21
- make_enum ( & codes, & mut file) ;
14
+ make_type ( & mut file) ;
15
+ make_consts ( & codes, & mut file) ;
22
16
make_map ( & codes, & mut file) ;
23
- make_impl ( & codes, & mut file) ;
24
17
}
25
18
26
- fn parse_codes ( ) -> Vec < Code > {
27
- let mut codes = vec ! [ ] ;
19
+ fn parse_codes ( ) -> LinkedHashMap < String , Vec < String > > {
20
+ let mut codes = LinkedHashMap :: new ( ) ;
28
21
29
22
for line in ERRCODES_TXT . lines ( ) {
30
23
if line. starts_with ( "#" ) || line. starts_with ( "Section" ) || line. trim ( ) . is_empty ( ) {
@@ -34,131 +27,70 @@ fn parse_codes() -> Vec<Code> {
34
27
let mut it = line. split_whitespace ( ) ;
35
28
let code = it. next ( ) . unwrap ( ) . to_owned ( ) ;
36
29
it. next ( ) ;
37
- it. next ( ) ;
38
- // for 2202E
39
- let name = match it. next ( ) {
40
- Some ( name) => name,
41
- None => continue ,
42
- } ;
43
- let variant = match variant_name ( & code) {
44
- Some ( variant) => variant,
45
- None => snake_to_camel ( & name) ,
46
- } ;
30
+ let name = it. next ( ) . unwrap ( ) . replace ( "ERRCODE_" , "" ) ;
47
31
48
- codes. push ( Code {
49
- code : code,
50
- variant : variant,
51
- } ) ;
32
+ codes. entry ( code) . or_insert_with ( Vec :: new) . push ( name) ;
52
33
}
53
34
54
35
codes
55
36
}
56
37
57
- fn variant_name ( code : & str ) -> Option < String > {
58
- match code {
59
- "01004" => Some ( "WarningStringDataRightTruncation" . to_owned ( ) ) ,
60
- "22001" => Some ( "DataStringDataRightTruncation" . to_owned ( ) ) ,
61
- "2F002" => Some ( "SqlRoutineModifyingSqlDataNotPermitted" . to_owned ( ) ) ,
62
- "38002" => Some ( "ForeignRoutineModifyingSqlDataNotPermitted" . to_owned ( ) ) ,
63
- "2F003" => Some ( "SqlRoutineProhibitedSqlStatementAttempted" . to_owned ( ) ) ,
64
- "38003" => Some ( "ForeignRoutineProhibitedSqlStatementAttempted" . to_owned ( ) ) ,
65
- "2F004" => Some ( "SqlRoutineReadingSqlDataNotPermitted" . to_owned ( ) ) ,
66
- "38004" => Some ( "ForeignRoutineReadingSqlDataNotPermitted" . to_owned ( ) ) ,
67
- "22004" => Some ( "DataNullValueNotAllowed" . to_owned ( ) ) ,
68
- "39004" => Some ( "ExternalRoutineInvocationNullValueNotAllowed" . to_owned ( ) ) ,
69
- _ => None ,
70
- }
71
- }
72
-
73
- fn make_header ( file : & mut BufWriter < File > ) {
38
+ fn make_type ( file : & mut BufWriter < File > ) {
74
39
write ! (
75
40
file,
76
41
"// Autogenerated file - DO NOT EDIT
77
42
use phf;
43
+ use std::borrow::Cow;
78
44
79
- "
80
- ) . unwrap ( ) ;
81
- }
82
-
83
- fn make_enum ( codes : & [ Code ] , file : & mut BufWriter < File > ) {
84
- write ! (
85
- file,
86
- r#"/// SQLSTATE error codes
45
+ /// A SQLSTATE error code
87
46
#[derive(PartialEq, Eq, Clone, Debug)]
88
- #[allow(enum_variant_names)]
89
- pub enum SqlState {{
90
- "#
91
- ) . unwrap ( ) ;
92
-
93
- for code in codes {
94
- write ! (
95
- file,
96
- " /// `{}`
97
- {},\n " ,
98
- code. code,
99
- code. variant
100
- ) . unwrap ( ) ;
101
- }
102
-
103
- write ! (
104
- file,
105
- " /// An unknown code
106
- Other(String),
107
- }}
108
-
109
- "
110
- ) . unwrap ( ) ;
111
- }
112
-
113
- fn make_map ( codes : & [ Code ] , file : & mut BufWriter < File > ) {
114
- write ! (
115
- file,
116
- "#[cfg_attr(rustfmt, rustfmt_skip)]
117
- static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = "
118
- ) . unwrap ( ) ;
119
- let mut builder = phf_codegen:: Map :: new ( ) ;
120
- for code in codes {
121
- builder. entry ( & * code. code , & format ! ( "SqlState::{}" , code. variant) ) ;
122
- }
123
- builder. build ( file) . unwrap ( ) ;
124
- write ! ( file, ";\n " ) . unwrap ( ) ;
125
- }
47
+ pub struct SqlState(Cow<'static, str>);
126
48
127
- fn make_impl ( codes : & [ Code ] , file : & mut BufWriter < File > ) {
128
- write ! (
129
- file,
130
- r#"
131
49
impl SqlState {{
132
50
/// Creates a `SqlState` from its error code.
133
51
pub fn from_code(s: &str) -> SqlState {{
134
52
match SQLSTATE_MAP.get(s) {{
135
53
Some(state) => state.clone(),
136
- None => SqlState::Other (s.to_owned( )),
54
+ None => SqlState(Cow::Owned (s.to_string() )),
137
55
}}
138
56
}}
139
57
140
58
/// Returns the error code corresponding to the `SqlState`.
141
59
pub fn code(&self) -> &str {{
142
- match *self {{"#
60
+ &self.0
61
+ }}
62
+ }}
63
+ "
143
64
) . unwrap ( ) ;
65
+ }
144
66
145
- for code in codes {
146
- write ! (
147
- file,
148
- r#"
149
- SqlState::{} => "{}","# ,
150
- code. variant,
151
- code. code
152
- ) . unwrap ( ) ;
67
+ fn make_consts ( codes : & LinkedHashMap < String , Vec < String > > , file : & mut BufWriter < File > ) {
68
+ for ( code, names) in codes {
69
+ for name in names {
70
+ write ! (
71
+ file,
72
+ r#"
73
+ /// {code}
74
+ pub const {name}: SqlState = SqlState(Cow::Borrowed("{code}"));
75
+ "# ,
76
+ name = name,
77
+ code = code,
78
+ ) . unwrap ( ) ;
79
+ }
153
80
}
81
+ }
154
82
83
+ fn make_map ( codes : & LinkedHashMap < String , Vec < String > > , file : & mut BufWriter < File > ) {
155
84
write ! (
156
85
file,
157
- r#"
158
- SqlState::Other(ref s) => s,
159
- }}
160
- }}
161
- }}
162
- "#
86
+ "
87
+ #[cfg_attr(rustfmt, rustfmt_skip)]
88
+ static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = "
163
89
) . unwrap ( ) ;
90
+ let mut builder = phf_codegen:: Map :: new ( ) ;
91
+ for ( code, names) in codes {
92
+ builder. entry ( & * * code, & names[ 0 ] ) ;
93
+ }
94
+ builder. build ( file) . unwrap ( ) ;
95
+ write ! ( file, ";\n " ) . unwrap ( ) ;
164
96
}
0 commit comments