diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index fb8832f9..00000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.rs eol=lf diff --git a/.travis/update_docs.sh b/.travis/update_docs.sh deleted file mode 100755 index 737f3842..00000000 --- a/.travis/update_docs.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -set -o errexit -o nounset - -git clone --branch gh-pages "https://$GH_TOKEN@github.com/${TRAVIS_REPO_SLUG}.git" deploy_docs -cd deploy_docs - -git config user.name "Steven Fackler" -git config user.email "sfackler@gmail.com" - -rm -rf doc/master -mv ../target/doc doc/master - -git add -A . -git commit -m "rebuild pages at ${TRAVIS_COMMIT}" -git push diff --git a/Cargo.toml b/Cargo.toml index 643ccadb..a6005ec5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] name = "postgres" -version = "0.10.1" +version = "0.10.2" authors = ["Steven Fackler "] license = "MIT" description = "A native PostgreSQL driver" repository = "https://github.com/sfackler/rust-postgres" -documentation = "https://sfackler.github.io/rust-postgres/doc/v0.10.1/postgres" +documentation = "https://sfackler.github.io/rust-postgres/doc/v0.10.2/postgres" readme = "README.md" keywords = ["database", "sql"] build = "build.rs" @@ -31,7 +31,7 @@ phf = "0.7" rustc-serialize = "0.3" net2 = { version = "0.2", features = ["nightly"] } chrono = { version = "0.2.14", optional = true } -openssl = { version = "0.6.4", optional = true } +openssl = { version = ">= 0.6.4, < 0.8", optional = true } serde = { version = "0.3", optional = true } # Delete for 0.11 serde_json = { version = "0.6", optional = true } time = { version = "0.1.14", optional = true } diff --git a/README.md b/README.md index 0f0044e8..4a8f35bf 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Rust-Postgres A native PostgreSQL driver for Rust. -[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.10.1/postgres) +[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.10.2/postgres) [![Build Status](https://travis-ci.org/sfackler/rust-postgres.png?branch=master)](https://travis-ci.org/sfackler/rust-postgres) [![Latest Version](https://img.shields.io/crates/v/postgres.svg)](https://crates.io/crates/postgres) @@ -198,16 +198,16 @@ types. The driver currently supports the following conversions: - serialize::json::Json + serialize::json::Json and - serde_json::Value + serde_json::Value (optional) JSON, JSONB - time::Timespec + time::Timespec and chrono::NaiveDateTime (optional) @@ -216,7 +216,7 @@ types. The driver currently supports the following conversions: - time::Timespec, + time::Timespec, chrono::DateTime<UTC>, chrono::DateTime<Local>, and @@ -241,7 +241,7 @@ types. The driver currently supports the following conversions: - uuid::Uuid + uuid::Uuid (optional) UUID @@ -284,8 +284,9 @@ implementations for `uuid`'s `Uuid` type. [JSON and JSONB](http://www.postgresql.org/docs/9.4/static/datatype-json.html) support is provided optionally by the `rustc-serialize` feature, which adds `ToSql` and `FromSql` implementations for `rustc-serialize`'s `Json` type, and -the `serde` feature, which adds implementations for `serde_json`'s `Value` -type. +the `serde_json` feature, which adds implementations for `serde_json`'s `Value` +type. The `serde` feature provides implementations for the older +`serde::json::Value` type. ### TIMESTAMP/TIMESTAMPTZ/DATE/TIME types diff --git a/src/error.rs b/src/error.rs index 9600df27..6fe7242e 100644 --- a/src/error.rs +++ b/src/error.rs @@ -48,10 +48,10 @@ impl DbErrorNew for DbError { None => match map.remove(&b'p') { Some(pos) => Some(ErrorPosition::Internal { position: try!(pos.parse().map_err(|_| ())), - query: try!(map.remove(&b'q').ok_or(())) + query: try!(map.remove(&b'q').ok_or(())), }), - None => None - } + None => None, + }, }, where_: map.remove(&b'W'), schema: map.remove(&b's'), @@ -194,7 +194,7 @@ impl error::Error for DbError { #[derive(Debug)] pub enum ConnectError { /// An error creating `ConnectParams`. - BadConnectParams(Box), + BadConnectParams(Box), /// The `ConnectParams` was missing a user. MissingUser, /// An error from the Postgres server itself. @@ -207,7 +207,7 @@ pub enum ConnectError { /// The Postgres server does not support SSL encryption. NoSslSupport, /// An error initializing the SSL session. - SslError(Box), + SslError(Box), /// An error communicating with the server. IoError(io::Error), } @@ -220,7 +220,7 @@ impl fmt::Display for ConnectError { ConnectError::DbError(ref err) => write!(fmt, ": {}", err), ConnectError::SslError(ref err) => write!(fmt, ": {}", err), ConnectError::IoError(ref err) => write!(fmt, ": {}", err), - _ => Ok(()) + _ => Ok(()), } } } @@ -231,7 +231,8 @@ impl error::Error for ConnectError { ConnectError::BadConnectParams(_) => "Error creating `ConnectParams`", ConnectError::MissingUser => "User missing in `ConnectParams`", ConnectError::DbError(_) => "Error reported by Postgres", - ConnectError::MissingPassword => "The server requested a password but none was provided", + ConnectError::MissingPassword => + "The server requested a password but none was provided", ConnectError::UnsupportedAuthentication => { "The server requested an unsupported authentication method" } @@ -247,7 +248,7 @@ impl error::Error for ConnectError { ConnectError::DbError(ref err) => Some(&**err), ConnectError::SslError(ref err) => Some(&**err), ConnectError::IoError(ref err) => Some(err), - _ => None + _ => None, } } } @@ -280,8 +281,8 @@ pub enum ErrorPosition { /// The byte position. position: u32, /// A query generated by the Postgres server. - query: String - } + query: String, + }, } /// An error encountered when communicating with the Postgres server. @@ -297,7 +298,7 @@ pub enum Error { /// An attempt was made to read from a column that does not exist. InvalidColumn, /// An error converting between Postgres and Rust types. - Conversion(Box), + Conversion(Box), } impl fmt::Display for Error { @@ -329,7 +330,7 @@ impl error::Error for Error { Error::DbError(ref err) => Some(&**err), Error::IoError(ref err) => Some(err), Error::Conversion(ref err) => Some(&**err), - _ => None + _ => None, } } } diff --git a/src/io/mod.rs b/src/io/mod.rs index f3fad41b..d459ae00 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -26,6 +26,8 @@ pub trait NegotiateSsl { /// /// The host portion of the connection parameters is provided for hostname /// verification. - fn negotiate_ssl(&self, host: &str, stream: Stream) - -> Result, Box>; + fn negotiate_ssl(&self, + host: &str, + stream: Stream) + -> Result, Box>; } diff --git a/src/io/openssl.rs b/src/io/openssl.rs index 0ddd4691..72d84a12 100644 --- a/src/io/openssl.rs +++ b/src/io/openssl.rs @@ -16,8 +16,10 @@ impl StreamWrapper for SslStream { } impl NegotiateSsl for SslContext { - fn negotiate_ssl(&self, _: &str, stream: Stream) - -> Result, Box> { + fn negotiate_ssl(&self, + _: &str, + stream: Stream) + -> Result, Box> { let stream = try!(SslStream::connect(self, stream)); Ok(Box::new(stream)) } diff --git a/src/lib.rs b/src/lib.rs index 937b07c8..cd0a4972 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,7 +41,7 @@ //! } //! } //! ``` -#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.10.1")] +#![doc(html_root_url="https://sfackler.github.io/rust-postgres/doc/v0.10.2")] #![warn(missing_docs)] extern crate bufstream; @@ -114,7 +114,7 @@ pub enum ConnectTarget { /// /// Only available on Unix platforms with the `unix_socket` feature. #[cfg(feature = "unix_socket")] - Unix(PathBuf) + Unix(PathBuf), } /// Authentication information. @@ -148,17 +148,17 @@ pub struct ConnectParams { /// A trait implemented by types that can be converted into a `ConnectParams`. pub trait IntoConnectParams { /// Converts the value of `self` into a `ConnectParams`. - fn into_connect_params(self) -> result::Result>; + fn into_connect_params(self) -> result::Result>; } impl IntoConnectParams for ConnectParams { - fn into_connect_params(self) -> result::Result> { + fn into_connect_params(self) -> result::Result> { Ok(self) } } impl<'a> IntoConnectParams for &'a str { - fn into_connect_params(self) -> result::Result> { + fn into_connect_params(self) -> result::Result> { match Url::parse(self) { Ok(url) => url.into_connect_params(), Err(err) => return Err(err.into()), @@ -167,7 +167,7 @@ impl<'a> IntoConnectParams for &'a str { } impl IntoConnectParams for Url { - fn into_connect_params(self) -> result::Result> { + fn into_connect_params(self) -> result::Result> { let Url { host, port, @@ -178,11 +178,11 @@ impl IntoConnectParams for Url { #[cfg(feature = "unix_socket")] fn make_unix(maybe_path: String) - -> result::Result> { + -> result::Result> { Ok(ConnectTarget::Unix(PathBuf::from(maybe_path))) } #[cfg(not(feature = "unix_socket"))] - fn make_unix(_: String) -> result::Result> { + fn make_unix(_: String) -> result::Result> { Err("unix socket support requires the `unix_socket` feature".into()) } @@ -194,7 +194,10 @@ impl IntoConnectParams for Url { }; let user = user.map(|url::UserInfo { user, pass }| { - UserInfo { user: user, password: pass } + UserInfo { + user: user, + password: pass, + } }); let database = if path.is_empty() { @@ -254,7 +257,7 @@ pub struct CancelData { /// Only the host and port of the connection info are used. See /// `Connection::connect` for details of the `params` argument. /// -/// ## Example +/// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; @@ -265,19 +268,21 @@ pub struct CancelData { /// thread::spawn(move || { /// conn.execute("SOME EXPENSIVE QUERY", &[]).unwrap(); /// }); -/// # let _ = -/// postgres::cancel_query(url, &SslMode::None, cancel_data); +/// postgres::cancel_query(url, &SslMode::None, cancel_data).unwrap(); /// ``` -pub fn cancel_query(params: T, ssl: &SslMode, data: CancelData) - -> result::Result<(), ConnectError> - where T: IntoConnectParams { +pub fn cancel_query(params: T, + ssl: &SslMode, + data: CancelData) + -> result::Result<(), ConnectError> + where T: IntoConnectParams +{ let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams)); let mut socket = try!(priv_io::initialize_stream(¶ms, ssl)); try!(socket.write_message(&CancelRequest { code: message::CANCEL_CODE, process_id: data.process_id, - secret_key: data.secret_key + secret_key: data.secret_key, })); try!(socket.flush()); @@ -291,7 +296,8 @@ fn bad_response() -> std_io::Error { fn desynchronized() -> std_io::Error { std_io::Error::new(std_io::ErrorKind::Other, - "communication with the server has desynchronized due to an earlier IO error") + "communication with the server has desynchronized due to an earlier IO \ + error") } /// An enumeration of transaction isolation levels. @@ -353,9 +359,9 @@ pub enum SslMode { /// The connection will not use SSL. None, /// The connection will use SSL if the backend supports it. - Prefer(Box), + Prefer(Box), /// The connection must use SSL. - Require(Box), + Require(Box), } impl fmt::Debug for SslMode { @@ -399,7 +405,8 @@ impl Drop for InnerConnection { impl InnerConnection { fn connect(params: T, ssl: &SslMode) -> result::Result - where T: IntoConnectParams { + where T: IntoConnectParams + { let params = try!(params.into_connect_params().map_err(ConnectError::BadConnectParams)); let stream = try!(priv_io::initialize_stream(¶ms, ssl)); @@ -412,7 +419,10 @@ impl InnerConnection { next_stmt_id: 0, notice_handler: Box::new(LoggingNoticeHandler), notifications: VecDeque::new(), - cancel_data: CancelData { process_id: 0, secret_key: 0 }, + cancel_data: CancelData { + process_id: 0, + secret_key: 0, + }, unknown_types: HashMap::new(), cached_statements: HashMap::new(), parameters: HashMap::new(), @@ -432,9 +442,9 @@ impl InnerConnection { } try!(conn.write_messages(&[StartupMessage { - version: message::PROTOCOL_VERSION, - parameters: &options - }])); + version: message::PROTOCOL_VERSION, + parameters: &options, + }])); try!(conn.handle_auth(user)); @@ -455,21 +465,22 @@ impl InnerConnection { Ok(conn) } + #[cfg_attr(rustfmt, rustfmt_skip)] fn setup_typeinfo_query(&mut self) -> result::Result<(), ConnectError> { match self.raw_prepare(TYPEINFO_QUERY, "SELECT t.typname, t.typelem, r.rngsubtype, n.nspname \ FROM pg_catalog.pg_type t \ - LEFT OUTER JOIN pg_catalog.pg_range r \ - ON r.rngtypid = t.oid \ - INNER JOIN pg_catalog.pg_namespace n \ - ON t.typnamespace = n.oid \ + LEFT OUTER JOIN pg_catalog.pg_range r ON \ + r.rngtypid = t.oid \ + INNER JOIN pg_catalog.pg_namespace n ON \ + t.typnamespace = n.oid \ WHERE t.oid = $1") { Ok(..) => return Ok(()), Err(Error::IoError(e)) => return Err(ConnectError::IoError(e)), // Range types weren't added until Postgres 9.2, so pg_range may not exist Err(Error::DbError(ref e)) if e.code() == &SqlState::UndefinedTable => {} Err(Error::DbError(e)) => return Err(ConnectError::DbError(e)), - _ => unreachable!() + _ => unreachable!(), } match self.raw_prepare(TYPEINFO_QUERY, @@ -481,7 +492,7 @@ impl InnerConnection { Ok(..) => Ok(()), Err(Error::IoError(e)) => Err(ConnectError::IoError(e)), Err(Error::DbError(e)) => Err(ConnectError::DbError(e)), - _ => unreachable!() + _ => unreachable!(), } } @@ -505,12 +516,13 @@ impl InnerConnection { ParameterStatus { parameter, value } => { self.parameters.insert(parameter, value); } - val => return Ok(val) + val => return Ok(val), } } } - fn read_message_with_notification_timeout(&mut self, timeout: Duration) + fn read_message_with_notification_timeout(&mut self, + timeout: Duration) -> std::io::Result> { debug_assert!(!self.desynchronized); loop { @@ -523,7 +535,7 @@ impl InnerConnection { Some(ParameterStatus { parameter, value }) => { self.parameters.insert(parameter, value); } - val => return Ok(val) + val => return Ok(val), } } } @@ -535,10 +547,10 @@ impl InnerConnection { self.notifications.push_back(Notification { pid: pid, channel: channel, - payload: payload + payload: payload, }) } - val => return Ok(val) + val => return Ok(val), } } } @@ -548,9 +560,7 @@ impl InnerConnection { AuthenticationOk => return Ok(()), AuthenticationCleartextPassword => { let pass = try!(user.password.ok_or(ConnectError::MissingPassword)); - try!(self.write_messages(&[PasswordMessage { - password: &pass, - }])); + try!(self.write_messages(&[PasswordMessage { password: &pass }])); } AuthenticationMD5Password { salt } => { let pass = try!(user.password.ok_or(ConnectError::MissingPassword)); @@ -562,22 +572,20 @@ impl InnerConnection { let _ = hasher.input(output.as_bytes()); let _ = hasher.input(&salt); let output = format!("md5{}", hasher.result_str()); - try!(self.write_messages(&[PasswordMessage { - password: &output - }])); + try!(self.write_messages(&[PasswordMessage { password: &output }])); } - AuthenticationKerberosV5 - | AuthenticationSCMCredential - | AuthenticationGSS - | AuthenticationSSPI => return Err(ConnectError::UnsupportedAuthentication), + AuthenticationKerberosV5 | + AuthenticationSCMCredential | + AuthenticationGSS | + AuthenticationSSPI => return Err(ConnectError::UnsupportedAuthentication), ErrorResponse { fields } => return DbError::new_connect(fields), - _ => return Err(ConnectError::IoError(bad_response())) + _ => return Err(ConnectError::IoError(bad_response())), } match try!(self.read_message()) { AuthenticationOk => Ok(()), ErrorResponse { fields } => return DbError::new_connect(fields), - _ => return Err(ConnectError::IoError(bad_response())) + _ => return Err(ConnectError::IoError(bad_response())), } } @@ -588,17 +596,16 @@ impl InnerConnection { fn raw_prepare(&mut self, stmt_name: &str, query: &str) -> Result<(Vec, Vec)> { debug!("preparing query with name `{}`: {}", stmt_name, query); - try!(self.write_messages(&[ - Parse { - name: stmt_name, - query: query, - param_types: &[] - }, - Describe { - variant: b'S', - name: stmt_name, - }, - Sync])); + try!(self.write_messages(&[Parse { + name: stmt_name, + query: query, + param_types: &[], + }, + Describe { + variant: b'S', + name: stmt_name, + }, + Sync])); match try!(self.read_message()) { ParseComplete => {} @@ -617,7 +624,7 @@ impl InnerConnection { let raw_columns = match try!(self.read_message()) { RowDescription { descriptions } => descriptions, NoData => vec![], - _ => bad_response!(self) + _ => bad_response!(self), }; try!(self.wait_for_ready()); @@ -669,16 +676,15 @@ impl InnerConnection { } fn close_statement(&mut self, name: &str, type_: u8) -> Result<()> { - try!(self.write_messages(&[ - Close { - variant: type_, - name: name, - }, - Sync])); + try!(self.write_messages(&[Close { + variant: type_, + name: name, + }, + Sync])); let resp = match try!(self.read_message()) { CloseComplete => Ok(()), ErrorResponse { fields } => DbError::new(fields), - _ => bad_response!(self) + _ => bad_response!(self), }; try!(self.wait_for_ready()); resp @@ -699,57 +705,56 @@ impl InnerConnection { IsNull::Yes => None, IsNull::No => Some(buf), }; - try!(self.write_messages(&[ - Bind { - portal: "", - statement: TYPEINFO_QUERY, - formats: &[1], - values: &[value], - result_formats: &[1] - }, - Execute { - portal: "", - max_rows: 0, - }, - Sync])); + try!(self.write_messages(&[Bind { + portal: "", + statement: TYPEINFO_QUERY, + formats: &[1], + values: &[value], + result_formats: &[1], + }, + Execute { + portal: "", + max_rows: 0, + }, + Sync])); match try!(self.read_message()) { BindComplete => {} ErrorResponse { fields } => { try!(self.wait_for_ready()); return DbError::new(fields); } - _ => bad_response!(self) + _ => bad_response!(self), } let (name, elem_oid, rngsubtype, schema): (String, Oid, Option, String) = - match try!(self.read_message()) { - DataRow { row } => { - let ctx = SessionInfo::new(self); - (try!(FromSql::from_sql_nullable(&Type::Name, - row[0].as_ref().map(|r| &**r).as_mut(), - &ctx)), - try!(FromSql::from_sql_nullable(&Type::Oid, - row[1].as_ref().map(|r| &**r).as_mut(), - &ctx)), - try!(FromSql::from_sql_nullable(&Type::Oid, - row[2].as_ref().map(|r| &**r).as_mut(), - &ctx)), - try!(FromSql::from_sql_nullable(&Type::Name, - row[3].as_ref().map(|r| &**r).as_mut(), - &ctx))) - } - ErrorResponse { fields } => { - try!(self.wait_for_ready()); - return DbError::new(fields); - } - _ => bad_response!(self) - }; + match try!(self.read_message()) { + DataRow { row } => { + let ctx = SessionInfo::new(self); + (try!(FromSql::from_sql_nullable(&Type::Name, + row[0].as_ref().map(|r| &**r).as_mut(), + &ctx)), + try!(FromSql::from_sql_nullable(&Type::Oid, + row[1].as_ref().map(|r| &**r).as_mut(), + &ctx)), + try!(FromSql::from_sql_nullable(&Type::Oid, + row[2].as_ref().map(|r| &**r).as_mut(), + &ctx)), + try!(FromSql::from_sql_nullable(&Type::Name, + row[3].as_ref().map(|r| &**r).as_mut(), + &ctx))) + } + ErrorResponse { fields } => { + try!(self.wait_for_ready()); + return DbError::new(fields); + } + _ => bad_response!(self), + }; match try!(self.read_message()) { CommandComplete { .. } => {} ErrorResponse { fields } => { try!(self.wait_for_ready()); return DbError::new(fields); } - _ => bad_response!(self) + _ => bad_response!(self), } try!(self.wait_for_ready()); @@ -758,7 +763,7 @@ impl InnerConnection { } else { match rngsubtype { Some(oid) => Kind::Range(try!(self.get_type(oid))), - None => Kind::Simple + None => Kind::Simple, } }; @@ -774,7 +779,7 @@ impl InnerConnection { fn wait_for_ready(&mut self) -> Result<()> { match try!(self.read_message()) { ReadyForQuery { .. } => Ok(()), - _ => bad_response!(self) + _ => bad_response!(self), } } @@ -788,16 +793,19 @@ impl InnerConnection { match try!(self.read_message()) { ReadyForQuery { .. } => break, DataRow { row } => { - result.push(row.into_iter().map(|opt| { - opt.map(|b| String::from_utf8_lossy(&b).into_owned()) - }).collect()); + result.push(row.into_iter() + .map(|opt| { + opt.map(|b| String::from_utf8_lossy(&b).into_owned()) + }) + .collect()); } - CopyInResponse { .. } => { - try!(self.write_messages(&[ - CopyFail { - message: "COPY queries cannot be directly executed", - }, - Sync])); + CopyInResponse { .. } | + CopyOutResponse { .. } => { + try!(self.write_messages(&[CopyFail { + message: "COPY queries cannot be directly \ + executed", + }, + Sync])); } ErrorResponse { fields } => { try!(self.wait_for_ready()); @@ -817,25 +825,26 @@ impl InnerConnection { } fn _ensure_send() { - fn _is_send() {} + fn _is_send() { + } _is_send::(); } /// A connection to a Postgres database. pub struct Connection { - conn: RefCell + conn: RefCell, } impl fmt::Debug for Connection { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { let conn = self.conn.borrow(); fmt.debug_struct("Connection") - .field("cancel_data", &conn.cancel_data) - .field("notifications", &conn.notifications.len()) - .field("transaction_depth", &conn.trans_depth) - .field("desynchronized", &conn.desynchronized) - .field("cached_statements", &conn.cached_statements.len()) - .finish() + .field("cancel_data", &conn.cancel_data) + .field("notifications", &conn.notifications.len()) + .field("transaction_depth", &conn.trans_depth) + .field("desynchronized", &conn.desynchronized) + .field("cached_statements", &conn.cached_statements.len()) + .finish() } } @@ -860,28 +869,27 @@ impl Connection { /// struct should be created manually and passed in. Note that Postgres /// does not support SSL over Unix sockets. /// - /// ## Examples + /// # Examples /// /// ```rust,no_run - /// # use postgres::{Connection, SslMode}; - /// # fn f() -> Result<(), ::postgres::error::ConnectError> { + /// use postgres::{Connection, SslMode}; + /// /// let url = "postgresql://postgres:hunter2@localhost:2994/foodb"; - /// let conn = try!(Connection::connect(url, &SslMode::None)); - /// # Ok(()) }; + /// let conn = Connection::connect(url, &SslMode::None).unwrap(); /// ``` /// /// ```rust,no_run - /// # use postgres::{Connection, SslMode}; - /// # fn f() -> Result<(), ::postgres::error::ConnectError> { + /// use postgres::{Connection, SslMode}; + /// /// let url = "postgresql://postgres@%2Frun%2Fpostgres"; - /// let conn = try!(Connection::connect(url, &SslMode::None)); - /// # Ok(()) }; + /// let conn = Connection::connect(url, &SslMode::None).unwrap(); /// ``` /// /// ```rust,no_run - /// # use postgres::{Connection, UserInfo, ConnectParams, SslMode, ConnectTarget}; + /// use postgres::{Connection, UserInfo, ConnectParams, SslMode, ConnectTarget}; + /// /// # #[cfg(feature = "unix_socket")] - /// # fn f() -> Result<(), ::postgres::error::ConnectError> { + /// # fn f() { /// # let some_crazy_path = Path::new(""); /// let params = ConnectParams { /// target: ConnectTarget::Unix(some_crazy_path), @@ -893,14 +901,13 @@ impl Connection { /// database: None, /// options: vec![], /// }; - /// let conn = try!(Connection::connect(params, &SslMode::None)); - /// # Ok(()) }; + /// let conn = Connection::connect(params, &SslMode::None).unwrap(); + /// # } /// ``` pub fn connect(params: T, ssl: &SslMode) -> result::Result - where T: IntoConnectParams { - InnerConnection::connect(params, ssl).map(|conn| { - Connection { conn: RefCell::new(conn) } - }) + where T: IntoConnectParams + { + InnerConnection::connect(params, ssl).map(|conn| Connection { conn: RefCell::new(conn) }) } /// Sets the notice handler for the connection, returning the old handler. @@ -924,16 +931,18 @@ impl Connection { /// The statement is associated with the connection that created it and may /// not outlive that connection. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; + /// # let x = 10i32; /// # let conn = Connection::connect("", &SslMode::None).unwrap(); - /// let maybe_stmt = conn.prepare("SELECT foo FROM bar WHERE baz = $1"); - /// let stmt = match maybe_stmt { - /// Ok(stmt) => stmt, - /// Err(err) => panic!("Error preparing statement: {:?}", err) - /// }; + /// let stmt = conn.prepare("SELECT foo FROM bar WHERE baz = $1").unwrap(); + /// for row in stmt.query(&[&x]).unwrap() { + /// let foo: String = row.get(0); + /// println!("foo: {}", foo); + /// } + /// ``` pub fn prepare<'a>(&'a self, query: &str) -> Result> { self.conn.borrow_mut().prepare(query, self) } @@ -945,18 +954,17 @@ impl Connection { /// is going to be used frequently, caching it can improve performance by /// reducing the number of round trips to the Postgres backend. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; - /// # fn f() -> postgres::Result<()> { /// # let x = 10i32; /// # let conn = Connection::connect("", &SslMode::None).unwrap(); - /// let stmt = try!(conn.prepare_cached("SELECT foo FROM bar WHERE baz = $1")); - /// for row in try!(stmt.query(&[&x])) { - /// println!("foo: {}", row.get::<_, String>(0)); + /// let stmt = conn.prepare_cached("SELECT foo FROM bar WHERE baz = $1").unwrap(); + /// for row in stmt.query(&[&x]).unwrap() { + /// let foo: String = row.get(0); + /// println!("foo: {}", foo); /// } - /// # Ok(()) }; /// ``` pub fn prepare_cached<'a>(&'a self, query: &str) -> Result> { self.conn.borrow_mut().prepare_cached(query, self) @@ -968,32 +976,30 @@ impl Connection { /// the connection for the duration of the transaction. The transaction /// is active until the `Transaction` object falls out of scope. /// - /// ## Note + /// # Note /// A transaction will roll back by default. The `set_commit`, /// `set_rollback`, and `commit` methods alter this behavior. /// - /// ## Panics + /// # Panics /// /// Panics if a transaction is already active. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; - /// # fn foo() -> Result<(), postgres::error::Error> { /// # let conn = Connection::connect("", &SslMode::None).unwrap(); - /// let trans = try!(conn.transaction()); - /// try!(trans.execute("UPDATE foo SET bar = 10", &[])); + /// let trans = conn.transaction().unwrap(); + /// trans.execute("UPDATE foo SET bar = 10", &[]).unwrap(); /// // ... /// - /// try!(trans.commit()); - /// # Ok(()) - /// # } + /// trans.commit().unwrap(); /// ``` pub fn transaction<'a>(&'a self) -> Result> { let mut conn = self.conn.borrow_mut(); check_desync!(conn); - assert!(conn.trans_depth == 0, "`transaction` must be called on the active transaction"); + assert!(conn.trans_depth == 0, + "`transaction` must be called on the active transaction"); try!(conn.quick_query("BEGIN")); conn.trans_depth += 1; Ok(Transaction { @@ -1006,7 +1012,9 @@ impl Connection { /// Sets the isolation level which will be used for future transactions. /// - /// ## Note + /// This is a simple wrapper around `SET TRANSACTION ISOLATION LEVEL ...`. + /// + /// # Note /// /// This will not change the behavior of an active transaction. pub fn set_transaction_isolation(&self, level: IsolationLevel) -> Result<()> { @@ -1014,6 +1022,8 @@ impl Connection { } /// Returns the isolation level which will be used for future transactions. + /// + /// This is a simple wrapper around `SHOW TRANSACTION ISOLATION LEVEL`. pub fn transaction_isolation(&self) -> Result { let mut conn = self.conn.borrow_mut(); check_desync!(conn); @@ -1028,13 +1038,18 @@ impl Connection { /// /// On success, returns the number of rows modified or 0 if not applicable. /// - /// ## Panics + /// # Panics /// /// Panics if the number of parameters provided does not match the number /// expected. pub fn execute(&self, query: &str, params: &[&ToSql]) -> Result { let (param_types, columns) = try!(self.conn.borrow_mut().raw_prepare("", query)); - let stmt = Statement::new(self, "".to_owned(), param_types, columns, Cell::new(0), true); + let stmt = Statement::new(self, + "".to_owned(), + param_types, + columns, + Cell::new(0), + true); stmt.execute(params) } @@ -1045,33 +1060,32 @@ impl Connection { /// execution of batches of non-dynamic statements - for example, creation /// of a schema for a fresh database. /// - /// ## Warning + /// # Warning /// /// Prepared statements should be used for any SQL statement which contains /// user-specified data, as it provides functionality to safely embed that /// data in the statement. Do not form statements via string concatenation /// and feed them into this method. /// - /// ## Example + /// # Example /// /// ```rust,no_run - /// # use postgres::{Connection, Result}; - /// fn init_db(conn: &Connection) -> Result<()> { - /// conn.batch_execute(" - /// CREATE TABLE person ( - /// id SERIAL PRIMARY KEY, - /// name NOT NULL - /// ); + /// # use postgres::{Connection, SslMode, Result}; + /// # let conn = Connection::connect("", &SslMode::None).unwrap(); + /// conn.batch_execute(" + /// CREATE TABLE person ( + /// id SERIAL PRIMARY KEY, + /// name NOT NULL + /// ); /// - /// CREATE TABLE purchase ( - /// id SERIAL PRIMARY KEY, - /// person INT NOT NULL REFERENCES person (id), - /// time TIMESTAMPTZ NOT NULL, - /// ); + /// CREATE TABLE purchase ( + /// id SERIAL PRIMARY KEY, + /// person INT NOT NULL REFERENCES person (id), + /// time TIMESTAMPTZ NOT NULL, + /// ); /// - /// CREATE INDEX ON purchase (time); - /// ") - /// } + /// CREATE INDEX ON purchase (time); + /// ").unwrap(); /// ``` pub fn batch_execute(&self, query: &str) -> Result<()> { self.conn.borrow_mut().quick_query(query).map(|_| ()) @@ -1133,9 +1147,9 @@ pub struct Transaction<'conn> { impl<'a> fmt::Debug for Transaction<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("Transaction") - .field("commit", &self.commit.get()) - .field("depth", &self.depth) - .finish() + .field("commit", &self.commit.get()) + .field("depth", &self.depth) + .finish() } } @@ -1186,7 +1200,7 @@ impl<'conn> Transaction<'conn> { /// Like `Connection::transaction`. /// - /// ## Panics + /// # Panics /// /// Panics if there is an active nested transaction. pub fn transaction<'a>(&'a self) -> Result> { @@ -1263,11 +1277,10 @@ fn read_rows(conn: &mut InnerConnection, buf: &mut VecDeque>> return DbError::new(fields); } CopyInResponse { .. } => { - try!(conn.write_messages(&[ - CopyFail { - message: "COPY queries cannot be directly executed", - }, - Sync])); + try!(conn.write_messages(&[CopyFail { + message: "COPY queries cannot be directly executed", + }, + Sync])); } CopyOutResponse { .. } => { loop { @@ -1276,9 +1289,9 @@ fn read_rows(conn: &mut InnerConnection, buf: &mut VecDeque>> _ => {} } } - return Err(Error::IoError(std_io::Error::new( - std_io::ErrorKind::InvalidInput, - "COPY queries cannot be directly executed"))); + return Err(Error::IoError(std_io::Error::new(std_io::ErrorKind::InvalidInput, + "COPY queries cannot be directly \ + executed"))); } _ => { conn.desynchronized = true; @@ -1384,7 +1397,8 @@ trait LazyRowsNew<'trans, 'stmt> { row_limit: i32, more_rows: bool, finished: bool, - trans: &'trans Transaction<'trans>) -> LazyRows<'trans, 'stmt>; + trans: &'trans Transaction<'trans>) + -> LazyRows<'trans, 'stmt>; } trait SessionInfoNew<'a> { @@ -1397,7 +1411,8 @@ trait StatementInternals<'conn> { param_types: Vec, columns: Vec, next_portal_id: Cell, - finished: bool) -> Statement<'conn>; + finished: bool) + -> Statement<'conn>; fn conn(&self) -> &'conn Connection; } diff --git a/src/md5.rs b/src/md5.rs index 894d1bf4..1656609c 100644 --- a/src/md5.rs +++ b/src/md5.rs @@ -18,7 +18,7 @@ use std::iter::repeat; struct StepUp { next: T, end: T, - ammount: T + ammount: T, } impl Iterator for StepUp where @@ -47,7 +47,7 @@ impl RangeExt for Range where StepUp { next: self.start, end: self.end, - ammount: ammount + ammount: ammount, } } } @@ -72,7 +72,7 @@ fn zero(dst: &mut [u8]) { } /// Read a vector of bytes into a vector of u32s. The values are read in little-endian format. -fn read_u32v_le(dst: &mut[u32], input: &[u8]) { +fn read_u32v_le(dst: &mut [u32], input: &[u8]) { assert!(dst.len() * 4 == input.len()); unsafe { let mut x: *mut u32 = dst.get_unchecked_mut(0); @@ -89,7 +89,7 @@ fn read_u32v_le(dst: &mut[u32], input: &[u8]) { /// Write a u32 into a vector, which must be 4 bytes long. The value is written in little-endian /// format. -fn write_u32_le(dst: &mut[u8], mut input: u32) { +fn write_u32_le(dst: &mut [u8], mut input: u32) { assert!(dst.len() == 4); input = input.to_le(); unsafe { @@ -147,7 +147,7 @@ trait FixedBuffer { /// Get the current buffer. The buffer must already be full. This clears the buffer as well. fn full_buffer<'s>(&'s mut self) -> &'s [u8]; - /// Get the current buffer. + /// Get the current buffer. fn current_buffer<'s>(&'s mut self) -> &'s [u8]; /// Get the current position of the buffer. @@ -247,14 +247,18 @@ struct FixedBuffer64 { buffer_idx: usize, } -impl Clone for FixedBuffer64 { fn clone(&self) -> FixedBuffer64 { *self } } +impl Clone for FixedBuffer64 { + fn clone(&self) -> FixedBuffer64 { + *self + } +} impl FixedBuffer64 { /// Create a new buffer fn new() -> FixedBuffer64 { FixedBuffer64 { buffer: [0u8; 64], - buffer_idx: 0 + buffer_idx: 0, } } } @@ -266,7 +270,7 @@ struct Md5State { s0: u32, s1: u32, s2: u32, - s3: u32 + s3: u32, } impl Md5State { @@ -275,7 +279,7 @@ impl Md5State { s0: 0x67452301, s1: 0xefcdab89, s2: 0x98badcfe, - s3: 0x10325476 + s3: 0x10325476, } } @@ -341,8 +345,18 @@ impl Md5State { for i in (0..16).step_up(4) { a = op_g(a, b, c, d, data[t & 0x0f].wrapping_add(C2[i]), 5); d = op_g(d, a, b, c, data[(t + 5) & 0x0f].wrapping_add(C2[i + 1]), 9); - c = op_g(c, d, a, b, data[(t + 10) & 0x0f].wrapping_add(C2[i + 2]), 14); - b = op_g(b, c, d, a, data[(t + 15) & 0x0f].wrapping_add(C2[i + 3]), 20); + c = op_g(c, + d, + a, + b, + data[(t + 10) & 0x0f].wrapping_add(C2[i + 2]), + 14); + b = op_g(b, + c, + d, + a, + data[(t + 15) & 0x0f].wrapping_add(C2[i + 3]), + 20); t += 20; } @@ -361,8 +375,18 @@ impl Md5State { for i in (0..16).step_up(4) { a = op_i(a, b, c, d, data[t & 0x0f].wrapping_add(C4[i]), 6); d = op_i(d, a, b, c, data[(t + 7) & 0x0f].wrapping_add(C4[i + 1]), 10); - c = op_i(c, d, a, b, data[(t + 14) & 0x0f].wrapping_add(C4[i + 2]), 15); - b = op_i(b, c, d, a, data[(t + 21) & 0x0f].wrapping_add(C4[i + 3]), 21); + c = op_i(c, + d, + a, + b, + data[(t + 14) & 0x0f].wrapping_add(C4[i + 2]), + 15); + b = op_i(b, + c, + d, + a, + data[(t + 21) & 0x0f].wrapping_add(C4[i + 3]), + 21); t += 28; } @@ -374,28 +398,24 @@ impl Md5State { } // Round 1 constants -static C1: [u32; 16] = [ - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 -]; +static C1: [u32; 16] = [0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, + 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821]; // Round 2 constants -static C2: [u32; 16] = [ - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a -]; +static C2: [u32; 16] = [0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, + 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a]; // Round 3 constants -static C3: [u32; 16] = [ - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 -]; +static C3: [u32; 16] = [0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, + 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665]; // Round 4 constants -static C4: [u32; 16] = [ - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 -]; +static C4: [u32; 16] = [0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, + 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391]; /// The MD5 Digest algorithm pub struct Md5 { @@ -412,7 +432,7 @@ impl Md5 { length_bytes: 0, buffer: FixedBuffer64::new(), state: Md5State::new(), - finished: false + finished: false, } } @@ -422,8 +442,9 @@ impl Md5 { // 2^64 - ie: integer overflow is OK. self.length_bytes += input.len() as u64; let self_state = &mut self.state; - self.buffer.input(input, |d: &[u8]| { self_state.process_block(d);} - ); + self.buffer.input(input, |d: &[u8]| { + self_state.process_block(d); + }); } pub fn reset(&mut self) { @@ -436,7 +457,9 @@ impl Md5 { pub fn result(&mut self, out: &mut [u8]) { if !self.finished { let self_state = &mut self.state; - self.buffer.standard_padding(8, |d: &[u8]| { self_state.process_block(d); }); + self.buffer.standard_padding(8, |d: &[u8]| { + self_state.process_block(d); + }); write_u32_le(self.buffer.next(4), (self.length_bytes << 3) as u32); write_u32_le(self.buffer.next(4), (self.length_bytes >> 29) as u32); self_state.process_block(self.buffer.full_buffer()); @@ -449,12 +472,14 @@ impl Md5 { write_u32_le(&mut out[12..16], self.state.s3); } - fn output_bits(&self) -> usize { 128 } + fn output_bits(&self) -> usize { + 128 + } pub fn result_str(&mut self) -> String { use serialize::hex::ToHex; - let mut buf: Vec = repeat(0).take((self.output_bits()+7)/8).collect(); + let mut buf: Vec = repeat(0).take((self.output_bits() + 7) / 8).collect(); self.result(&mut buf); buf[..].to_hex() } diff --git a/src/message.rs b/src/message.rs index f0072e5d..b46a1b10 100644 --- a/src/message.rs +++ b/src/message.rs @@ -20,14 +20,14 @@ pub enum BackendMessage { AuthenticationGSS, AuthenticationKerberosV5, AuthenticationMD5Password { - salt: [u8; 4] + salt: [u8; 4], }, AuthenticationOk, AuthenticationSCMCredential, AuthenticationSSPI, BackendKeyData { process_id: u32, - secret_key: u32 + secret_key: u32, }, BindComplete, CloseComplete, @@ -48,15 +48,15 @@ pub enum BackendMessage { column_formats: Vec, }, DataRow { - row: Vec>> + row: Vec>>, }, EmptyQueryResponse, ErrorResponse { - fields: Vec<(u8, String)> + fields: Vec<(u8, String)>, }, NoData, NoticeResponse { - fields: Vec<(u8, String)> + fields: Vec<(u8, String)>, }, NotificationResponse { pid: u32, @@ -64,7 +64,7 @@ pub enum BackendMessage { payload: String, }, ParameterDescription { - types: Vec + types: Vec, }, ParameterStatus { parameter: String, @@ -73,11 +73,11 @@ pub enum BackendMessage { ParseComplete, PortalSuspended, ReadyForQuery { - _state: u8 + _state: u8, }, RowDescription { - descriptions: Vec - } + descriptions: Vec, + }, } pub struct RowDescriptionEntry { @@ -87,7 +87,7 @@ pub struct RowDescriptionEntry { pub type_oid: Oid, pub type_size: i16, pub type_modifier: i32, - pub format: i16 + pub format: i16, } pub enum FrontendMessage<'a> { @@ -96,7 +96,7 @@ pub enum FrontendMessage<'a> { statement: &'a str, formats: &'a [i16], values: &'a [Option>], - result_formats: &'a [i16] + result_formats: &'a [i16], }, CancelRequest { code: u32, @@ -105,43 +105,43 @@ pub enum FrontendMessage<'a> { }, Close { variant: u8, - name: &'a str + name: &'a str, }, CopyData { data: &'a [u8], }, CopyDone, CopyFail { - message: &'a str + message: &'a str, }, Describe { variant: u8, - name: &'a str + name: &'a str, }, Execute { portal: &'a str, - max_rows: i32 + max_rows: i32, }, Parse { name: &'a str, query: &'a str, - param_types: &'a [Oid] + param_types: &'a [Oid], }, PasswordMessage { - password: &'a str + password: &'a str, }, Query { - query: &'a str + query: &'a str, }, SslRequest { - code: u32 + code: u32, }, StartupMessage { version: u32, - parameters: &'a [(String, String)] + parameters: &'a [(String, String)], }, Sync, - Terminate + Terminate, } #[doc(hidden)] @@ -158,7 +158,7 @@ impl WriteCStr for W { #[doc(hidden)] pub trait WriteMessage { - fn write_message(&mut self, &FrontendMessage) -> io::Result<()> ; + fn write_message(&mut self, &FrontendMessage) -> io::Result<()>; } impl WriteMessage for W { @@ -285,8 +285,7 @@ impl ReadCStr for R { pub trait ReadMessage { fn read_message(&mut self) -> io::Result; - fn read_message_timeout(&mut self, timeout: Duration) - -> io::Result>; + fn read_message_timeout(&mut self, timeout: Duration) -> io::Result>; fn finish_read_message(&mut self, ident: u8) -> io::Result; } @@ -297,8 +296,7 @@ impl ReadMessage for R { self.finish_read_message(ident) } - fn read_message_timeout(&mut self, timeout: Duration) - -> io::Result> { + fn read_message_timeout(&mut self, timeout: Duration) -> io::Result> { try!(self.set_read_timeout(Some(timeout))); let ident = self.read_u8(); try!(self.set_read_timeout(None)); @@ -328,16 +326,14 @@ impl ReadMessage for R { b'A' => NotificationResponse { pid: try!(rdr.read_u32::()), channel: try!(rdr.read_cstr()), - payload: try!(rdr.read_cstr()) + payload: try!(rdr.read_cstr()), }, b'c' => BCopyDone, b'C' => CommandComplete { tag: try!(rdr.read_cstr()) }, b'd' => { let mut data = vec![]; try!(rdr.read_to_end(&mut data)); - BCopyData { - data: data, - } + BCopyData { data: data } } b'D' => try!(read_data_row(&mut rdr)), b'E' => ErrorResponse { fields: try!(read_fields(&mut rdr)) }, @@ -366,7 +362,7 @@ impl ReadMessage for R { b'I' => EmptyQueryResponse, b'K' => BackendKeyData { process_id: try!(rdr.read_u32::()), - secret_key: try!(rdr.read_u32::()) + secret_key: try!(rdr.read_u32::()), }, b'n' => NoData, b'N' => NoticeResponse { fields: try!(read_fields(&mut rdr)) }, @@ -374,7 +370,7 @@ impl ReadMessage for R { b's' => PortalSuspended, b'S' => ParameterStatus { parameter: try!(rdr.read_cstr()), - value: try!(rdr.read_cstr()) + value: try!(rdr.read_cstr()), }, b't' => try!(read_parameter_description(&mut rdr)), b'T' => try!(read_row_description(&mut rdr)), @@ -431,7 +427,7 @@ fn read_auth_message(buf: &mut R) -> io::Result { let mut salt = [0; 4]; try!(util::read_all(buf, &mut salt)); AuthenticationMD5Password { salt: salt } - }, + } 6 => AuthenticationSCMCredential, 7 => AuthenticationGSS, 9 => AuthenticationSSPI, diff --git a/src/notification.rs b/src/notification.rs index 58289a2b..2ba7df53 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -20,14 +20,14 @@ pub struct Notification { /// An iterator over asynchronous notifications. pub struct Notifications<'conn> { - conn: &'conn Connection + conn: &'conn Connection, } impl<'a> fmt::Debug for Notifications<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("Notifications") - .field("pending", &self.len()) - .finish() + .field("pending", &self.len()) + .finish() } } @@ -45,9 +45,7 @@ impl<'conn> Notifications<'conn> { /// `None` if more notifications are received. However, those notifications /// will not be registered until the connection is used in some way. pub fn iter<'a>(&'a self) -> Iter<'a> { - Iter { - conn: self.conn, - } + Iter { conn: self.conn } } /// Returns an iterator over notifications that blocks until one is @@ -55,9 +53,7 @@ impl<'conn> Notifications<'conn> { /// /// The iterator will never return `None`. pub fn blocking_iter<'a>(&'a self) -> BlockingIter<'a> { - BlockingIter { - conn: self.conn, - } + BlockingIter { conn: self.conn } } /// Returns an iterator over notifications that blocks for a limited time @@ -86,9 +82,7 @@ impl<'a, 'conn> IntoIterator for &'a Notifications<'conn> { impl<'conn> NotificationsNew<'conn> for Notifications<'conn> { fn new(conn: &'conn Connection) -> Notifications<'conn> { - Notifications { - conn: conn, - } + Notifications { conn: conn } } } @@ -129,11 +123,11 @@ impl<'a> Iterator for BlockingIter<'a> { Some(Ok(Notification { pid: pid, channel: channel, - payload: payload + payload: payload, })) } Err(err) => Some(Err(Error::IoError(err))), - _ => unreachable!() + _ => unreachable!(), } } } @@ -164,12 +158,12 @@ impl<'a> Iterator for TimeoutIter<'a> { Some(Ok(Notification { pid: pid, channel: channel, - payload: payload + payload: payload, })) } Ok(None) => None, Err(err) => Some(Err(Error::IoError(err))), - _ => unreachable!() + _ => unreachable!(), } } } diff --git a/src/priv_io.rs b/src/priv_io.rs index fc68bbfa..788a722b 100644 --- a/src/priv_io.rs +++ b/src/priv_io.rs @@ -13,7 +13,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::os::windows::io::{AsRawSocket, RawSocket}; use {SslMode, ConnectParams, ConnectTarget}; -use error::{ConnectError}; +use error::ConnectError; use io::{NegotiateSsl, StreamWrapper}; use message::{self, WriteMessage}; use message::FrontendMessage::SslRequest; @@ -28,7 +28,8 @@ pub trait ReadTimeout { impl ReadTimeout for BufStream> { fn set_read_timeout(&self, timeout: Option) -> io::Result<()> { match self.get_ref().get_ref().0 { - InternalStream::Tcp(ref s) => ::set_read_timeout(s, timeout), + InternalStream::Tcp(ref s) => + ::set_read_timeout(s, timeout), #[cfg(feature = "unix_socket")] InternalStream::Unix(ref s) => s.set_read_timeout(timeout), } @@ -136,8 +137,9 @@ fn open_socket(params: &ConnectParams) -> Result { } } -pub fn initialize_stream(params: &ConnectParams, ssl: &SslMode) - -> Result, ConnectError> { +pub fn initialize_stream(params: &ConnectParams, + ssl: &SslMode) + -> Result, ConnectError> { let mut socket = Stream(try!(open_socket(params))); let (ssl_required, negotiator) = match *ssl { @@ -161,11 +163,11 @@ pub fn initialize_stream(params: &ConnectParams, ssl: &SslMode) let host = match params.target { ConnectTarget::Tcp(ref host) => host, #[cfg(feature = "unix_socket")] - ConnectTarget::Unix(_) => return Err(ConnectError::IoError(::bad_response())) + ConnectTarget::Unix(_) => return Err(ConnectError::IoError(::bad_response())), }; match negotiator.negotiate_ssl(host, socket) { Ok(stream) => Ok(stream), - Err(err) => Err(ConnectError::SslError(err)) + Err(err) => Err(ConnectError::SslError(err)), } } diff --git a/src/rows.rs b/src/rows.rs index 0dd667d4..acd7711a 100644 --- a/src/rows.rs +++ b/src/rows.rs @@ -7,13 +7,7 @@ use std::borrow::Cow; use std::slice; use std::vec; -use {Result, - Transaction, - read_rows, - DbErrorNew, - SessionInfoNew, - RowsNew, - LazyRowsNew, +use {Result, Transaction, read_rows, DbErrorNew, SessionInfoNew, RowsNew, LazyRowsNew, StatementInternals}; use types::{FromSql, SessionInfo}; use stmt::{Statement, Column}; @@ -38,9 +32,9 @@ impl<'a> RowsNew<'a> for Rows<'a> { impl<'a> fmt::Debug for Rows<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("Rows") - .field("columns", &self.columns()) - .field("rows", &self.data.len()) - .finish() + .field("columns", &self.columns()) + .field("rows", &self.data.len()) + .finish() } } @@ -71,7 +65,7 @@ impl<'stmt> Rows<'stmt> { pub fn iter<'a>(&'a self) -> Iter<'a> { Iter { stmt: self.stmt, - iter: self.data.iter() + iter: self.data.iter(), } } } @@ -92,7 +86,7 @@ impl<'stmt> IntoIterator for Rows<'stmt> { fn into_iter(self) -> IntoIter<'stmt> { IntoIter { stmt: self.stmt, - iter: self.data.into_iter() + iter: self.data.into_iter(), } } } @@ -172,14 +166,14 @@ impl<'stmt> ExactSizeIterator for IntoIter<'stmt> {} /// A single result row of a query. pub struct Row<'a> { stmt: &'a Statement<'a>, - data: Cow<'a, [Option>]> + data: Cow<'a, [Option>]>, } impl<'a> fmt::Debug for Row<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("Row") - .field("statement", self.stmt) - .finish() + .field("statement", self.stmt) + .finish() } } @@ -201,14 +195,18 @@ impl<'a> Row<'a> { /// /// Returns an `Error` value if the index does not reference a column or /// the return type is not compatible with the Postgres type. - pub fn get_opt(&self, idx: I) -> Result where I: RowIndex, T: FromSql { + pub fn get_opt(&self, idx: I) -> Result + where I: RowIndex, + T: FromSql + { let idx = try!(idx.idx(self.stmt).ok_or(Error::InvalidColumn)); let ty = self.stmt.columns()[idx].type_(); if !::accepts(ty) { return Err(Error::WrongType(ty.clone())); } let conn = self.stmt.conn().conn.borrow(); - FromSql::from_sql_nullable(ty, self.data[idx].as_ref().map(|e| &**e).as_mut(), + FromSql::from_sql_nullable(ty, + self.data[idx].as_ref().map(|e| &**e).as_mut(), &SessionInfo::new(&*conn)) } @@ -217,35 +215,41 @@ impl<'a> Row<'a> { /// A field can be accessed by the name or index of its column, though /// access by index is more efficient. Rows are 0-indexed. /// - /// ## Panics + /// # Panics /// /// Panics if the index does not reference a column or the return type is /// not compatible with the Postgres type. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; /// # let conn = Connection::connect("", &SslMode::None).unwrap(); - /// # let stmt = conn.prepare("").unwrap(); - /// # let mut result = stmt.query(&[]).unwrap(); - /// # let row = result.iter().next().unwrap(); - /// let foo: i32 = row.get(0); - /// let bar: String = row.get("bar"); + /// let stmt = conn.prepare("SELECT foo, bar from BAZ").unwrap(); + /// for row in stmt.query(&[]).unwrap() { + /// let foo: i32 = row.get(0); + /// let bar: String = row.get("bar"); + /// println!("{}: {}", foo, bar); + /// } /// ``` - pub fn get(&self, idx: I) -> T where I: RowIndex + fmt::Debug + Clone, T: FromSql { + pub fn get(&self, idx: I) -> T + where I: RowIndex + fmt::Debug + Clone, + T: FromSql + { match self.get_opt(idx.clone()) { Ok(ok) => ok, - Err(err) => panic!("error retrieving column {:?}: {:?}", idx, err) + Err(err) => panic!("error retrieving column {:?}: {:?}", idx, err), } } /// Retrieves the specified field as a raw buffer of Postgres data. /// - /// ## Panics + /// # Panics /// /// Panics if the index does not reference a column. - pub fn get_bytes(&self, idx: I) -> Option<&[u8]> where I: RowIndex + fmt::Debug { + pub fn get_bytes(&self, idx: I) -> Option<&[u8]> + where I: RowIndex + fmt::Debug + { match idx.idx(self.stmt) { Some(idx) => self.data[idx].as_ref().map(|e| &**e), None => panic!("invalid index {:?}", idx), @@ -303,7 +307,8 @@ impl<'trans, 'stmt> LazyRowsNew<'trans, 'stmt> for LazyRows<'trans, 'stmt> { row_limit: i32, more_rows: bool, finished: bool, - trans: &'trans Transaction<'trans>) -> LazyRows<'trans, 'stmt> { + trans: &'trans Transaction<'trans>) + -> LazyRows<'trans, 'stmt> { LazyRows { stmt: stmt, data: data, @@ -311,7 +316,7 @@ impl<'trans, 'stmt> LazyRowsNew<'trans, 'stmt> for LazyRows<'trans, 'stmt> { row_limit: row_limit, more_rows: more_rows, finished: finished, - _trans: trans + _trans: trans, } } } @@ -327,11 +332,11 @@ impl<'a, 'b> Drop for LazyRows<'a, 'b> { impl<'a, 'b> fmt::Debug for LazyRows<'a, 'b> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("LazyRows") - .field("name", &self.name) - .field("row_limit", &self.row_limit) - .field("remaining_rows", &self.data.len()) - .field("more_rows", &self.more_rows) - .finish() + .field("name", &self.name) + .field("row_limit", &self.row_limit) + .field("remaining_rows", &self.data.len()) + .field("more_rows", &self.more_rows) + .finish() } } @@ -345,12 +350,11 @@ impl<'trans, 'stmt> LazyRows<'trans, 'stmt> { fn execute(&mut self) -> Result<()> { let mut conn = self.stmt.conn().conn.borrow_mut(); - try!(conn.write_messages(&[ - Execute { - portal: &self.name, - max_rows: self.row_limit - }, - Sync])); + try!(conn.write_messages(&[Execute { + portal: &self.name, + max_rows: self.row_limit, + }, + Sync])); read_rows(&mut conn, &mut self.data).map(|more_rows| self.more_rows = more_rows) } diff --git a/src/stmt.rs b/src/stmt.rs index 54135b6f..5d5909b2 100644 --- a/src/stmt.rs +++ b/src/stmt.rs @@ -28,10 +28,10 @@ pub struct Statement<'conn> { impl<'a> fmt::Debug for Statement<'a> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("Statement") - .field("name", &self.name) - .field("parameter_types", &self.param_types) - .field("columns", &self.columns) - .finish() + .field("name", &self.name) + .field("parameter_types", &self.param_types) + .field("columns", &self.columns) + .finish() } } @@ -47,7 +47,8 @@ impl<'conn> StatementInternals<'conn> for Statement<'conn> { param_types: Vec, columns: Vec, next_portal_id: Cell, - finished: bool) -> Statement<'conn> { + finished: bool) + -> Statement<'conn> { Statement { conn: conn, name: name, @@ -81,7 +82,9 @@ impl<'conn> Statement<'conn> { "expected {} parameters but got {}", self.param_types.len(), params.len()); - debug!("executing statement {} with parameters: {:?}", self.name, params); + debug!("executing statement {} with parameters: {:?}", + self.name, + params); let mut values = vec![]; for (param, ty) in params.iter().zip(self.param_types.iter()) { let mut buf = vec![]; @@ -89,21 +92,20 @@ impl<'conn> Statement<'conn> { IsNull::Yes => values.push(None), IsNull::No => values.push(Some(buf)), } - }; + } - try!(conn.write_messages(&[ - Bind { - portal: portal_name, - statement: &self.name, - formats: &[1], - values: &values, - result_formats: &[1] - }, - Execute { - portal: portal_name, - max_rows: row_limit - }, - Sync])); + try!(conn.write_messages(&[Bind { + portal: portal_name, + statement: &self.name, + formats: &[1], + values: &values, + result_formats: &[1], + }, + Execute { + portal: portal_name, + max_rows: row_limit, + }, + Sync])); match try!(conn.read_message()) { BindComplete => Ok(()), @@ -118,7 +120,10 @@ impl<'conn> Statement<'conn> { } } - fn inner_query<'a>(&'a self, portal_name: &str, row_limit: i32, params: &[&ToSql]) + fn inner_query<'a>(&'a self, + portal_name: &str, + row_limit: i32, + params: &[&ToSql]) -> Result<(VecDeque>>>, bool)> { try!(self.inner_execute(portal_name, row_limit, params)); @@ -141,12 +146,12 @@ impl<'conn> Statement<'conn> { /// /// If the statement does not modify any rows (e.g. SELECT), 0 is returned. /// - /// ## Panics + /// # Panics /// /// Panics if the number of parameters provided does not match the number /// expected. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; @@ -154,10 +159,8 @@ impl<'conn> Statement<'conn> { /// # let bar = 1i32; /// # let baz = true; /// let stmt = conn.prepare("UPDATE foo SET bar = $1 WHERE baz = $2").unwrap(); - /// match stmt.execute(&[&bar, &baz]) { - /// Ok(count) => println!("{} row(s) updated", count), - /// Err(err) => println!("Error executing query: {:?}", err) - /// } + /// let rows_updated = stmt.execute(&[&bar, &baz]).unwrap(); + /// println!("{} rows updated", rows_updated); /// ``` pub fn execute(&self, params: &[&ToSql]) -> Result { check_desync!(self.conn); @@ -181,11 +184,11 @@ impl<'conn> Statement<'conn> { break; } CopyInResponse { .. } => { - try!(conn.write_messages(&[ - CopyFail { - message: "COPY queries cannot be directly executed", - }, - Sync])); + try!(conn.write_messages(&[CopyFail { + message: "COPY queries cannot be directly \ + executed", + }, + Sync])); } CopyOutResponse { .. } => { loop { @@ -214,32 +217,26 @@ impl<'conn> Statement<'conn> { /// Executes the prepared statement, returning the resulting rows. /// - /// ## Panics + /// # Panics /// /// Panics if the number of parameters provided does not match the number /// expected. /// - /// ## Example + /// # Example /// /// ```rust,no_run /// # use postgres::{Connection, SslMode}; /// # let conn = Connection::connect("", &SslMode::None).unwrap(); /// let stmt = conn.prepare("SELECT foo FROM bar WHERE baz = $1").unwrap(); /// # let baz = true; - /// let rows = match stmt.query(&[&baz]) { - /// Ok(rows) => rows, - /// Err(err) => panic!("Error running query: {:?}", err) - /// }; - /// for row in &rows { + /// for row in stmt.query(&[&baz]).unwrap() { /// let foo: i32 = row.get("foo"); /// println!("foo: {}", foo); /// } /// ``` pub fn query<'a>(&'a self, params: &[&ToSql]) -> Result> { check_desync!(self.conn); - self.inner_query("", 0, params).map(|(buf, _)| { - Rows::new(self, buf.into_iter().collect()) - }) + self.inner_query("", 0, params).map(|(buf, _)| Rows::new(self, buf.into_iter().collect())) } /// Executes the prepared statement, returning a lazily loaded iterator @@ -254,7 +251,7 @@ impl<'conn> Statement<'conn> { /// object representing the active transaction must be passed to /// `lazy_query`. /// - /// ## Panics + /// # Panics /// /// Panics if the provided `Transaction` is not associated with the same /// `Connection` as this `Statement`, if the `Transaction` is not @@ -318,9 +315,10 @@ impl<'conn> Statement<'conn> { loop { match try!(conn.read_message()) { ReadyForQuery { .. } => { - return Err(Error::IoError(io::Error::new( - io::ErrorKind::InvalidInput, - "called `copy_in` on a non-`COPY FROM STDIN` statement"))); + return Err(Error::IoError(io::Error::new(io::ErrorKind::InvalidInput, + "called `copy_in` on a \ + non-`COPY FROM STDIN` \ + statement"))); } _ => {} } @@ -339,20 +337,15 @@ impl<'conn> Statement<'conn> { match fill_copy_buf(&mut buf, r, &info) { Ok(0) => break, Ok(len) => { - try_desync!(info.conn, info.conn.stream.write_message( - &CopyData { - data: &buf[..len], - })); + try_desync!(info.conn, + info.conn.stream.write_message(&CopyData { data: &buf[..len] })); } Err(err) => { - try!(info.conn.write_messages(&[ - CopyFail { - message: "", - }, - CopyDone, - Sync])); + try!(info.conn.write_messages(&[CopyFail { message: "" }, CopyDone, Sync])); match try!(info.conn.read_message()) { - ErrorResponse { .. } => { /* expected from the CopyFail */ } + ErrorResponse { .. } => { + // expected from the CopyFail + } _ => { info.conn.desynchronized = true; return Err(Error::IoError(bad_response())); @@ -401,7 +394,7 @@ impl<'conn> Statement<'conn> { /// INSERT INTO people (id, name) VALUES (1, 'john'), (2, 'jane');").unwrap(); /// let stmt = conn.prepare("COPY people TO STDOUT").unwrap(); /// let mut buf = vec![]; - /// let mut r = stmt.copy_out(&[], &mut buf).unwrap(); + /// stmt.copy_out(&[], &mut buf).unwrap(); /// assert_eq!(buf, b"1\tjohn\n2\tjane\n"); /// ``` pub fn copy_out<'a, W: WriteWithInfo>(&'a self, params: &[&ToSql], w: &mut W) -> Result { @@ -411,23 +404,20 @@ impl<'conn> Statement<'conn> { let (format, column_formats) = match try!(conn.read_message()) { CopyOutResponse { format, column_formats } => (format, column_formats), CopyInResponse { .. } => { - try!(conn.write_messages(&[ - CopyFail { - message: "", - }, - CopyDone, - Sync])); + try!(conn.write_messages(&[CopyFail { message: "" }, CopyDone, Sync])); match try!(conn.read_message()) { - ErrorResponse { .. } => { /* expected from the CopyFail */ } + ErrorResponse { .. } => { + // expected from the CopyFail + } _ => { conn.desynchronized = true; return Err(Error::IoError(bad_response())); } } try!(conn.wait_for_ready()); - return Err(Error::IoError(io::Error::new( - io::ErrorKind::InvalidInput, - "called `copy_out` on a non-`COPY TO STDOUT` statement"))); + return Err(Error::IoError(io::Error::new(io::ErrorKind::InvalidInput, + "called `copy_out` on a non-`COPY TO \ + STDOUT` statement"))); } ErrorResponse { fields } => { try!(conn.wait_for_ready()); @@ -437,9 +427,10 @@ impl<'conn> Statement<'conn> { loop { match try!(conn.read_message()) { ReadyForQuery { .. } => { - return Err(Error::IoError(io::Error::new( - io::ErrorKind::InvalidInput, - "called `copy_out` on a non-`COPY TO STDOUT` statement"))); + return Err(Error::IoError(io::Error::new(io::ErrorKind::InvalidInput, + "called `copy_out` on a \ + non-`COPY TO STDOUT` \ + statement"))); } _ => {} } @@ -472,7 +463,7 @@ impl<'conn> Statement<'conn> { } } } - BCopyDone => {}, + BCopyDone => {} CommandComplete { tag } => { count = util::parse_update_count(tag); break; @@ -512,8 +503,7 @@ impl<'conn> Statement<'conn> { } } -fn fill_copy_buf(buf: &mut [u8], r: &mut R, info: &CopyInfo) - -> io::Result { +fn fill_copy_buf(buf: &mut [u8], r: &mut R, info: &CopyInfo) -> io::Result { let mut nread = 0; while nread < buf.len() { match r.read_with_info(&mut buf[nread..], info) { @@ -530,7 +520,7 @@ fn fill_copy_buf(buf: &mut [u8], r: &mut R, info: &CopyInfo) #[derive(PartialEq, Eq, Clone, Debug)] pub struct Column { name: String, - type_: Type + type_: Type, } impl ColumnNew for Column { diff --git a/src/types/chrono.rs b/src/types/chrono.rs index 7c4e3160..657baec4 100644 --- a/src/types/chrono.rs +++ b/src/types/chrono.rs @@ -3,7 +3,8 @@ extern crate chrono; use std::error; use std::io::prelude::*; use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian}; -use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC, Local, FixedOffset}; +use self::chrono::{Duration, NaiveDate, NaiveTime, NaiveDateTime, DateTime, UTC, Local, + FixedOffset}; use Result; use error::Error; @@ -23,11 +24,15 @@ impl FromSql for NaiveDateTime { } impl ToSql for NaiveDateTime { - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { let time = match (*self - base()).num_microseconds() { Some(time) => time, None => { - let err: Box = "value too large to transmit".into(); + let err: Box = "value too large to transmit".into(); return Err(Error::Conversion(err)); } }; @@ -49,8 +54,11 @@ impl FromSql for DateTime { } impl ToSql for DateTime { - fn to_sql(&self, type_: &Type, mut w: &mut W, info: &SessionInfo) - -> Result { + fn to_sql(&self, + type_: &Type, + mut w: &mut W, + info: &SessionInfo) + -> Result { self.naive_utc().to_sql(type_, w, info) } @@ -68,8 +76,11 @@ impl FromSql for DateTime { } impl ToSql for DateTime { - fn to_sql(&self, type_: &Type, mut w: &mut W, info: &SessionInfo) - -> Result { + fn to_sql(&self, + type_: &Type, + mut w: &mut W, + info: &SessionInfo) + -> Result { self.with_timezone(&UTC).to_sql(type_, w, info) } @@ -78,7 +89,9 @@ impl ToSql for DateTime { } impl FromSql for DateTime { - fn from_sql(type_: &Type, raw: &mut R, info: &SessionInfo) + fn from_sql(type_: &Type, + raw: &mut R, + info: &SessionInfo) -> Result> { let utc = try!(DateTime::::from_sql(type_, raw, info)); Ok(utc.with_timezone(&FixedOffset::east(0))) @@ -88,8 +101,11 @@ impl FromSql for DateTime { } impl ToSql for DateTime { - fn to_sql(&self, type_: &Type, mut w: &mut W, info: &SessionInfo) - -> Result { + fn to_sql(&self, + type_: &Type, + mut w: &mut W, + info: &SessionInfo) + -> Result { self.with_timezone(&UTC).to_sql(type_, w, info) } @@ -107,10 +123,14 @@ impl FromSql for NaiveDate { } impl ToSql for NaiveDate { - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { let jd = (*self - base().date()).num_days(); if jd > i32::max_value() as i64 || jd < i32::min_value() as i64 { - let err: Box = "value too large to transmit".into(); + let err: Box = "value too large to transmit".into(); return Err(Error::Conversion(err)); } @@ -132,12 +152,16 @@ impl FromSql for NaiveTime { } impl ToSql for NaiveTime { - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { let delta = *self - NaiveTime::from_hms(0, 0, 0); let time = match delta.num_microseconds() { Some(time) => time, None => { - let err: Box = "value too large to transmit".into(); + let err: Box = "value too large to transmit".into(); return Err(Error::Conversion(err)); } }; diff --git a/src/types/mod.rs b/src/types/mod.rs index 9d8ed8a3..7ad02213 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -37,7 +37,7 @@ macro_rules! to_sql_checked { if !::accepts(ty) { return Err($crate::error::Error::WrongType(ty.clone())); } - self.to_sql(ty, out, ctx) + $crate::types::ToSql::to_sql(self, ty, out, ctx) } } } @@ -63,9 +63,7 @@ pub struct SessionInfo<'a> { impl<'a> SessionInfoNew<'a> for SessionInfo<'a> { fn new(conn: &'a InnerConnection) -> SessionInfo<'a> { - SessionInfo { - conn: conn - } + SessionInfo { conn: conn } } } @@ -176,317 +174,317 @@ macro_rules! make_postgres_type { // Values from pg_type.h make_postgres_type! { - #[doc="BOOL - boolean, 'true'/'false'"] + /// BOOL - boolean, 'true'/'false' 16: "bool" => Bool: Kind::Simple, - #[doc="BYTEA - variable-length string, binary values escaped"] + /// BYTEA - variable-length string, binary values escaped 17: "bytea" => Bytea: Kind::Simple, - #[doc="\"char\" - single character"] + /// "char" - single character 18: "char" => Char: Kind::Simple, - #[doc="NAME - 63-byte type for storing system identifiers"] + /// NAME - 63-byte type for storing system identifiers 19: "name" => Name: Kind::Simple, - #[doc="INT8/BIGINT - ~18 digit integer, 8-byte storage"] + /// INT8/BIGINT - ~18 digit integer, 8-byte storage 20: "int8" => Int8: Kind::Simple, - #[doc="INT2/SMALLINT - -32 thousand to 32 thousand, 2-byte storage"] + /// INT2/SMALLINT - -32 thousand to 32 thousand, 2-byte storage 21: "int2" => Int2: Kind::Simple, - #[doc="INT2VECTOR - array of int2, used in system tables"] + /// INT2VECTOR - array of int2, used in system tables 22: "int2vector" => Int2Vector: Kind::Array(Type::Int2), - #[doc="INT4/INT - -2 billion to 2 billion integer, 4-byte storage"] + /// INT4/INT - -2 billion to 2 billion integer, 4-byte storage 23: "int4" => Int4: Kind::Simple, - #[doc="REGPROC - registered procedure"] + /// REGPROC - registered procedure 24: "regproc" => Regproc: Kind::Simple, - #[doc="TEXT - variable-length string, no limit specified"] + /// TEXT - variable-length string, no limit specified 25: "text" => Text: Kind::Simple, - #[doc="OID - object identifier(oid), maximum 4 billion"] + /// OID - object identifier(oid), maximum 4 billion 26: "oid" => Oid: Kind::Simple, - #[doc="TID - (block, offset), physical location of tuple"] + /// TID - (block, offset), physical location of tuple 27: "tid" => Tid: Kind::Simple, - #[doc="XID - transaction id"] + /// XID - transaction id 28: "xid" => Xid: Kind::Simple, - #[doc="CID - command identifier type, sequence in transaction id"] + /// CID - command identifier type, sequence in transaction id 29: "cid" => Cid: Kind::Simple, - #[doc="OIDVECTOR - array of oids, used in system tables"] + /// OIDVECTOR - array of oids, used in system tables 30: "oidvector" => OidVector: Kind::Array(Type::Oid), - #[doc="PG_TYPE"] + /// PG_TYPE 71: "pg_type" => PgType: Kind::Simple, - #[doc="PG_ATTRIBUTE"] + /// PG_ATTRIBUTE 75: "pg_attribute" => PgAttribute: Kind::Simple, - #[doc="PG_PROC"] + /// PG_PROC 81: "pg_proc" => PgProc: Kind::Simple, - #[doc="PG_CLASS"] + /// PG_CLASS 83: "pg_class" => PgClass: Kind::Simple, - #[doc="JSON"] + /// JSON 114: "json" => Json: Kind::Simple, - #[doc="XML - XML content"] + /// XML - XML content 142: "xml" => Xml: Kind::Simple, - #[doc="XML[]"] + /// XML[] 143: "_xml" => XmlArray: Kind::Array(Type::Xml), - #[doc="PG_NODE_TREE - string representing an internal node tree"] + /// PG_NODE_TREE - string representing an internal node tree 194: "pg_node_tree" => PgNodeTree: Kind::Simple, - #[doc="JSON[]"] + /// JSON[] 199: "_json" => JsonArray: Kind::Array(Type::Json), - #[doc="SMGR - storage manager"] + /// SMGR - storage manager 210: "smgr" => Smgr: Kind::Simple, - #[doc="POINT - geometric point '(x, y)'"] + /// POINT - geometric point '(x, y)' 600: "point" => Point: Kind::Simple, - #[doc="LSEG - geometric line segment '(pt1,pt2)'"] + /// LSEG - geometric line segment '(pt1,pt2)' 601: "lseg" => Lseg: Kind::Simple, - #[doc="PATH - geometric path '(pt1,...)'"] + /// PATH - geometric path '(pt1,...)' 602: "path" => Path: Kind::Simple, - #[doc="BOX - geometric box '(lower left,upper right)'"] + /// BOX - geometric box '(lower left,upper right)' 603: "box" => Box: Kind::Simple, - #[doc="POLYGON - geometric polygon '(pt1,...)'"] + /// POLYGON - geometric polygon '(pt1,...)' 604: "polygon" => Polygon: Kind::Simple, - #[doc="LINE - geometric line"] + /// LINE - geometric line 628: "line" => Line: Kind::Simple, - #[doc="LINE[]"] + /// LINE[] 629: "_line" => LineArray: Kind::Array(Type::Line), - #[doc="CIDR - network IP address/netmask, network address"] + /// CIDR - network IP address/netmask, network address 650: "cidr" => Cidr: Kind::Simple, - #[doc="CIDR[]"] + /// CIDR[] 651: "_cidr" => CidrArray: Kind::Array(Type::Cidr), - #[doc="FLOAT4/REAL - single-precision floating point number, 4-byte storage"] + /// FLOAT4/REAL - single-precision floating point number, 4-byte storage 700: "float4" => Float4: Kind::Simple, - #[doc="FLOAT8/DOUBLE PRECISION - double-precision floating point number, 8-byte storage"] + /// FLOAT8/DOUBLE PRECISION - double-precision floating point number, 8-byte storage 701: "float8" => Float8: Kind::Simple, - #[doc="ABSTIME - absolute, limited-range date and time (Unix system time)"] + /// ABSTIME - absolute, limited-range date and time (Unix system time) 702: "abstime" => Abstime: Kind::Simple, - #[doc="RELTIME - relative, limited-range date and time (Unix delta time)"] + /// RELTIME - relative, limited-range date and time (Unix delta time) 703: "reltime" => Reltime: Kind::Simple, - #[doc="TINTERVAL - (abstime,abstime), time interval"] + /// TINTERVAL - (abstime,abstime), time interval 704: "tinterval" => Tinterval: Kind::Simple, - #[doc="UNKNOWN"] + /// UNKNOWN 705: "unknown" => Unknown: Kind::Simple, - #[doc="CIRCLE - geometric circle '(center,radius)'"] + /// CIRCLE - geometric circle '(center,radius)' 718: "circle" => Circle: Kind::Simple, - #[doc="CIRCLE[]"] + /// CIRCLE[] 719: "_circle" => CircleArray: Kind::Array(Type::Circle), - #[doc="MONEY - monetary amounts, $d,ddd.cc"] + /// MONEY - monetary amounts, $d,ddd.cc 790: "money" => Money: Kind::Simple, - #[doc="MONEY[]"] + /// MONEY[] 791: "_money" => MoneyArray: Kind::Array(Type::Money), - #[doc="MACADDR - XX:XX:XX:XX:XX:XX, MAC address"] + /// MACADDR - XX:XX:XX:XX:XX:XX, MAC address 829: "macaddr" => Macaddr: Kind::Simple, - #[doc="INET - IP address/netmask, host address, netmask optional"] + /// INET - IP address/netmask, host address, netmask optional 869: "inet" => Inet: Kind::Simple, - #[doc="BOOL[]"] + /// BOOL[] 1000: "_bool" => BoolArray: Kind::Array(Type::Bool), - #[doc="BYTEA[]"] + /// BYTEA[] 1001: "_bytea" => ByteaArray: Kind::Array(Type::Bytea), - #[doc="\"char\"[]"] + /// "char"[] 1002: "_char" => CharArray: Kind::Array(Type::Char), - #[doc="NAME[]"] + /// NAME[] 1003: "_name" => NameArray: Kind::Array(Type::Name), - #[doc="INT2[]"] + /// INT2[] 1005: "_int2" => Int2Array: Kind::Array(Type::Int2), - #[doc="INT2VECTOR[]"] + /// INT2VECTOR[] 1006: "_int2vector" => Int2VectorArray: Kind::Array(Type::Int2Vector), - #[doc="INT4[]"] + /// INT4[] 1007: "_int4" => Int4Array: Kind::Array(Type::Int4), - #[doc="REGPROC[]"] + /// REGPROC[] 1008: "_regproc" => RegprocArray: Kind::Array(Type::Regproc), - #[doc="TEXT[]"] + /// TEXT[] 1009: "_text" => TextArray: Kind::Array(Type::Text), - #[doc="TID[]"] + /// TID[] 1010: "_tid" => TidArray: Kind::Array(Type::Tid), - #[doc="XID[]"] + /// XID[] 1011: "_xid" => XidArray: Kind::Array(Type::Xid), - #[doc="CID[]"] + /// CID[] 1012: "_cid" => CidArray: Kind::Array(Type::Cid), - #[doc="OIDVECTOR[]"] + /// OIDVECTOR[] 1013: "_oidvector" => OidVectorArray: Kind::Array(Type::OidVector), - #[doc="BPCHAR[]"] + /// BPCHAR[] 1014: "_bpchar" => BpcharArray: Kind::Array(Type::Bpchar), - #[doc="VARCHAR[]"] + /// VARCHAR[] 1015: "_varchar" => VarcharArray: Kind::Array(Type::Varchar), - #[doc="INT8[]"] + /// INT8[] 1016: "_int8" => Int8Array: Kind::Array(Type::Int8), - #[doc="POINT[]"] + /// POINT[] 1017: "_point" => PointArray: Kind::Array(Type::Point), - #[doc="LSEG[]"] + /// LSEG[] 1018: "_lseg" => LsegArray: Kind::Array(Type::Lseg), - #[doc="PATH[]"] + /// PATH[] 1019: "_path" => PathArray: Kind::Array(Type::Path), - #[doc="BOX[]"] + /// BOX[] 1020: "_box" => BoxArray: Kind::Array(Type::Box), - #[doc="FLOAT4[]"] + /// FLOAT4[] 1021: "_float4" => Float4Array: Kind::Array(Type::Float4), - #[doc="FLOAT8[]"] + /// FLOAT8[] 1022: "_float8" => Float8Array: Kind::Array(Type::Float8), - #[doc="ABSTIME[]"] + /// ABSTIME[] 1023: "_abstime" => AbstimeArray: Kind::Array(Type::Abstime), - #[doc="RELTIME[]"] + /// RELTIME[] 1024: "_reltime" => ReltimeArray: Kind::Array(Type::Reltime), - #[doc="TINTERVAL[]"] + /// TINTERVAL[] 1025: "_tinterval" => TintervalArray: Kind::Array(Type::Tinterval), - #[doc="POLYGON[]"] + /// POLYGON[] 1027: "_polygon" => PolygonArray: Kind::Array(Type::Polygon), - #[doc="OID[]"] + /// OID[] 1028: "_oid" => OidArray: Kind::Array(Type::Oid), - #[doc="ACLITEM - access control list"] + /// ACLITEM - access control list 1033: "aclitem" => Aclitem: Kind::Simple, - #[doc="ACLITEM[]"] + /// ACLITEM[] 1034: "_aclitem" => AclitemArray: Kind::Array(Type::Aclitem), - #[doc="MACADDR[]"] + /// MACADDR[] 1040: "_macaddr" => MacaddrArray: Kind::Array(Type::Macaddr), - #[doc="INET[]"] + /// INET[] 1041: "_inet" => InetArray: Kind::Array(Type::Inet), - #[doc="BPCHAR - char(length), blank-padded string, fixed storage length"] + /// BPCHAR - char(length), blank-padded string, fixed storage length 1042: "bpchar" => Bpchar: Kind::Simple, - #[doc="VARCHAR - varchar(length), non-blank-padded string, variable storage length"] + /// VARCHAR - varchar(length), non-blank-padded string, variable storage length 1043: "varchar" => Varchar: Kind::Simple, - #[doc="DATE - date"] + /// DATE - date 1082: "date" => Date: Kind::Simple, - #[doc="TIME - time of day"] + /// TIME - time of day 1083: "time" => Time: Kind::Simple, - #[doc="TIMESTAMP - date and time"] + /// TIMESTAMP - date and time 1114: "timestamp" => Timestamp: Kind::Simple, - #[doc="TIMESTAMP[]"] + /// TIMESTAMP[] 1115: "_timestamp" => TimestampArray: Kind::Array(Type::Timestamp), - #[doc="DATE[]"] + /// DATE[] 1182: "_date" => DateArray: Kind::Array(Type::Date), - #[doc="TIME[]"] + /// TIME[] 1183: "_time" => TimeArray: Kind::Array(Type::Time), - #[doc="TIMESTAMPTZ - date and time with time zone"] + /// TIMESTAMPTZ - date and time with time zone 1184: "timestamptz" => TimestampTZ: Kind::Simple, - #[doc="TIMESTAMPTZ[]"] + /// TIMESTAMPTZ[] 1185: "_timestamptz" => TimestampTZArray: Kind::Array(Type::TimestampTZ), - #[doc="INTERVAL - @ <number> <units>, time interval"] + /// INTERVAL - @ <number> <units>, time interval 1186: "interval" => Interval: Kind::Simple, - #[doc="INTERVAL[]"] + /// INTERVAL[] 1187: "_interval" => IntervalArray: Kind::Array(Type::Interval), - #[doc="NUMERIC[]"] + /// NUMERIC[] 1231: "_numeric" => NumericArray: Kind::Array(Type::Numeric), - #[doc="CSTRING[]"] + /// CSTRING[] 1263: "_cstring" => CstringArray: Kind::Array(Type::Cstring), - #[doc="TIMETZ - time of day with time zone"] + /// TIMETZ - time of day with time zone 1266: "timetz" => Timetz: Kind::Simple, - #[doc="TIMETZ[]"] + /// TIMETZ[] 1270: "_timetz" => TimetzArray: Kind::Array(Type::Timetz), - #[doc="BIT - fixed-length bit string"] + /// BIT - fixed-length bit string 1560: "bit" => Bit: Kind::Simple, - #[doc="BIT[]"] + /// BIT[] 1561: "_bit" => BitArray: Kind::Array(Type::Bit), - #[doc="VARBIT - variable-length bit string"] + /// VARBIT - variable-length bit string 1562: "varbit" => Varbit: Kind::Simple, - #[doc="VARBIT[]"] + /// VARBIT[] 1563: "_varbit" => VarbitArray: Kind::Array(Type::Varbit), - #[doc="NUMERIC - numeric(precision, decimal), arbitrary precision number"] + /// NUMERIC - numeric(precision, decimal), arbitrary precision number 1700: "numeric" => Numeric: Kind::Simple, - #[doc="REFCURSOR - reference to cursor (portal name)"] + /// REFCURSOR - reference to cursor (portal name) 1790: "refcursor" => Refcursor: Kind::Simple, - #[doc="REFCURSOR[]"] + /// REFCURSOR[] 2201: "_refcursor" => RefcursorArray: Kind::Array(Type::Refcursor), - #[doc="REGPROCEDURE - registered procedure (with args)"] + /// REGPROCEDURE - registered procedure (with args) 2202: "regprocedure" => Regprocedure: Kind::Simple, - #[doc="REGOPER - registered operator"] + /// REGOPER - registered operator 2203: "regoper" => Regoper: Kind::Simple, - #[doc="REGOPERATOR - registered operator (with args)"] + /// REGOPERATOR - registered operator (with args) 2204: "regoperator" => Regoperator: Kind::Simple, - #[doc="REGCLASS - registered class"] + /// REGCLASS - registered class 2205: "regclass" => Regclass: Kind::Simple, - #[doc="REGTYPE - registered type"] + /// REGTYPE - registered type 2206: "regtype" => Regtype: Kind::Simple, - #[doc="REGPROCEDURE[]"] + /// REGPROCEDURE[] 2207: "_regprocedure" => RegprocedureArray: Kind::Array(Type::Regprocedure), - #[doc="REGOPER[]"] + /// REGOPER[] 2208: "_regoper" => RegoperArray: Kind::Array(Type::Regoper), - #[doc="REGOPERATOR[]"] + /// REGOPERATOR[] 2209: "_regoperator" => RegoperatorArray: Kind::Array(Type::Regoperator), - #[doc="REGCLASS[]"] + /// REGCLASS[] 2210: "_regclass" => RegclassArray: Kind::Array(Type::Regclass), - #[doc="REGTYPE[]"] + /// REGTYPE[] 2211: "_regtype" => RegtypeArray: Kind::Array(Type::Regtype), - #[doc="RECORD"] + /// RECORD 2249: "record" => Record: Kind::Simple, - #[doc="CSTRING"] + /// CSTRING 2275: "cstring" => Cstring: Kind::Simple, - #[doc="ANY"] + /// ANY 2276: "any" => Any: Kind::Simple, - #[doc="ANYARRAY"] + /// ANYARRAY 2277: "anyarray" => AnyArray: Kind::Array(Type::Any), - #[doc="VOID"] + /// VOID 2278: "void" => Void: Kind::Simple, - #[doc="TRIGGER"] + /// TRIGGER 2279: "trigger" => Trigger: Kind::Simple, - #[doc="LANGUAGE_HANDLER"] + /// LANGUAGE_HANDLER 2280: "language_handler" => LanguageHandler: Kind::Simple, - #[doc="INTERNAL"] + /// INTERNAL 2281: "internal" => Internal: Kind::Simple, - #[doc="OPAQUE"] + /// OPAQUE 2282: "opaque" => Opaque: Kind::Simple, - #[doc="ANYELEMENT"] + /// ANYELEMENT 2283: "anyelement" => Anyelement: Kind::Simple, - #[doc="RECORD[]"] + /// RECORD[] 2287: "_record" => RecordArray: Kind::Array(Type::Record), - #[doc="ANYNONARRAY"] + /// ANYNONARRAY 2776: "anynonarray" => Anynonarray: Kind::Simple, - #[doc="TXID_SNAPSHOT[]"] + /// TXID_SNAPSHOT[] 2949: "_txid_snapshot" => TxidSnapshotArray: Kind::Array(Type::TxidSnapshot), - #[doc="UUID - UUID datatype"] + /// UUID - UUID datatype 2950: "uuid" => Uuid: Kind::Simple, - #[doc="TXID_SNAPSHOT - txid snapshot"] + /// TXID_SNAPSHOT - txid snapshot 2970: "txid_snapshot" => TxidSnapshot: Kind::Simple, - #[doc="UUID[]"] + /// UUID[] 2951: "_uuid" => UuidArray: Kind::Array(Type::Uuid), - #[doc="FDW_HANDLER"] + /// FDW_HANDLER 3115: "fdw_handler" => FdwHandler: Kind::Simple, - #[doc="PG_LSN - PostgreSQL LSN datatype"] + /// PG_LSN - PostgreSQL LSN datatype 3220: "pg_lsn" => PgLsn: Kind::Simple, - #[doc="PG_LSN[]"] + /// PG_LSN[] 3221: "_pg_lsn" => PgLsnArray: Kind::Array(Type::PgLsn), - #[doc="ANYENUM"] + /// ANYENUM 3500: "anyenum" => Anyenum: Kind::Simple, - #[doc="TSVECTOR - text representation for text search"] + /// TSVECTOR - text representation for text search 3614: "tsvector" => Tsvector: Kind::Simple, - #[doc="TSQUERY - query representation for text search"] + /// TSQUERY - query representation for text search 3615: "tsquery" => Tsquery: Kind::Simple, - #[doc="GTSVECTOR - GiST index internal text representation for text search"] + /// GTSVECTOR - GiST index internal text representation for text search 3642: "gtsvector" => Gtsvector: Kind::Simple, - #[doc="TSVECTOR[]"] + /// TSVECTOR[] 3643: "_tsvector" => TsvectorArray: Kind::Array(Type::Tsvector), - #[doc="GTSVECTOR[]"] + /// GTSVECTOR[] 3644: "_gtsvector" => GtsvectorArray: Kind::Array(Type::Gtsvector), - #[doc="TSQUERY[]"] + /// TSQUERY[] 3645: "_tsquery" => TsqueryArray: Kind::Array(Type::Tsquery), - #[doc="REGCONFIG - registered text search configuration"] + /// REGCONFIG - registered text search configuration 3734: "regconfig" => Regconfig: Kind::Simple, - #[doc="REGCONFIG[]"] + /// REGCONFIG[] 3735: "_regconfig" => RegconfigArray: Kind::Array(Type::Regconfig), - #[doc="REGDICTIONARY - registered text search dictionary"] + /// REGDICTIONARY - registered text search dictionary 3769: "regdictionary" => Regdictionary: Kind::Simple, - #[doc="REGDICTIONARY[]"] + /// REGDICTIONARY[] 3770: "_regdictionary" => RegdictionaryArray: Kind::Array(Type::Regdictionary), - #[doc="JSONB"] + /// JSONB 3802: "jsonb" => Jsonb: Kind::Simple, - #[doc="ANYRANGE"] + /// ANYRANGE 3831: "anyrange" => Anyrange: Kind::Simple, - #[doc="JSONB[]"] + /// JSONB[] 3807: "_jsonb" => JsonbArray: Kind::Array(Type::Jsonb), - #[doc="INT4RANGE - range of integers"] + /// INT4RANGE - range of integers 3904: "int4range" => Int4Range: Kind::Range(Type::Int4), - #[doc="INT4RANGE[]"] + /// INT4RANGE[] 3905: "_int4range" => Int4RangeArray: Kind::Array(Type::Int4Range), - #[doc="NUMRANGE - range of numerics"] + /// NUMRANGE - range of numerics 3906: "numrange" => NumRange: Kind::Range(Type::Numeric), - #[doc="NUMRANGE[]"] + /// NUMRANGE[] 3907: "_numrange" => NumRangeArray: Kind::Array(Type::NumRange), - #[doc="TSRANGE - range of timestamps without time zone"] + /// TSRANGE - range of timestamps without time zone 3908: "tsrange" => TsRange: Kind::Range(Type::Timestamp), - #[doc="TSRANGE[]"] + /// TSRANGE[] 3909: "_tsrange" => TsRangeArray: Kind::Array(Type::TsRange), - #[doc="TSTZRANGE - range of timestamps with time zone"] + /// TSTZRANGE - range of timestamps with time zone 3910: "tstzrange" => TstzRange: Kind::Range(Type::TimestampTZ), - #[doc="TSTZRANGE[]"] + /// TSTZRANGE[] 3911: "_tstzrange" => TstzRangeArray: Kind::Array(Type::TstzRange), - #[doc="DATERANGE - range of dates"] + /// DATERANGE - range of dates 3912: "daterange" => DateRange: Kind::Range(Type::Date), - #[doc="DATERANGE[]"] + /// DATERANGE[] 3913: "_daterange" => DateRangeArray: Kind::Array(Type::DateRange), - #[doc="INT8RANGE - range of bigints"] + /// INT8RANGE - range of bigints 3926: "int8range" => Int8Range: Kind::Range(Type::Int8), - #[doc="INT8RANGE[]"] + /// INT8RANGE[] 3927: "_int8range" => Int8RangeArray: Kind::Array(Type::Int8Range), - #[doc="EVENT_TRIGGER"] + /// EVENT_TRIGGER 3838: "event_trigger" => EventTrigger: Kind::Simple } @@ -596,7 +594,9 @@ impl error::Error for WasNull { /// nullable Postgres value. pub trait FromSql: Sized { /// ### Deprecated - fn from_sql_nullable(ty: &Type, raw: Option<&mut R>, ctx: &SessionInfo) + fn from_sql_nullable(ty: &Type, + raw: Option<&mut R>, + ctx: &SessionInfo) -> Result { match raw { Some(raw) => FromSql::from_sql(ty, raw, ctx), @@ -704,7 +704,9 @@ primitive_from!(f32, read_f32, Type::Float4); primitive_from!(f64, read_f64, Type::Float8); impl FromSql for HashMap> { - fn from_sql(_: &Type, raw: &mut R, _: &SessionInfo) + fn from_sql(_: &Type, + raw: &mut R, + _: &SessionInfo) -> Result>> { let mut map = HashMap::new(); @@ -740,7 +742,7 @@ impl FromSql for HashMap> { fn accepts(ty: &Type) -> bool { match *ty { Type::Other(ref u) if u.name() == "hstore" => true, - _ => false + _ => false, } } } @@ -811,7 +813,8 @@ pub trait ToSql: fmt::Debug { /// `NULL`. If this is the case, implementations **must not** write /// anything to `out`. fn to_sql(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) -> Result - where Self: Sized, W: Write; + where Self: Sized, + W: Write; /// Determines if a value of this type can be converted to the specified /// Postgres `Type`. @@ -821,34 +824,33 @@ pub trait ToSql: fmt::Debug { /// /// *All* implementations of this method should be generated by the /// `to_sql_checked!()` macro. - fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) - -> Result; + fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) -> Result; } impl<'a, T> ToSql for &'a T where T: ToSql { - fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) - -> Result { - if !<&'a T as ToSql>::accepts(ty) { - return Err(Error::WrongType(ty.clone())); - } - self.to_sql(ty, out, ctx) - } + to_sql_checked!(); - - fn to_sql(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) -> Result { + fn to_sql(&self, + ty: &Type, + out: &mut W, + ctx: &SessionInfo) + -> Result { (*self).to_sql(ty, out, ctx) } - fn accepts(ty: &Type) -> bool { T::accepts(ty) } + fn accepts(ty: &Type) -> bool { + T::accepts(ty) + } } - - impl ToSql for Option { to_sql_checked!(); - fn to_sql(&self, ty: &Type, out: &mut W, ctx: &SessionInfo) - -> Result { + fn to_sql(&self, + ty: &Type, + out: &mut W, + ctx: &SessionInfo) + -> Result { match *self { Some(ref val) => val.to_sql(ty, out, ctx), None => Ok(IsNull::Yes), @@ -863,8 +865,11 @@ impl ToSql for Option { impl ToSql for bool { to_sql_checked!(); - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { try!(w.write_u8(*self as u8)); Ok(IsNull::No) } @@ -873,17 +878,9 @@ impl ToSql for bool { } impl<'a> ToSql for &'a [u8] { - // FIXME should use to_sql_checked!() but blocked on rust-lang/rust#24308 - fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) - -> Result { - if !<&'a [u8] as ToSql>::accepts(ty) { - return Err(Error::WrongType(ty.clone())); - } - self.to_sql(ty, out, ctx) - } + to_sql_checked!(); - fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) -> Result { try!(w.write_all(*self)); Ok(IsNull::No) } @@ -894,8 +891,7 @@ impl<'a> ToSql for &'a [u8] { impl ToSql for Vec { to_sql_checked!(); - fn to_sql(&self, ty: &Type, w: &mut W, ctx: &SessionInfo) - -> Result { + fn to_sql(&self, ty: &Type, w: &mut W, ctx: &SessionInfo) -> Result { <&[u8] as ToSql>::to_sql(&&**self, ty, w, ctx) } @@ -905,17 +901,9 @@ impl ToSql for Vec { } impl<'a> ToSql for &'a str { - // FIXME should use to_sql_checked!() but blocked on rust-lang/rust#24308 - fn to_sql_checked(&self, ty: &Type, out: &mut Write, ctx: &SessionInfo) - -> Result { - if !<&'a str as ToSql>::accepts(ty) { - return Err(Error::WrongType(ty.clone())); - } - self.to_sql(ty, out, ctx) - } + to_sql_checked!(); - fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) -> Result { try!(w.write_all(self.as_bytes())); Ok(IsNull::No) } @@ -932,8 +920,7 @@ impl<'a> ToSql for &'a str { impl ToSql for String { to_sql_checked!(); - fn to_sql(&self, ty: &Type, w: &mut W, ctx: &SessionInfo) - -> Result { + fn to_sql(&self, ty: &Type, w: &mut W, ctx: &SessionInfo) -> Result { <&str as ToSql>::to_sql(&&**self, ty, w, ctx) } @@ -945,8 +932,11 @@ impl ToSql for String { impl ToSql for i8 { to_sql_checked!(); - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { try!(w.write_i8(*self)); Ok(IsNull::No) } @@ -980,8 +970,11 @@ to_primitive!(f64, write_f64, Type::Float8); impl ToSql for HashMap> { to_sql_checked!(); - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { try!(w.write_i32::(try!(downcast(self.len())))); for (key, val) in self { @@ -993,7 +986,7 @@ impl ToSql for HashMap> { try!(w.write_i32::(try!(downcast(val.len())))); try!(w.write_all(val.as_bytes())); } - None => try!(w.write_i32::(-1)) + None => try!(w.write_i32::(-1)), } } @@ -1010,7 +1003,7 @@ impl ToSql for HashMap> { fn downcast(len: usize) -> Result { if len > i32::max_value() as usize { - let err: Box = "value too large to transmit".into(); + let err: Box = "value too large to transmit".into(); Err(Error::Conversion(err)) } else { Ok(len as i32) diff --git a/src/types/rustc_serialize.rs b/src/types/rustc_serialize.rs index f5e9bcf0..fb171fbb 100644 --- a/src/types/rustc_serialize.rs +++ b/src/types/rustc_serialize.rs @@ -12,7 +12,8 @@ impl FromSql for json::Json { if let Type::Jsonb = *ty { // We only support version 1 of the jsonb binary format if try!(raw.read_u8()) != 1 { - let err: Box = "unsupported JSONB encoding version".into(); + let err: Box = "unsupported JSONB encoding version" + .into(); return Err(Error::Conversion(err)); } } @@ -23,8 +24,11 @@ impl FromSql for json::Json { } impl ToSql for json::Json { - fn to_sql(&self, ty: &Type, mut out: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + ty: &Type, + mut out: &mut W, + _: &SessionInfo) + -> Result { if let Type::Jsonb = *ty { try!(out.write_u8(1)); } diff --git a/src/types/serde.rs b/src/types/serde.rs index b5db60fc..82e29b09 100644 --- a/src/types/serde.rs +++ b/src/types/serde.rs @@ -14,7 +14,8 @@ impl FromSql for Value { if let Type::Jsonb = *ty { // We only support version 1 of the jsonb binary format if try!(raw.read_u8()) != 1 { - let err: Box = "unsupported JSONB encoding version".into(); + let err: Box = "unsupported JSONB encoding version" + .into(); return Err(Error::Conversion(err)); } } @@ -25,8 +26,11 @@ impl FromSql for Value { } impl ToSql for Value { - fn to_sql(&self, ty: &Type, mut out: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + ty: &Type, + mut out: &mut W, + _: &SessionInfo) + -> Result { if let Type::Jsonb = *ty { try!(out.write_u8(1)); } diff --git a/src/types/serde_json.rs b/src/types/serde_json.rs index 839d3839..c0e21739 100644 --- a/src/types/serde_json.rs +++ b/src/types/serde_json.rs @@ -14,7 +14,8 @@ impl FromSql for Value { if let Type::Jsonb = *ty { // We only support version 1 of the jsonb binary format if try!(raw.read_u8()) != 1 { - let err: Box = "unsupported JSONB encoding version".into(); + let err: Box = "unsupported JSONB encoding version" + .into(); return Err(Error::Conversion(err)); } } @@ -25,8 +26,11 @@ impl FromSql for Value { } impl ToSql for Value { - fn to_sql(&self, ty: &Type, mut out: &mut W, _: &SessionInfo) - -> Result { + fn to_sql(&self, + ty: &Type, + mut out: &mut W, + _: &SessionInfo) + -> Result { if let Type::Jsonb = *ty { try!(out.write_u8(1)); } diff --git a/src/types/slice.rs b/src/types/slice.rs index 02cb3975..789d3365 100644 --- a/src/types/slice.rs +++ b/src/types/slice.rs @@ -38,7 +38,11 @@ impl<'a, T: 'a + ToSql> ToSql for Slice<'a, T> { self.to_sql(ty, out, ctx) } - fn to_sql(&self, ty: &Type, mut w: &mut W, ctx: &SessionInfo) -> Result { + fn to_sql(&self, + ty: &Type, + mut w: &mut W, + ctx: &SessionInfo) + -> Result { let member_type = match ty.kind() { &Kind::Array(ref member) => member, _ => panic!("expected array type"), diff --git a/src/types/time.rs b/src/types/time.rs index 9abe3e01..ec284402 100644 --- a/src/types/time.rs +++ b/src/types/time.rs @@ -31,7 +31,11 @@ impl FromSql for Timespec { } impl ToSql for Timespec { - fn to_sql(&self, _: &Type, mut w: &mut W, _: &SessionInfo) -> Result { + fn to_sql(&self, + _: &Type, + mut w: &mut W, + _: &SessionInfo) + -> Result { let t = (self.sec - TIME_SEC_CONVERSION) * USEC_PER_SEC + self.nsec as i64 / NSEC_PER_USEC; try!(w.write_i64::(t)); Ok(IsNull::No) diff --git a/src/types/uuid.rs b/src/types/uuid.rs index 4f1c1a57..73cdccf6 100644 --- a/src/types/uuid.rs +++ b/src/types/uuid.rs @@ -18,7 +18,7 @@ impl FromSql for Uuid { } impl ToSql for Uuid { - fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) -> Result { + fn to_sql(&self, _: &Type, w: &mut W, _: &SessionInfo) -> Result { try!(w.write_all(self.as_bytes())); Ok(IsNull::No) } diff --git a/src/url.rs b/src/url.rs index d80c813f..1298afd1 100644 --- a/src/url.rs +++ b/src/url.rs @@ -23,12 +23,12 @@ pub struct Url { pub struct Path { pub path: String, pub query: Query, - pub fragment: Option + pub fragment: Option, } pub struct UserInfo { pub user: String, - pub pass: Option + pub pass: Option, } pub type Query = Vec<(String, String)>; @@ -47,7 +47,7 @@ impl Url { user: user, host: host, port: port, - path: Path::new(path, query, fragment) + path: Path::new(path, query, fragment), } } @@ -66,21 +66,18 @@ impl Url { let (query, fragment) = try!(get_query_fragment(rest)); let url = Url::new(scheme.to_owned(), - userinfo, - host.to_owned(), - port, - path, - query, - fragment); + userinfo, + host.to_owned(), + port, + path, + query, + fragment); Ok(url) } } impl Path { - pub fn new(path: String, - query: Query, - fragment: Option) - -> Path { + pub fn new(path: String, query: Query, fragment: Option) -> Path { Path { path: path, query: query, @@ -94,14 +91,21 @@ impl Path { // query and fragment let (query, fragment) = try!(get_query_fragment(&rest)); - Ok(Path{ path: path, query: query, fragment: fragment }) + Ok(Path { + path: path, + query: query, + fragment: fragment, + }) } } impl UserInfo { #[inline] pub fn new(user: String, pass: Option) -> UserInfo { - UserInfo { user: user, pass: pass } + UserInfo { + user: user, + pass: pass, + } } } @@ -121,28 +125,40 @@ fn decode_inner(c: &str, full_url: bool) -> DecodeResult { '%' => { let bytes = match (iter.next(), iter.next()) { (Some(one), Some(two)) => [one, two], - _ => return Err(format!("Malformed input: found '%' \ - without two trailing bytes")), + _ => return Err(format!("Malformed input: found '%' without two \ + trailing bytes")), }; // Only decode some characters if full_url: match str::from_utf8(&bytes).unwrap().from_hex().unwrap()[0] as char { // gen-delims: - ':' | '/' | '?' | '#' | '[' | ']' | '@' | - - // sub-delims: - '!' | '$' | '&' | '"' | '(' | ')' | '*' | - '+' | ',' | ';' | '=' - if full_url => { + ':' | + '/' | + '?' | + '#' | + '[' | + ']' | + '@' | + '!' | + '$' | + '&' | + '"' | + '(' | + ')' | + '*' | + '+' | + ',' | + ';' | + '=' if full_url => { out.push('%'); out.push(bytes[0] as char); out.push(bytes[1] as char); } - ch => out.push(ch) + ch => out.push(ch), } } - ch => out.push(ch) + ch => out.push(ch), }, None => return Ok(out), } @@ -160,12 +176,11 @@ fn split_char_first(s: &str, c: char) -> (&str, &str) { } fn query_from_str(rawquery: &str) -> DecodeResult { - let mut query: Query = vec!(); + let mut query: Query = vec![]; if !rawquery.is_empty() { for p in rawquery.split('&') { let (k, v) = split_char_first(p, '='); - query.push((try!(decode_component(k)), - try!(decode_component(v)))); + query.push((try!(decode_component(k)), try!(decode_component(v)))); } } @@ -173,12 +188,14 @@ fn query_from_str(rawquery: &str) -> DecodeResult { } pub fn get_scheme(rawurl: &str) -> DecodeResult<(&str, &str)> { - for (i,c) in rawurl.chars().enumerate() { + for (i, c) in rawurl.chars().enumerate() { let result = match c { - 'A' ... 'Z' - | 'a' ... 'z' => continue, - '0' ... '9' | '+' | '-' | '.' => { - if i != 0 { continue } + 'A'...'Z' | + 'a'...'z' => continue, + '0'...'9' | '+' | '-' | '.' => { + if i != 0 { + continue; + } Err("url: Scheme must begin with a letter.".to_owned()) } @@ -186,7 +203,7 @@ pub fn get_scheme(rawurl: &str) -> DecodeResult<(&str, &str)> { if i == 0 { Err("url: Scheme cannot be empty.".to_owned()) } else { - Ok((&rawurl[0..i], &rawurl[i+1..rawurl.len()])) + Ok((&rawurl[0..i], &rawurl[i + 1..rawurl.len()])) } } _ => Err("url: Invalid character in scheme.".to_owned()), @@ -199,22 +216,21 @@ pub fn get_scheme(rawurl: &str) -> DecodeResult<(&str, &str)> { } // returns userinfo, host, port, and unparsed part, or an error -fn get_authority(rawurl: &str) -> - DecodeResult<(Option, &str, Option, &str)> { +fn get_authority(rawurl: &str) -> DecodeResult<(Option, &str, Option, &str)> { enum State { Start, // starting state PassHostPort, // could be in user or port Ip6Port, // either in ipv6 host or port Ip6Host, // are in an ipv6 host InHost, // are in a host - may be ipv6, but don't know yet - InPort // are in port + InPort, // are in port } #[derive(Clone, PartialEq)] enum Input { Digit, // all digits Hex, // digits and letters a-f - Unreserved // all other legal characters + Unreserved, // all other legal characters } if !rawurl.starts_with("//") { @@ -235,23 +251,35 @@ fn get_authority(rawurl: &str) -> let mut begin = 2; let mut end = len; - for (i,c) in rawurl.chars().enumerate() - // ignore the leading '//' handled by early return - .skip(2) { + for (i, c) in rawurl.chars() + .enumerate() + .skip(2) { // deal with input class first match c { - '0' ... '9' => (), - 'A' ... 'F' - | 'a' ... 'f' => { + '0'...'9' => (), + 'A'...'F' | + 'a'...'f' => { if input == Input::Digit { input = Input::Hex; } } - 'G' ... 'Z' - | 'g' ... 'z' - | '-' | '.' | '_' | '~' | '%' - | '&' |'\'' | '(' | ')' | '+' - | '!' | '*' | ',' | ';' | '=' => input = Input::Unreserved, + 'G'...'Z' | + 'g'...'z' | + '-' | + '.' | + '_' | + '~' | + '%' | + '&' | + '\'' | + '(' | + ')' | + '+' | + '!' | + '*' | + ',' | + ';' | + '=' => input = Input::Unreserved, ':' | '@' | '?' | '#' | '/' => { // separators, don't change anything } @@ -260,97 +288,96 @@ fn get_authority(rawurl: &str) -> // now process states match c { - ':' => { - colon_count += 1; - match st { - State::Start => { - pos = i; - st = State::PassHostPort; - } - State::PassHostPort => { - // multiple colons means ipv6 address. - if input == Input::Unreserved { - return Err( - "Illegal characters in IPv6 address.".to_owned()); + ':' => { + colon_count += 1; + match st { + State::Start => { + pos = i; + st = State::PassHostPort; + } + State::PassHostPort => { + // multiple colons means ipv6 address. + if input == Input::Unreserved { + return Err("Illegal characters in IPv6 address.".to_owned()); + } + st = State::Ip6Host; + } + State::InHost => { + pos = i; + if input == Input::Unreserved { + // must be port + host = &rawurl[begin..i]; + st = State::InPort; + } else { + // can't be sure whether this is an ipv6 address or a port + st = State::Ip6Port; + } + } + State::Ip6Port => { + if input == Input::Unreserved { + return Err("Illegal characters in authority.".to_owned()); + } + st = State::Ip6Host; + } + State::Ip6Host => { + if colon_count > 7 { + host = &rawurl[begin..i]; + pos = i; + st = State::InPort; + } + } + _ => return Err("Invalid ':' in authority.".to_owned()), } - st = State::Ip6Host; - } - State::InHost => { - pos = i; - if input == Input::Unreserved { - // must be port - host = &rawurl[begin..i]; - st = State::InPort; - } else { - // can't be sure whether this is an ipv6 address or a port - st = State::Ip6Port; - } - } - State::Ip6Port => { - if input == Input::Unreserved { - return Err("Illegal characters in authority.".to_owned()); - } - st = State::Ip6Host; - } - State::Ip6Host => { - if colon_count > 7 { - host = &rawurl[begin..i]; - pos = i; - st = State::InPort; - } - } - _ => return Err("Invalid ':' in authority.".to_owned()), + input = Input::Digit; // reset input class } - input = Input::Digit; // reset input class - } - '@' => { - input = Input::Digit; // reset input class - colon_count = 0; // reset count - match st { - State::Start => { - let user = try!(decode_component(&rawurl[begin..i])); - userinfo = Some(UserInfo::new(user, None)); - st = State::InHost; - } - State::PassHostPort => { - let user = try!(decode_component(&rawurl[begin..pos])); - let pass = try!(decode_component(&rawurl[pos+1..i])); - userinfo = Some(UserInfo::new(user, Some(pass))); - st = State::InHost; - } - _ => return Err("Invalid '@' in authority.".to_owned()), + '@' => { + input = Input::Digit; // reset input class + colon_count = 0; // reset count + match st { + State::Start => { + let user = try!(decode_component(&rawurl[begin..i])); + userinfo = Some(UserInfo::new(user, None)); + st = State::InHost; + } + State::PassHostPort => { + let user = try!(decode_component(&rawurl[begin..pos])); + let pass = try!(decode_component(&rawurl[pos + 1..i])); + userinfo = Some(UserInfo::new(user, Some(pass))); + st = State::InHost; + } + _ => return Err("Invalid '@' in authority.".to_owned()), + } + begin = i + 1; } - begin = i+1; - } - '?' | '#' | '/' => { - end = i; - break; - } - _ => () + '?' | '#' | '/' => { + end = i; + break; + } + _ => (), } } // finish up match st { - State::Start => host = &rawurl[begin..end], - State::PassHostPort - | State::Ip6Port => { - if input != Input::Digit { - return Err("Non-digit characters in port.".to_owned()); + State::Start => host = &rawurl[begin..end], + State::PassHostPort | + State::Ip6Port => { + if input != Input::Digit { + return Err("Non-digit characters in port.".to_owned()); + } + host = &rawurl[begin..pos]; + port = Some(&rawurl[pos + 1..end]); } - host = &rawurl[begin..pos]; - port = Some(&rawurl[pos+1..end]); - } - State::Ip6Host - | State::InHost => host = &rawurl[begin..end], - State::InPort => { - if input != Input::Digit { - return Err("Non-digit characters in port.".to_owned()); + State::Ip6Host | + State::InHost => host = &rawurl[begin..end], + State::InPort => { + if input != Input::Digit { + return Err("Non-digit characters in port.".to_owned()); + } + port = Some(&rawurl[pos + 1..end]); } - port = Some(&rawurl[pos+1..end]); - } } let rest = &rawurl[end..len]; @@ -359,8 +386,8 @@ fn get_authority(rawurl: &str) -> None => None, opt => match opt.and_then(|p| FromStr::from_str(p).ok()) { None => return Err(format!("Failed to parse port: {:?}", port)), - opt => opt - } + opt => opt, + }, }; Ok((userinfo, host, port, rest)) @@ -371,26 +398,39 @@ fn get_authority(rawurl: &str) -> fn get_path(rawurl: &str, is_authority: bool) -> DecodeResult<(String, &str)> { let len = rawurl.len(); let mut end = len; - for (i,c) in rawurl.chars().enumerate() { + for (i, c) in rawurl.chars().enumerate() { match c { - 'A' ... 'Z' - | 'a' ... 'z' - | '0' ... '9' - | '&' |'\'' | '(' | ')' | '.' - | '@' | ':' | '%' | '/' | '+' - | '!' | '*' | ',' | ';' | '=' - | '_' | '-' | '~' => continue, - '?' | '#' => { - end = i; - break; - } - _ => return Err("Invalid character in path.".to_owned()) + 'A'...'Z' | + 'a'...'z' | + '0'...'9' | + '&' | + '\'' | + '(' | + ')' | + '.' | + '@' | + ':' | + '%' | + '/' | + '+' | + '!' | + '*' | + ',' | + ';' | + '=' | + '_' | + '-' | + '~' => continue, + '?' | '#' => { + end = i; + break; + } + _ => return Err("Invalid character in path.".to_owned()), } } if is_authority && end != 0 && !rawurl.starts_with("/") { - Err("Non-empty path must begin with \ - '/' in presence of authority.".to_owned()) + Err("Non-empty path must begin with '/' in presence of authority.".to_owned()) } else { Ok((try!(decode_component(&rawurl[0..end])), &rawurl[end..len])) } @@ -403,12 +443,12 @@ fn get_query_fragment(rawurl: &str) -> DecodeResult<(Query, Option)> { // Parse the fragment if available let fragment = match raw_fragment { "" => None, - raw => Some(try!(decode_component(raw))) + raw => Some(try!(decode_component(raw))), }; match before_fragment.chars().next() { Some('?') => Ok((try!(query_from_str(&before_fragment[1..])), fragment)), - None => Ok((vec!(), fragment)), + None => Ok((vec![], fragment)), _ => Err(format!("Query didn't start with '?': '{}..'", before_fragment)), } } @@ -426,4 +466,3 @@ impl FromStr for Path { Path::parse(s) } } -