1#[cfg(feature = "sql-browser-tokio")]
2mod tokio;
34#[cfg(feature = "sql-browser-async-std")]
5mod async_std;
67#[cfg(feature = "sql-browser-smol")]
8mod smol;
910use crate::client::Config;
11use async_trait::async_trait;
1213/// An extension trait to a `TcpStream` to find a port and connecting to a
14/// named database instance.
15///
16/// Only needed on Windows platforms, where the server port is not known and the
17/// address is in the form of `hostname\\INSTANCE`.
18#[async_trait]
19pub trait SqlBrowser {
20/// If the given builder defines a named instance, finds the correct port
21 /// and returns a `TcpStream` to be used in the [`Client`]. If instance name
22 /// is not defined, connects directly to the given host and port.
23 ///
24 /// [`Client`]: struct.Client.html
25async fn connect_named(builder: &Config) -> crate::Result<Self>
26where
27Self: Sized + Send + Sync;
28}
2930#[cfg(any(
31 feature = "sql-browser-async-std",
32 feature = "sql-browser-tokio",
33 feature = "sql-browser-smol"
34))]
35fn get_port_from_sql_browser_reply(
36mut buf: Vec<u8>,
37 len: usize,
38 instance_name: &str,
39) -> crate::Result<u16> {
40const DELIMITER: &[u8] = b"tcp;";
4142 buf.truncate(len);
4344let err = crate::Error::Conversion(
45format!("Could not resolve SQL browser instance {}", instance_name).into(),
46 );
4748if len == 0 {
49return Err(err);
50 }
5152let rsp = &buf[3..len];
5354let port: u16 = rsp
55 .windows(DELIMITER.len())
56 .rev()
57 .position(|window| window == DELIMITER)
58 .and_then(|pos| rsp[(rsp.len() - pos)..].split(|item| *item == b';').next())
59 .ok_or(err)
60 .and_then(|val| Ok(std::str::from_utf8(val)?.parse()?))?;
6162Ok(port)
63}