diff --git a/codegen/src/main.rs b/codegen/src/main.rs index 0ab7eab1..293686cb 100644 --- a/codegen/src/main.rs +++ b/codegen/src/main.rs @@ -9,7 +9,7 @@ mod sqlstate; mod type_gen; fn main() { - let path = Path::new("../src"); + let path = Path::new(".."); sqlstate::build(path); type_gen::build(path); } diff --git a/codegen/src/sqlstate.rs b/codegen/src/sqlstate.rs index 03bffaf9..94f37ae0 100644 --- a/codegen/src/sqlstate.rs +++ b/codegen/src/sqlstate.rs @@ -13,7 +13,7 @@ struct Code { } pub fn build(path: &Path) { - let mut file = BufWriter::new(File::create(path.join("error/sqlstate.rs")).unwrap()); + let mut file = BufWriter::new(File::create(path.join("postgres-shared/src/error/sqlstate.rs")).unwrap()); let codes = parse_codes(); diff --git a/codegen/src/type_gen.rs b/codegen/src/type_gen.rs index 49607538..034b4e3a 100644 --- a/codegen/src/type_gen.rs +++ b/codegen/src/type_gen.rs @@ -20,7 +20,7 @@ struct Type { } pub fn build(path: &Path) { - let mut file = BufWriter::new(File::create(path.join("types/type_gen.rs")).unwrap()); + let mut file = BufWriter::new(File::create(path.join("postgres/src/types/type_gen.rs")).unwrap()); let ranges = parse_ranges(); let types = parse_types(&ranges); diff --git a/postgres-shared/Cargo.toml b/postgres-shared/Cargo.toml index 80e16b7c..8c433c73 100644 --- a/postgres-shared/Cargo.toml +++ b/postgres-shared/Cargo.toml @@ -5,3 +5,6 @@ authors = ["Steven Fackler "] [dependencies] hex = "0.2" +fallible-iterator = "0.1.3" +phf = "=0.7.20" +postgres-protocol = "0.2" diff --git a/postgres/src/error/mod.rs b/postgres-shared/src/error/mod.rs similarity index 84% rename from postgres/src/error/mod.rs rename to postgres-shared/src/error/mod.rs index 94105221..f96ff5a9 100644 --- a/postgres/src/error/mod.rs +++ b/postgres-shared/src/error/mod.rs @@ -6,10 +6,8 @@ use std::error; use std::convert::From; use std::fmt; use std::io; -use std::result; pub use self::sqlstate::SqlState; -use {Result, DbErrorNew}; mod sqlstate; @@ -141,8 +139,9 @@ pub struct DbError { _p: (), } -impl DbErrorNew for DbError { - fn new_raw(fields: &mut ErrorFields) -> io::Result { +impl DbError { + #[doc(hidden)] + pub fn new_raw(fields: &mut ErrorFields) -> io::Result { let mut severity = None; let mut parsed_severity = None; let mut code = None; @@ -169,8 +168,18 @@ impl DbErrorNew for DbError { b'M' => message = Some(field.value().to_owned()), b'D' => detail = Some(field.value().to_owned()), b'H' => hint = Some(field.value().to_owned()), - b'P' => normal_position = Some(try!(field.value().parse::().map_err(|_| ::bad_response()))), - b'p' => internal_position = Some(try!(field.value().parse::().map_err(|_| ::bad_response()))), + b'P' => { + normal_position = Some(try!(field.value().parse::().map_err(|_| { + io::Error::new(io::ErrorKind::InvalidInput, + "`P` field did not contain an integer") + }))); + } + b'p' => { + internal_position = Some(try!(field.value().parse::().map_err(|_| { + io::Error::new(io::ErrorKind::InvalidInput, + "`p` field did not contain an integer") + }))); + } b'q' => internal_query = Some(field.value().to_owned()), b'W' => where_ = Some(field.value().to_owned()), b's' => schema = Some(field.value().to_owned()), @@ -179,18 +188,32 @@ impl DbErrorNew for DbError { b'd' => datatype = Some(field.value().to_owned()), b'n' => constraint = Some(field.value().to_owned()), b'F' => file = Some(field.value().to_owned()), - b'L' => line = Some(try!(field.value().parse::().map_err(|_| ::bad_response()))), + b'L' => { + line = Some(try!(field.value().parse::().map_err(|_| { + io::Error::new(io::ErrorKind::InvalidInput, + "`L` field did not contain an integer") + }))); + } b'R' => routine = Some(field.value().to_owned()), - b'V' => parsed_severity = Some(try!(Severity::from_str(field.value()).ok_or_else(::bad_response))), + b'V' => { + parsed_severity = Some(try!(Severity::from_str(field.value()).ok_or_else(|| { + io::Error::new(io::ErrorKind::InvalidInput, + "`V` field contained an invalid value") + }))); + } _ => {}, } } Ok(DbError { - severity: try!(severity.ok_or_else(|| ::bad_response())), + severity: try!(severity.ok_or_else(|| { + io::Error::new(io::ErrorKind::InvalidInput, "`S` field missing") + })), parsed_severity: parsed_severity, - code: try!(code.ok_or_else(|| ::bad_response())), - message: try!(message.ok_or_else(|| ::bad_response())), + code: try!(code.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, + "`C` field missing"))), + message: try!(message.ok_or_else(|| io::Error::new(io::ErrorKind::InvalidInput, + "`M` field missing"))), detail: detail, hint: hint, position: match normal_position { @@ -200,7 +223,10 @@ impl DbErrorNew for DbError { Some(position) => { Some(ErrorPosition::Internal { position: position, - query: try!(internal_query.ok_or_else(|| ::bad_response())), + query: try!(internal_query.ok_or_else(|| { + io::Error::new(io::ErrorKind::InvalidInput, + "`q` field missing but `p` field present") + })), }) } None => None, @@ -220,14 +246,16 @@ impl DbErrorNew for DbError { }) } - fn new_connect(fields: &mut ErrorFields) -> result::Result { + #[doc(hidden)] + pub fn new_connect(fields: &mut ErrorFields) -> Result { match DbError::new_raw(fields) { Ok(err) => Err(ConnectError::Db(Box::new(err))), Err(e) => Err(ConnectError::Io(e)), } } - fn new(fields: &mut ErrorFields) -> Result { + #[doc(hidden)] + pub fn new(fields: &mut ErrorFields) -> Result { match DbError::new_raw(fields) { Ok(err) => Err(Error::Db(Box::new(err))), Err(e) => Err(Error::Io(e)), diff --git a/postgres/src/error/sqlstate.rs b/postgres-shared/src/error/sqlstate.rs similarity index 100% rename from postgres/src/error/sqlstate.rs rename to postgres-shared/src/error/sqlstate.rs diff --git a/postgres-shared/src/lib.rs b/postgres-shared/src/lib.rs index 4027c423..1448ca15 100644 --- a/postgres-shared/src/lib.rs +++ b/postgres-shared/src/lib.rs @@ -1,3 +1,9 @@ -extern crate hex; +#![allow(unknown_lints)] // for clippy +extern crate hex; +extern crate fallible_iterator; +extern crate phf; +extern crate postgres_protocol; + +pub mod error; pub mod params; diff --git a/postgres/Cargo.toml b/postgres/Cargo.toml index e72069ae..1d89e01c 100644 --- a/postgres/Cargo.toml +++ b/postgres/Cargo.toml @@ -40,7 +40,6 @@ bufstream = "0.1" fallible-iterator = "0.1.3" hex = "0.2" log = "0.3" -phf = "=0.7.20" postgres-protocol = "0.2" bit-vec = { version = "0.4", optional = true } chrono = { version = "0.2.14", optional = true } @@ -54,5 +53,7 @@ serde_json = { version = ">= 0.6, < 0.9", optional = true } time = { version = "0.1.14", optional = true } uuid = { version = ">= 0.1, < 0.4", optional = true } +postgres-shared = { path = "../postgres-shared" } + [dev-dependencies] url = "1.0" diff --git a/postgres/src/lib.rs b/postgres/src/lib.rs index 0c58d082..86bfd186 100644 --- a/postgres/src/lib.rs +++ b/postgres/src/lib.rs @@ -76,8 +76,8 @@ extern crate hex; #[cfg(not(feature = "no-logging"))] #[macro_use] extern crate log; -extern crate phf; extern crate postgres_protocol; +extern crate postgres_shared; use fallible_iterator::{FallibleIterator, FromFallibleIterator}; use std::cell::{Cell, RefCell}; @@ -90,7 +90,7 @@ use std::result; use std::sync::Arc; use std::time::Duration; use postgres_protocol::authentication; -use postgres_protocol::message::backend::{self, ErrorFields}; +use postgres_protocol::message::backend; use postgres_protocol::message::frontend; use error::{Error, ConnectError, SqlState, DbError}; @@ -103,13 +103,15 @@ use stmt::{Statement, Column}; use transaction::{Transaction, IsolationLevel}; use types::{IsNull, Kind, Type, SessionInfo, Oid, Other, WrongType, ToSql, FromSql, Field}; +#[doc(inline)] +pub use postgres_shared::error; + #[macro_use] mod macros; mod feature_check; mod priv_io; mod url; -pub mod error; pub mod tls; pub mod notification; pub mod params; @@ -473,7 +475,7 @@ impl InnerConnection { .map_err(Into::into) .and_then(|oid| self.get_type(oid)) .collect()); - + let columns = match raw_columns { Some(body) => { try!(body.fields() @@ -1373,12 +1375,6 @@ trait OtherNew { fn new(name: String, oid: Oid, kind: Kind, schema: String) -> Other; } -trait DbErrorNew { - fn new_raw(fields: &mut ErrorFields) -> io::Result; - fn new_connect(fields: &mut ErrorFields) -> result::Result; - fn new(fields: &mut ErrorFields) -> Result; -} - trait RowsNew<'a> { fn new(stmt: &'a Statement<'a>, data: Vec) -> Rows<'a>; fn new_owned(stmt: Statement<'a>, data: Vec) -> Rows<'a>; diff --git a/postgres/src/stmt.rs b/postgres/src/stmt.rs index 4fbbc6c0..0fb55f9c 100644 --- a/postgres/src/stmt.rs +++ b/postgres/src/stmt.rs @@ -13,7 +13,7 @@ use types::{SessionInfo, Type, ToSql}; use rows::{Rows, LazyRows}; use transaction::Transaction; use {bad_response, Connection, StatementInternals, Result, RowsNew, InnerConnection, RowData, - SessionInfoNew, LazyRowsNew, DbErrorNew, ColumnNew, StatementInfo, TransactionInternals}; + SessionInfoNew, LazyRowsNew, ColumnNew, StatementInfo, TransactionInternals}; /// A prepared statement. pub struct Statement<'conn> {