1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
use std::process::Command; use std::path::Path; use std::fs::{self, File}; use std::io::{self, BufReader, Read, Write}; use std::env; use std::ffi::OsString; use libflate::gzip; use tar; #[derive(Debug)] pub struct ExecutionStatus { status: Option< i32 > } impl ExecutionStatus { pub fn is_ok( &self ) -> bool { self.status == Some( 0 ) } } pub trait CommandExt { fn run( &mut self ) -> ExecutionStatus; fn append_to_path< P: AsRef< Path > >( &mut self, path: P ) -> &mut Self; } impl CommandExt for Command { fn run( &mut self ) -> ExecutionStatus { let mut child = match self.spawn() { Ok( child ) => child, Err( _ ) => { return ExecutionStatus { status: None }; } }; let result = child.wait(); let status = result.unwrap().code().unwrap(); ExecutionStatus { status: Some( status ) } } fn append_to_path< P: AsRef< Path > >( &mut self, path: P ) -> &mut Self { let mut paths = env::var_os( "PATH" ).map( |paths| env::split_paths( &paths ).collect() ).unwrap_or( Vec::new() ); paths.push( path.as_ref().into() ); let new_path = env::join_paths( paths ).unwrap(); self.env( "PATH", new_path ); self } } pub fn read< P: AsRef< Path > >( path: P ) -> Result< String, io::Error > { let mut fp = File::open( path.as_ref() )?; let mut output = String::new(); fp.read_to_string( &mut output )?; Ok( output ) } pub fn read_bytes< P: AsRef< Path > >( path: P ) -> Result< Vec< u8 >, io::Error > { let mut fp = File::open( path.as_ref() )?; let mut output = Vec::new(); fp.read_to_end( &mut output )?; Ok( output ) } pub fn write< P: AsRef< Path > >( path: P, string: &str ) -> Result< (), io::Error > { let mut fp = File::create( path )?; fp.write_all( string.as_bytes() )?; Ok( () ) } pub fn has_cmd( cmd: &str ) -> bool { let path = env::var_os( "PATH" ).unwrap_or( OsString::new() ); env::split_paths( &path ).map( |p| { p.join( &cmd ) }).any( |p| { p.exists() }) } pub fn find_cmd< 'a >( cmds: &[ &'a str ] ) -> Option< &'a str > { cmds.into_iter().map( |&s| s ).filter( |&s| has_cmd( s ) ).next() } pub fn unpack< I: AsRef< Path >, O: AsRef< Path > >( input_path: I, output_path: O ) -> Result< (), Box< io::Error > > { let output_path = output_path.as_ref(); let file = fs::File::open( input_path )?; let reader = BufReader::new( file ); let decoder = gzip::Decoder::new( reader )?; let mut archive = tar::Archive::new( decoder ); archive.unpack( output_path )?; Ok(()) }