diff --git a/Cargo.toml b/Cargo.toml index efbee62..84f235b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,15 @@ # Copyright (c) 2015 Aaron Power -# Use of this source code is governed by the MIT license that can be -# found in the LICENSE file. +# Use of this source code is governed by the MIT/APACHE2.0 license that can be +# found in the LICENCE-{APACHE, MIT} file. [package] name = "tokei" -version = "1.5.1" +version = "1.6.0" authors = ["Aaronepower "] repository = "https://github.com/Aaronepower/tokei.git" homepage = "https://aaronepower.github.io/tokei/" license = "MIT/Apache-2.0" readme = "README.md" -description = "Count lines of code within a directory, quickly." +description = "Count your code, quickly." [profile.dev] debug = true diff --git a/src/language.rs b/src/language.rs index efc48cb..fff54dd 100644 --- a/src/language.rs +++ b/src/language.rs @@ -2,9 +2,11 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -use std::cell::RefCell; +use std::cell::{RefCell, RefMut}; use std::fmt; use std::path::PathBuf; +use std::ops::AddAssign; +use stats::Stats; #[derive(Debug, Default)] pub struct Language<'a> { @@ -105,3 +107,23 @@ impl<'a> fmt::Display for Language<'a> { self.code) } } +// Adding languages to the raw total. +impl<'a, 'b> AddAssign<&'b Language<'a>> for Language<'a> { + fn add_assign(&mut self, rhs: &Self) { + self.total += rhs.files.len(); + self.lines += rhs.lines; + self.comments += rhs.comments; + self.blanks += rhs.blanks; + self.code += rhs.code; + } +} + +// Adding a file to the language. +impl<'a> AddAssign for Language<'a> { + fn add_assign(&mut self, rhs: Stats) { + self.lines += rhs.lines; + self.code += rhs.code; + self.comments += rhs.comments; + self.blanks += rhs.blanks; + } +} diff --git a/src/main.rs b/src/main.rs index 196f364..90af90b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ // Copyright (c) 2015 Aaron Power -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. +// Use of this source code is governed by the MIT/APACHE2.0 license that can be +// found in the LICENCE-{APACHE, MIT} file. #[macro_use] extern crate clap; @@ -12,6 +12,7 @@ extern crate walkdir; pub mod macros; pub mod language; pub mod fsutil; +pub mod stats; use std::cell::RefCell; use std::collections::BTreeMap; @@ -240,8 +241,8 @@ fn main() { get_all_files(paths, &languages, ignored_directories); let mut total = Language::new_raw("Total"); - for language in languages.values() { - let mut language = language.borrow_mut(); + for language_ref in languages.values() { + let mut language = language_ref.borrow_mut(); if language.printed { continue; @@ -256,14 +257,16 @@ fn main() { for file in files { let mut contents = String::new(); let is_fortran = language.name.contains("FORTRAN"); + let mut stats = stats::Stats::new(unwrap_opt_cont!(file.to_str())); let _ = unwrap_rs_cont!(unwrap_rs_cont!(File::open(file)) .read_to_string(&mut contents)); let mut is_in_comments = false; let lines = contents.lines(); + if is_blank_lang { - language.code += lines.count(); + stats.code += lines.count(); continue; } @@ -273,10 +276,10 @@ fn main() { } else { line.trim() }; - language.lines += 1; + stats.lines += 1; if line.trim().is_empty() { - language.blanks += 1; + stats.blanks += 1; continue; } @@ -286,7 +289,7 @@ fn main() { if line.starts_with(multi_line) { is_in_comments = true; } else if contains_comments(line, multi_line, multi_line_end) { - language.code += 1; + stats.code += 1; is_in_comments = true; } } @@ -296,7 +299,7 @@ fn main() { if line.contains(language.multi_line_end) { is_in_comments = false; } - language.comments += 1; + stats.comments += 1; continue; } @@ -304,33 +307,34 @@ fn main() { for single in single_comments { if line.starts_with(single) { - language.comments += 1; + stats.comments += 1; continue 'line; } } - language.code += 1; + stats.code += 1; } + + if matches.is_present(FILES) { + println!("{}", stats); + } + + *language += stats; } if !language.is_empty() { language.printed = true; if let None = sort { - println!("{}", *language); if matches.is_present(FILES) { println!("{}", ROW); - for file in &language.files { - println!("{}", unwrap_opt_cont!(file.to_str())); - } + println!("{}", *language); println!("{}", ROW); + } else { + println!("{}", *language); } } } - total.total += language.files.len(); - total.lines += language.lines; - total.comments += language.comments; - total.blanks += language.blanks; - total.code += language.code; + total += &*language; } if let Some(sort_category) = sort { @@ -357,7 +361,9 @@ fn main() { } } - println!("{}", ROW); + if !matches.is_present(FILES) { + println!("{}", ROW); + } println!("{}", total); println!("{}", ROW); } diff --git a/src/stats.rs b/src/stats.rs new file mode 100644 index 0000000..8176faa --- /dev/null +++ b/src/stats.rs @@ -0,0 +1,43 @@ +use std::fmt; + +#[derive(Debug)] +pub struct Stats { + pub name: String, + pub code: usize, + pub blanks: usize, + pub lines: usize, + pub comments: usize, +} + + +impl Stats { + pub fn new>(name: S) -> Self { + Stats { + name: name.into(), + code: 0, + blanks: 0, + lines: 0, + comments: 0, + } + } +} + + +impl fmt::Display for Stats { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let name = if self.name.len() > 24 { + let mut name = String::from("|"); + name.push_str(&self.name[self.name.len() - 24..]); + name + } else { + self.name.clone() + }; + write!(f, + " {: <25} {:>12} {:>12} {:>12} {:>12}", + name, + self.lines, + self.blanks, + self.comments, + self.code) + } +}