Skip to content

Commit 01a1529

Browse files
committed
Make SqlState into an opaque type rather than enum
1 parent 6f0950b commit 01a1529

File tree

11 files changed

+1090
-1127
lines changed

11 files changed

+1090
-1127
lines changed

codegen/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ authors = ["Steven Fackler <[email protected]>"]
77
phf_codegen = "=0.7.21"
88
regex = "0.1"
99
marksman_escape = "0.1"
10+
linked-hash-map = "0.4"

codegen/src/main.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
extern crate phf_codegen;
22
extern crate regex;
33
extern crate marksman_escape;
4+
extern crate linked_hash_map;
45

56
use std::ascii::AsciiExt;
67
use std::path::Path;

codegen/src/sqlstate.rs

+41-109
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,22 @@ use std::fs::File;
22
use std::io::{Write, BufWriter};
33
use std::path::Path;
44
use phf_codegen;
5-
6-
use snake_to_camel;
5+
use linked_hash_map::LinkedHashMap;
76

87
const ERRCODES_TXT: &'static str = include_str!("errcodes.txt");
98

10-
struct Code {
11-
code: String,
12-
variant: String,
13-
}
14-
159
pub fn build(path: &Path) {
1610
let mut file = BufWriter::new(File::create(path.join("error/sqlstate.rs")).unwrap());
1711

1812
let codes = parse_codes();
1913

20-
make_header(&mut file);
21-
make_enum(&codes, &mut file);
14+
make_type(&mut file);
15+
make_consts(&codes, &mut file);
2216
make_map(&codes, &mut file);
23-
make_impl(&codes, &mut file);
2417
}
2518

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();
2821

2922
for line in ERRCODES_TXT.lines() {
3023
if line.starts_with("#") || line.starts_with("Section") || line.trim().is_empty() {
@@ -34,131 +27,70 @@ fn parse_codes() -> Vec<Code> {
3427
let mut it = line.split_whitespace();
3528
let code = it.next().unwrap().to_owned();
3629
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_", "");
4731

48-
codes.push(Code {
49-
code: code,
50-
variant: variant,
51-
});
32+
codes.entry(code).or_insert_with(Vec::new).push(name);
5233
}
5334

5435
codes
5536
}
5637

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>) {
7439
write!(
7540
file,
7641
"// Autogenerated file - DO NOT EDIT
7742
use phf;
43+
use std::borrow::Cow;
7844
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
8746
#[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>);
12648
127-
fn make_impl(codes: &[Code], file: &mut BufWriter<File>) {
128-
write!(
129-
file,
130-
r#"
13149
impl SqlState {{
13250
/// Creates a `SqlState` from its error code.
13351
pub fn from_code(s: &str) -> SqlState {{
13452
match SQLSTATE_MAP.get(s) {{
13553
Some(state) => state.clone(),
136-
None => SqlState::Other(s.to_owned()),
54+
None => SqlState(Cow::Owned(s.to_string())),
13755
}}
13856
}}
13957
14058
/// Returns the error code corresponding to the `SqlState`.
14159
pub fn code(&self) -> &str {{
142-
match *self {{"#
60+
&self.0
61+
}}
62+
}}
63+
"
14364
).unwrap();
65+
}
14466

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+
}
15380
}
81+
}
15482

83+
fn make_map(codes: &LinkedHashMap<String, Vec<String>>, file: &mut BufWriter<File>) {
15584
write!(
15685
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> = "
16389
).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();
16496
}

postgres-shared/src/error/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::convert::From;
55
use std::fmt;
66
use std::io;
77

8-
pub use self::sqlstate::SqlState;
8+
pub use self::sqlstate::*;
99

1010
mod sqlstate;
1111

0 commit comments

Comments
 (0)