mysql 1.2.0

Mysql client library implemented in rust
Documentation
use std::path::PathBuf;
use std::net::SocketAddr;
use std::net::ToSocketAddrs;

type ParseResult<T> = Result<T, Error>;

enum Error {
    InvalidProtocol,
}

enum ParseState {
    ParseDsnProto,
    ParseDsnHost,
    ParseDsnPath,
    ParseDsnParams,
}

enum ParseDsnProtoState {
    ParseName,
    ParseColon,
    ParseSlash,
}

enum ParseUserPassState {
    SearchAt,
}

pub struct ParsedDsn {
    tcp_addr: SocketAddr,
    user: Option<String>,
    pass: Option<String>,
    db_name: Option<String>,
    prefer_socket: bool,
    #[cfg(feature = "ssl")]
    verify_peer: bool,
    #[cfg(feature = "ssl")]
    ssl_opts: Option<(PathBuf, Option<(PathBuf, PathBuf)>)>,
}

static valid_protocols: [&'static str; 1] = ["mysql"];
static valid_params: [&'static str; 5] =
    ["prefer_socket", "verify_peer", "ca_cert", "client_cert", "client_key"];

fn parse_proto(mut pos: usize, dsn: &str) -> ParseResult<(usize, String)> {
    let mut state = ParseDsnProtoState::ParseName;
    let mut proto = String::new();
    for c in &dsn[pos..].chars() {
        pos += 1;
        match c {
            'a' ... 'z' => {
                match state {
                    ParseDsnProtoState::ParseName => proto.push(c),
                    _ => return Err(Error::InvalidProtocol),
                }
            },
            ':' => {
                match state {
                    ParseDsnProtoState::ParseName => state = ParseDsnProtoState::ParseColon,
                    _ => return Err(Error::InvalidProtocol),
                }
            },
            '/' => {
                match state {
                    ParseDsnProtoState::ParseName => return Err(Error::InvalidProtocol),
                    ParseDsnProtoState::ParseColon => state = ParseDsnProtoState::ParseSlash,
                    ParseDsnProtoState::ParseSlash => break,
                }
            },
            _ => {
                return Err(Error::InvalidProtocol)
            }
        }
    }
    Ok((pos, proto))
}

fn parse_user_pass(mut pos: usize, dsn: &str) -> ParseResult<(Option<(String, Option<String>)>)> {

}

pub fn parse<A: AsRef<str>>(dsn: A) -> ParseResult<ParsedDsn> {
    let mut state = ParseState::ParseDsnProto;
    let pos = 0;
    let (pos, proto) = try!(parse_proto(pos, dsn.as_ref()));
    unimplemented!();
}