rust-postgres/codegen/src/sqlstate.rs

100 lines
2.5 KiB
Rust
Raw Normal View History

2018-04-22 21:55:20 +00:00
use linked_hash_map::LinkedHashMap;
use phf_codegen;
use std::fs::File;
2018-04-22 21:55:20 +00:00
use std::io::{BufWriter, Write};
2015-03-26 02:11:40 +00:00
use std::path::Path;
2018-12-10 05:23:31 +00:00
const ERRCODES_TXT: &str = include_str!("errcodes.txt");
2016-01-03 07:19:20 +00:00
pub fn build(path: &Path) {
2016-12-21 16:14:24 +00:00
let mut file = BufWriter::new(File::create(path.join("error/sqlstate.rs")).unwrap());
2016-01-03 07:19:20 +00:00
let codes = parse_codes();
make_type(&mut file);
make_consts(&codes, &mut file);
2016-01-03 07:19:20 +00:00
make_map(&codes, &mut file);
}
fn parse_codes() -> LinkedHashMap<String, Vec<String>> {
let mut codes = LinkedHashMap::new();
2016-01-03 07:19:20 +00:00
for line in ERRCODES_TXT.lines() {
2018-12-10 05:23:31 +00:00
if line.starts_with('#') || line.starts_with("Section") || line.trim().is_empty() {
2016-01-03 07:19:20 +00:00
continue;
}
let mut it = line.split_whitespace();
let code = it.next().unwrap().to_owned();
it.next();
let name = it.next().unwrap().replace("ERRCODE_", "");
2016-01-03 07:19:20 +00:00
codes.entry(code).or_insert_with(Vec::new).push(name);
2016-01-03 07:19:20 +00:00
}
codes
}
fn make_type(file: &mut BufWriter<File>) {
2017-07-01 03:35:17 +00:00
write!(
file,
"// Autogenerated file - DO NOT EDIT
use std::borrow::Cow;
2016-02-21 21:45:31 +00:00
/// A SQLSTATE error code
#[derive(PartialEq, Eq, Clone, Debug)]
pub struct SqlState(Cow<'static, str>);
impl SqlState {{
/// Creates a `SqlState` from its error code.
2016-12-19 00:11:38 +00:00
pub fn from_code(s: &str) -> SqlState {{
match SQLSTATE_MAP.get(s) {{
Some(state) => state.clone(),
None => SqlState(Cow::Owned(s.to_string())),
}}
}}
/// Returns the error code corresponding to the `SqlState`.
pub fn code(&self) -> &str {{
&self.0
}}
"
2018-12-09 01:53:30 +00:00
)
.unwrap();
}
fn make_consts(codes: &LinkedHashMap<String, Vec<String>>, file: &mut BufWriter<File>) {
for (code, names) in codes {
for name in names {
write!(
file,
r#"
2018-04-22 21:55:20 +00:00
/// {code}
pub const {name}: SqlState = SqlState(Cow::Borrowed("{code}"));
"#,
name = name,
code = code,
2018-12-09 01:53:30 +00:00
)
.unwrap();
}
}
2018-04-22 21:55:20 +00:00
write!(file, "}}").unwrap();
}
fn make_map(codes: &LinkedHashMap<String, Vec<String>>, file: &mut BufWriter<File>) {
2017-07-01 03:35:17 +00:00
write!(
file,
"
#[cfg_attr(rustfmt, rustfmt_skip)]
static SQLSTATE_MAP: phf::Map<&'static str, SqlState> = "
2018-12-09 01:53:30 +00:00
)
.unwrap();
let mut builder = phf_codegen::Map::new();
for (code, names) in codes {
2018-04-22 21:55:20 +00:00
builder.entry(&**code, &format!("SqlState::{}", &names[0]));
}
builder.build(file).unwrap();
2018-12-10 05:23:31 +00:00
writeln!(file, ";").unwrap();
}