cdbc_mssql/options/
parse.rs1
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}