dok 0.2.0

A Docker Registry CLI
use std::env;
use std::fs;

use serde_json;

use DokError;
use DokResult;

#[derive(Deserialize)]
struct DockerAuths {
    auths: serde_json::Map<String, serde_json::Value>,
}

// Given a Docker registry host name, tries to find credentials in
// ~/.docker/config.json
pub fn get(host: &str) -> DokResult<String> {
    let auths = read()?.auths;

    let try_keys = vec![host.to_string(), format!("http://{}", host), format!("https://{}", host)];
    for try_key in &try_keys {
        if !auths.contains_key(try_key) {
            continue;
        }

        let tried = match auths[try_key] {
            serde_json::Value::Object(ref t) => t,
            _ => continue,
        };

        if tried.contains_key("auth") {
            match tried["auth"] {
                serde_json::Value::String(ref s) => return Ok(s.to_string()),
                _ => {}
            }
        }
    }

    Err(DokError::new(&format!("No credentials found for host {}", host)))
}

fn read() -> DokResult<DockerAuths> {
    let home = match env::home_dir() {
        Some(path) => path,
        None => return Err(DokError::new("Could not find home directory!")),
    };

    let f = fs::File::open(format!("{}/.docker/config.json", home.display()))?;
    Ok(serde_json::from_reader(f)?)
}