mdsn 0.2.25

M-DSN: A Multi-address DSN(Data Source Name) parser.
Documentation
char = { ASCII_ALPHANUMERIC | "." | "_" | "-" }

encoded_char = { ASCII_ALPHANUMERIC | "%" }

driver = { char* }
protocol = { char+ }
SCHEME_IDENT = { "://" }

scheme = { driver ~ ("+" ~ protocol)? }

username = { char+ }
password = { char+ }
with_password = { ":" ~ password? }
username_with_password = { username? ~ (":" ~ password)? ~ "@" }

nondot = { ASCII_ALPHANUMERIC | "-" | "|" }
host = { nondot+ ~ ("." ~ nondot+)* }
port = { ASCII_DIGIT+ }
// url encoded path
path = { "%" ~ (char | "%" | "+" )+ }
address = { path | host ~ (":" ~ port?)? | ":" ~ port | ":" }
addresses = { address? ~ ("," ~ address)* }
paths = { path | ("," ~ path)}

fchar = { char | ":" }
fragment = { "./" ~ fchar+  ~ ("/" ~ fchar+)? | ("/" ~ fchar+) ~ ("/" ~ fchar+)+ }
path_like = { (fchar | "/" )+ }

protocol_with_addresses = { protocol ~ "(" ~ addresses ~ ")" | addresses }

name = { char+ }
varchar = { ASCII_ALPHANUMERIC | "." | "_" | "-" | "%" | "," | " " | "*" }
value = { varchar* }
param = { name ~ "=" ~ value }

database_char = { nondot | "," | "." | "_" }
database = { database_char+ }

dsn = {
  SOI ~
  scheme ~ (SCHEME_IDENT ~
      username_with_password* ~ protocol_with_addresses ~ (fragment | "/" ~ database?)? | ":" ~ path_like)
     ~ ("?" ~ param ~ ("&" ~ param)*)? ~
  EOI
}