sqlx_core/mysql/options/
parse.rs1use crate::error::Error;
2use crate::mysql::MySqlConnectOptions;
3use percent_encoding::percent_decode_str;
4use std::str::FromStr;
5use url::Url;
6
7impl FromStr for MySqlConnectOptions {
8 type Err = Error;
9
10 fn from_str(s: &str) -> Result<Self, Error> {
11 let url: Url = s.parse().map_err(Error::config)?;
12 let mut options = Self::new();
13
14 if let Some(host) = url.host_str() {
15 options = options.host(host);
16 }
17
18 if let Some(port) = url.port() {
19 options = options.port(port);
20 }
21
22 let username = url.username();
23 if !username.is_empty() {
24 options = options.username(
25 &*percent_decode_str(username)
26 .decode_utf8()
27 .map_err(Error::config)?,
28 );
29 }
30
31 if let Some(password) = url.password() {
32 options = options.password(
33 &*percent_decode_str(password)
34 .decode_utf8()
35 .map_err(Error::config)?,
36 );
37 }
38
39 let path = url.path().trim_start_matches('/');
40 if !path.is_empty() {
41 options = options.database(path);
42 }
43
44 for (key, value) in url.query_pairs().into_iter() {
45 match &*key {
46 "ssl-mode" => {
47 options = options.ssl_mode(value.parse().map_err(Error::config)?);
48 }
49
50 "ssl-ca" => {
51 options = options.ssl_ca(&*value);
52 }
53
54 "charset" => {
55 options = options.charset(&*value);
56 }
57
58 "collation" => {
59 options = options.collation(&*value);
60 }
61
62 "statement-cache-capacity" => {
63 options =
64 options.statement_cache_capacity(value.parse().map_err(Error::config)?);
65 }
66
67 "socket" => {
68 options = options.socket(&*value);
69 }
70
71 _ => {}
72 }
73 }
74
75 Ok(options)
76 }
77}
78
79#[test]
80fn it_parses_username_with_at_sign_correctly() {
81 let url = "mysql://user@hostname:password@hostname:5432/database";
82 let opts = MySqlConnectOptions::from_str(url).unwrap();
83
84 assert_eq!("user@hostname", &opts.username);
85}
86
87#[test]
88fn it_parses_password_with_non_ascii_chars_correctly() {
89 let url = "mysql://username:p@ssw0rd@hostname:5432/database";
90 let opts = MySqlConnectOptions::from_str(url).unwrap();
91
92 assert_eq!(Some("p@ssw0rd".into()), opts.password);
93}