subcomponent 0.1.0

A components orchestrator
/*
 * Copyright (c) 2017 Jean Guyomarc'h
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

extern crate getopts;
extern crate std;
extern crate term;

use cmd;
use config;
use compiler;

const PROLOG: &'static str =
"Usage:
    subcomponent status
";

pub struct CmdStatus {
   coloured: bool,
}

impl CmdStatus {
   #[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
   fn print_component_id(&self, t: &mut Box<term::StdoutTerminal>, component: &config::Component) -> Result<(), std::io::Error> {
      if self.coloured {
         t.fg(term::color::YELLOW)?;
         t.attr(term::Attr::Bold)?;
      }
      print!("{}", component.id_get());
      if self.coloured {
         t.reset()?;
      }
      Ok(())
   }

   #[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
   fn print_component_name(&self, t: &mut Box<term::StdoutTerminal>, component: &config::Component) -> Result<(), std::io::Error>  {
      print!(" (");
      if self.coloured {
         t.fg(term::color::BRIGHT_BLUE)?;
         t.attr(term::Attr::Bold)?;
      }
      print!("{}", component.name_get());
      if self.coloured {
         t.reset()?;
      }
      print!(")");
      Ok(())
   }

   #[cfg_attr(feature = "cargo-clippy", allow(borrowed_box))]
   fn print_component_path(&self, t: &mut Box<term::StdoutTerminal>, component: &config::Component) -> Result<(), std::io::Error>  {
      let path = std::path::Path::new(component.path_get());
      let canon_res = std::fs::canonicalize(&path);

      print!("\n  ");
      match canon_res {
         Ok(abs_path) => {
            print!("at: ");
            if self.coloured {
               t.fg(term::color::BRIGHT_BLUE)?;
            }
            println!("{}", abs_path.display());
         },
         Err(_) => {
            if self.coloured {
               t.fg(term::color::BRIGHT_RED)?;
               t.attr(term::Attr::Bold)?;
            }
            println!("Not fetched");
         },
      }

      if self.coloured {
         t.reset()?;
      }
      Ok(())
   }
}

impl cmd::Cmd for CmdStatus {
   fn help(&self, opts: &getopts::Options) {
      println!("{}", opts.usage(PROLOG));
   }

   fn getopts_set(&self, opts: &mut getopts::Options) {
      opts.optflag("", "no-color", "Do not use colors");
   }

   fn getopts_matches_use(&mut self, matches: &getopts::Matches) {
      if matches.opt_present("no-color") {
         self.coloured = false;
      }
   }

   fn run(&self, parser_arg: &Option<compiler::parser::Parser>) -> Result<(), cmd::Error> {
      if let Some(ref parser) = *parser_arg {
         let mut t = term::stdout().unwrap();
         let components = parser.components_get();
         for component in components.iter() {
            let borrowed = component.borrow();

            self.print_component_id(&mut t, &borrowed)?;
            self.print_component_name(&mut t, &borrowed)?;
            self.print_component_path(&mut t, &borrowed)?;
         }
         Ok(())
      } else {
         Err(cmd::Error::NoSubcomponentFile)
      }
   }
}

pub fn new() -> CmdStatus {
   CmdStatus {
      coloured: true,
   }
}