//! Connection parameters use std::error::Error; use std::path::PathBuf; use url::{self, Url}; /// Specifies the target server to connect to. #[derive(Clone, Debug)] pub enum ConnectTarget { /// Connect via TCP to the specified host. Tcp(String), /// Connect via a Unix domain socket in the specified directory. /// /// Unix sockets are only supported on Unixy platforms (i.e. not Windows). Unix(PathBuf), } /// Authentication information. #[derive(Clone, Debug)] pub struct UserInfo { /// The username. pub user: String, /// An optional password. pub password: Option, } /// Information necessary to open a new connection to a Postgres server. #[derive(Clone, Debug)] pub struct ConnectParams { /// The target server. pub target: ConnectTarget, /// The target port. /// /// Defaults to 5432 if not specified. pub port: Option, /// The user to login as. /// /// `Connection::connect` requires a user but `cancel_query` does not. pub user: Option, /// The database to connect to. /// /// Defaults the value of `user`. pub database: Option, /// Runtime parameters to be passed to the Postgres backend. pub options: Vec<(String, String)>, } /// 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>; } impl IntoConnectParams for ConnectParams { fn into_connect_params(self) -> Result> { Ok(self) } } impl<'a> IntoConnectParams for &'a str { fn into_connect_params(self) -> Result> { match Url::parse(self) { Ok(url) => url.into_connect_params(), Err(err) => Err(err.into()), } } } impl IntoConnectParams for Url { fn into_connect_params(self) -> Result> { let Url { host, port, user, path: url::Path { mut path, query: options, .. }, .. } = self; let maybe_path = try!(url::decode_component(&host)); let target = if maybe_path.starts_with('/') { ConnectTarget::Unix(PathBuf::from(maybe_path)) } else { ConnectTarget::Tcp(host) }; let user = user.map(|url::UserInfo { user, pass }| { UserInfo { user: user, password: pass, } }); let database = if path.is_empty() { None } else { // path contains the leading / path.remove(0); Some(path) }; Ok(ConnectParams { target: target, port: port, user: user, database: database, options: options, }) } }