rexcli 0.18.4

Replix admin CLI tool
//
// Copyright (c) 2020 RepliXio Ltd. All rights reserved.
// Use is subject to license terms.
//

use serde_json as json;

use crate::latest;

pub(crate) trait Show {
    fn show(self) -> String;
}

impl Show for latest::Realm {
    fn show(self) -> String {
        self.to_string()
    }
}

impl Show for latest::Volume {
    fn show(self) -> String {
        volume(self)
    }
}

impl Show for latest::Replica {
    fn show(self) -> String {
        self.to_string()
    }
}

impl Show for latest::Snapshot {
    fn show(self) -> String {
        self.to_string()
    }
}

impl Show for latest::SnapshotExport {
    fn show(self) -> String {
        self.to_string()
    }
}

impl Show for latest::InternalVersion {
    fn show(self) -> String {
        version(self, false)
    }
}

impl Show for latest::Job {
    fn show(self) -> String {
        job(self).unwrap()
    }
}

impl Show for Vec<latest::Job> {
    fn show(self) -> String {
        jobs(&self).unwrap()
    }
}

pub(crate) fn volume(volume: latest::Volume) -> String {
    let mut out = String::new();

    out += &format!("Volume :{:>60}\n", volume.name);
    out += &format!("Size   :{:>56} GiB\n", volume.size_gb);
    out += &format!("IQN    :{:>60}\n", volume.iqn);
    out += &format!("Status :{:>60}\n", volume.status.value);
    if !volume.description.is_empty() {
        out += &format!("Description:{:>60}\n", volume.description);
    }

    for replica in volume.replicas {
        let primary = if replica.primary {
            String::from("[PRIMARY]")
        } else {
            String::new()
        };
        let realm = match replica.realm {
            latest::ReplicaRealm::Aws { realm, .. } => realm,
            latest::ReplicaRealm::Azure { realm, .. } => realm,
        };
        out += "\n";
        out += &format!("    Replica     :{:>10}{:>37}\n", primary, replica.name);
        out += &format!("    Realm       :{:>47}\n", realm);
        out += &format!("    Status      :{:>47}\n", replica.status.value);
        if let Some(portal) = replica.iscsi_portal {
            out += &format!("    iSCSI Portal:{:>47}\n", portal);
        }
        if !replica.description.is_empty() {
            out += &format!("    Description :{:>47}\n", replica.description);
        }
    }

    out
}

pub(crate) fn version(version: latest::InternalVersion, crates: bool) -> String {
    if crates {
        version.metadata.join("\n")
    } else {
        format!(
            "{}{}{}{}{}{}{}{}",
            format_args!("Release : {}\n", version.release),
            format_args!("Name    : {}\n", version.name),
            format_args!("Vesion  : {}\n", version.version),
            format_args!("Build   : {}\n", version.build),
            format_args!("Branch  : {}\n", version.branch),
            format_args!("Tag:    : {}\n", version.tag),
            format_args!("Commit  : {}\n", version.commit),
            format_args!("Extra   : {}\n", version.extra),
        )
    }
}

pub(crate) fn job(job: latest::Job) -> Result<String, anyhow::Error> {
    let text = json::to_string_pretty(&job)?;
    Ok(text)
}

pub(crate) fn jobs<'a>(
    jobs: impl IntoIterator<Item = &'a latest::Job>,
) -> Result<String, anyhow::Error> {
    let text = jobs
        .into_iter()
        .map(json::to_string_pretty)
        .collect::<Result<Vec<_>, _>>()?
        .join("\n");

    Ok(text)
}