1use std::sync::Arc;
2
3use crate::buffer_pool::{BufferPool, GLOBAL_BUFFER_POOL};
4use crate::constant::{CapabilityFlags, CAPABILITIES_ALWAYS_ENABLED};
5use crate::error::Error;
6
7#[derive(Debug, Clone)]
17pub struct Opts {
18 pub tcp_nodelay: bool,
21
22 pub capabilities: CapabilityFlags,
25
26 pub compress: bool,
28
29 pub db: Option<String>,
31
32 pub host: Option<String>,
34
35 pub port: u16,
37
38 pub socket: Option<String>,
40
41 pub user: String,
43
44 pub password: Option<String>,
45
46 pub tls: bool,
47
48 pub upgrade_to_unix_socket: bool,
50
51 pub init_command: Option<String>,
53
54 pub buffer_pool: Arc<BufferPool>,
55}
56
57impl Default for Opts {
58 fn default() -> Self {
59 Self {
60 tcp_nodelay: true,
61 capabilities: CAPABILITIES_ALWAYS_ENABLED,
62 compress: false,
63 db: None,
64 host: None,
65 port: 3306,
66 socket: None,
67 user: String::new(),
68 password: None,
69 tls: false,
70 upgrade_to_unix_socket: true,
71 init_command: None,
72 buffer_pool: Arc::clone(&GLOBAL_BUFFER_POOL),
73 }
74 }
75}
76
77impl TryFrom<&str> for Opts {
78 type Error = Error;
79
80 fn try_from(url: &str) -> Result<Self, Self::Error> {
81 let parsed = url::Url::parse(url)
83 .map_err(|e| Error::BadConfigError(format!("Failed to parse MySQL URL: {}", e)))?;
84
85 if parsed.scheme() != "mysql" {
87 return Err(Error::BadConfigError(format!(
88 "Invalid URL scheme '{}', expected 'mysql'",
89 parsed.scheme()
90 )));
91 }
92
93 let host = parsed.host_str().map(ToString::to_string);
95 let port = parsed.port().unwrap_or(3306);
96
97 let user = parsed.username().to_string();
99
100 let password = parsed.password().map(ToString::to_string);
102
103 let db = parsed
105 .path()
106 .strip_prefix('/')
107 .filter(|db| !db.is_empty())
108 .map(ToString::to_string);
109
110 Ok(Self {
111 host,
112 port,
113 user,
114 password,
115 db,
116 ..Default::default()
117 })
118 }
119}