1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//! 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<String>,
}
/// 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<u16>,
/// The user to login as.
///
/// `Connection::connect` requires a user but `cancel_query` does not.
pub user: Option<UserInfo>,
/// The database to connect to.
///
/// Defaults the value of `user`.
pub database: Option<String>,
/// 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<ConnectParams, Box<Error + Sync + Send>>;
}
impl IntoConnectParams for ConnectParams {
fn into_connect_params(self) -> Result<ConnectParams, Box<Error + Sync + Send>> {
Ok(self)
}
}
impl<'a> IntoConnectParams for &'a str {
fn into_connect_params(self) -> Result<ConnectParams, Box<Error + Sync + Send>> {
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<ConnectParams, Box<Error + Sync + Send>> {
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,
})
}
}