rbdc-oracle 0.10.0

Oracle driver for rbdc
Documentation
use crate::OracleConnectOptions;
use rbdc::Error;
use std::str::FromStr;
use url::Url;

impl FromStr for OracleConnectOptions {
    type Err = Error;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        let value = value.trim();

        if value.starts_with('{') {
            return serde_json::from_str(value).map_err(|e| Error::from(e.to_string()));
        }

        Self::from_uri(value)
    }
}

impl OracleConnectOptions {
    pub(crate) fn from_uri(uri: &str) -> Result<Self, Error> {
        let parsed = Url::parse(uri).map_err(|e| Error::from(format!("Invalid URL: {e}")))?;

        if parsed.scheme() != "oracle" {
            return Err(Error::from("URL scheme must be 'oracle'"));
        }

        let username = parsed.username().to_owned();
        let password = parsed
            .password()
            .ok_or_else(|| Error::from("Password is required"))?
            .to_owned();
        let host = parsed
            .host_str()
            .ok_or_else(|| Error::from("Host is required"))?;
        let port = parsed.port().unwrap_or(1521);
        let service = parsed.path().trim_start_matches('/');
        let connect_string = if service.is_empty() {
            format!("//{host}:{port}")
        } else {
            format!("//{host}:{port}/{service}")
        };

        let mut options = Self::new();
        options.username = username;
        options.password = password;
        options.connect_string = connect_string;
        Ok(options)
    }
}

#[cfg(test)]
mod tests {
    use crate::OracleConnectOptions;

    #[test]
    fn test_parse_uri() {
        let options: OracleConnectOptions = "oracle://scott:tiger@localhost:1521/XE"
            .parse()
            .expect("oracle uri");
        assert_eq!(options.username, "scott");
        assert_eq!(options.password, "tiger");
        assert_eq!(options.connect_string, "//localhost:1521/XE");
    }

    #[test]
    fn test_parse_json() {
        let options: OracleConnectOptions =
            r#"{"username":"a","password":"b","connect_string":"//localhost/XE"}"#
                .parse()
                .expect("oracle json");
        assert_eq!(options.username, "a");
        assert_eq!(options.password, "b");
        assert_eq!(options.connect_string, "//localhost/XE");
    }
}