cdbc_mssql/options/
parse.rs

1
2use crate::MssqlConnectOptions;
3use percent_encoding::percent_decode_str;
4use std::str::FromStr;
5use url::Url;
6use cdbc::Error;
7
8impl FromStr for MssqlConnectOptions {
9    type Err = Error;
10
11    fn from_str(s: &str) -> Result<Self, Self::Err> {
12        let url: Url = s.parse().map_err(Error::config)?;
13        let mut options = Self::new();
14
15        if let Some(host) = url.host_str() {
16            options = options.host(host);
17        }
18
19        if let Some(port) = url.port() {
20            options = options.port(port);
21        }
22
23        let username = url.username();
24        if !username.is_empty() {
25            options = options.username(
26                &*percent_decode_str(username)
27                    .decode_utf8()
28                    .map_err(Error::config)?,
29            );
30        }
31
32        if let Some(password) = url.password() {
33            options = options.password(
34                &*percent_decode_str(password)
35                    .decode_utf8()
36                    .map_err(Error::config)?,
37            );
38        }
39
40        let path = url.path().trim_start_matches('/');
41        if !path.is_empty() {
42            options = options.database(path);
43        }
44
45        Ok(options)
46    }
47}
48
49#[test]
50fn it_parses_username_with_at_sign_correctly() {
51    let uri = "mysql://user@hostname:password@hostname:5432/database";
52    let opts = MssqlConnectOptions::from_str(uri).unwrap();
53
54    assert_eq!("user@hostname", &opts.username);
55}
56
57#[test]
58fn it_parses_password_with_non_ascii_chars_correctly() {
59    let uri = "mysql://username:p@ssw0rd@hostname:5432/database";
60    let opts = MssqlConnectOptions::from_str(uri).unwrap();
61
62    assert_eq!(Some("p@ssw0rd".into()), opts.password);
63}