| Crates.io | dsn |
| lib.rs | dsn |
| version | 1.2.1 |
| created_at | 2019-07-07 10:06:30.611915+00 |
| updated_at | 2025-11-14 12:41:18.258365+00 |
| description | DSN (Data Source Name) parser |
| homepage | https://docs.rs/dsn/latest/dsn/ |
| repository | https://github.com/nbari/dsn |
| max_upload_size | |
| id | 147259 |
| size | 72,324 |
A lightweight, fast, and type-safe Rust library for parsing and building Data Source Name (DSN) strings for databases like MySQL, PostgreSQL, Redis, and more.
percent-encodingAdd this to your Cargo.toml:
[dependencies]
dsn = "1.2"
The general DSN format is:
<driver>://<username>:<password>@<protocol>(<address>)/<database>?param1=value1&...¶mN=valueN
A complete DSN example:
mysql://username:password@tcp(host:port)/dbname?charset=utf8mb4
The address format changes depending on the protocol:
TCP/UDP - host:port format:
postgresql://user:pass@tcp(localhost:5432)/dbname
Unix Domain Sockets - absolute path to socket:
mysql://user@unix(/var/run/mysqld/mysqld.sock)/database
File Paths (SQLite) - absolute file path:
sqlite://@file(/full/unix/path/to/file.db)
Special characters in usernames and passwords are automatically percent-encoded when using the builder API. For parsing, you can manually encode credentials:
# Using jq
echo -n "p@ss:word!" | jq -s -R -r @uri
# Using xxd
echo -n "p@ss:word!" | xxd -p | sed 's/../%&/g'
Result:
mysql://root:p%40ss%3Aword%21@tcp(localhost:3306)/test
use dsn::parse;
let dsn = parse("mysql://user:pass@tcp(localhost:3306)/database?charset=utf8mb4")?;
println!("Driver: {}", dsn.driver);
println!("Host: {}", dsn.host.unwrap());
println!("Port: {}", dsn.port.unwrap());
println!("Database: {}", dsn.database.unwrap());
println!("Charset: {}", dsn.params.get("charset").unwrap());
use dsn::DSNBuilder;
// MySQL
let mysql = DSNBuilder::mysql()
.username("root")
.password("secret")
.host("localhost")
.database("myapp")
.param("charset", "utf8mb4")
.build();
println!("{}", mysql);
// Output: mysql://root:secret@tcp(localhost:3306)/myapp?charset=utf8mb4
// PostgreSQL with SSL
let postgres = DSNBuilder::postgres()
.username("postgres")
.password("admin")
.host("db.example.com")
.database("production")
.param("sslmode", "require")
.build();
// PostgreSQL with SSL disabled (development)
let postgres_dev = DSNBuilder::postgres()
.username("dev")
.password("dev123")
.host("localhost")
.database("dev_db")
.param("sslmode", "disable")
.build();
// Redis
let redis = DSNBuilder::redis()
.host("cache.example.com")
.password("redis-pass")
.database("0")
.build();
// Unix Socket
let socket_dsn = DSNBuilder::mysql()
.username("app")
.socket("/var/run/mysqld/mysqld.sock")
.database("appdb")
.build();
DSN structs implement Display, so you can convert them back to strings:
use dsn::parse;
let original = "mysql://root:pass@tcp(localhost:3306)/db";
let dsn = parse(original)?;
// Convert back to string
let dsn_string = dsn.to_string();
// or
let dsn_string = format!("{}", dsn);
The library provides descriptive error types:
use dsn::{parse, ParseError};
match parse("invalid://dsn") {
Ok(dsn) => println!("Parsed: {}", dsn.driver),
Err(ParseError::InvalidDriver) => eprintln!("Driver is invalid"),
Err(ParseError::InvalidPort) => eprintln!("Port number is invalid"),
Err(ParseError::MissingHost) => eprintln!("Host is required"),
Err(e) => eprintln!("Parse error: {}", e),
}
Available error types:
InvalidDriver - Driver name is invalid or missingInvalidProtocol - Protocol is invalidInvalidSocket - Unix socket path is invalidInvalidPath - File path is not absoluteInvalidPort - Port number is invalid or out of rangeInvalidParams - Query parameters are malformedMissingAddress - Address is missing after protocolMissingHost - Host is missing in addressUtf8Error - UTF-8 decoding error in credentialsPre-configured builders with sensible defaults:
| Builder | Driver | Default Port | Use Case |
|---|---|---|---|
DSNBuilder::mysql() |
mysql | 3306 | MySQL databases |
DSNBuilder::postgres() |
postgres | 5432 | PostgreSQL databases |
DSNBuilder::redis() |
redis | 6379 | Redis cache/store |
DSNBuilder::mariadb() |
mariadb | 3306 | MariaDB databases |
See the examples directory for comprehensive examples:
# General DSN building examples
cargo run --example builder
# PostgreSQL SSL mode examples
cargo run --example postgres_ssl
Using with the mysql crate:
use dsn::parse;
let dsn = parse("mysql://user:password@tcp(db.example.com)/mydb?tls=skip-verify")?;
let mut opts = mysql::OptsBuilder::new();
opts.user(dsn.username);
opts.pass(dsn.password);
opts.ip_or_hostname(dsn.host);
if let Some(port) = dsn.port {
opts.tcp_port(port);
}
opts.db_name(dsn.database);
let pool = mysql::Pool::new(opts)?;
Using with the postgres crate:
use dsn::DSNBuilder;
let dsn = DSNBuilder::postgres()
.username("postgres")
.password("secret")
.host("localhost")
.database("mydb")
.param("sslmode", "require")
.build();
let client = postgres::Client::connect(&dsn.to_string(), postgres::NoTls)?;
Using with the redis crate:
use dsn::DSNBuilder;
let dsn = DSNBuilder::redis()
.host("localhost")
.password("secret")
.database("0")
.build();
let client = redis::Client::open(dsn.to_string())?;
This crate requires Rust 1.85 or later due to the use of Edition 2024.
Contributions are welcome! Please feel free to submit a Pull Request.
BSD-3-Clause - See LICENSE for details.