this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add a progress bar to xz

+246 -9
+132
Cargo.lock
··· 209 209 "bzip2", 210 210 "clap", 211 211 "flate2", 212 + "indicatif", 212 213 "is-terminal", 213 214 "predicates", 214 215 "tar", ··· 220 221 version = "1.0.0" 221 222 source = "registry+https://github.com/rust-lang/crates.io-index" 222 223 checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" 224 + 225 + [[package]] 226 + name = "console" 227 + version = "0.15.7" 228 + source = "registry+https://github.com/rust-lang/crates.io-index" 229 + checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" 230 + dependencies = [ 231 + "encode_unicode", 232 + "lazy_static", 233 + "libc", 234 + "unicode-width", 235 + "windows-sys 0.45.0", 236 + ] 223 237 224 238 [[package]] 225 239 name = "crc32fast" ··· 282 296 checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" 283 297 284 298 [[package]] 299 + name = "encode_unicode" 300 + version = "0.3.6" 301 + source = "registry+https://github.com/rust-lang/crates.io-index" 302 + checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 303 + 304 + [[package]] 285 305 name = "errno" 286 306 version = "0.3.8" 287 307 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 381 401 ] 382 402 383 403 [[package]] 404 + name = "indicatif" 405 + version = "0.17.7" 406 + source = "registry+https://github.com/rust-lang/crates.io-index" 407 + checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" 408 + dependencies = [ 409 + "console", 410 + "instant", 411 + "number_prefix", 412 + "portable-atomic", 413 + "unicode-width", 414 + ] 415 + 416 + [[package]] 417 + name = "instant" 418 + version = "0.1.12" 419 + source = "registry+https://github.com/rust-lang/crates.io-index" 420 + checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 421 + dependencies = [ 422 + "cfg-if", 423 + ] 424 + 425 + [[package]] 384 426 name = "is-terminal" 385 427 version = "0.4.9" 386 428 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 399 441 dependencies = [ 400 442 "either", 401 443 ] 444 + 445 + [[package]] 446 + name = "lazy_static" 447 + version = "1.4.0" 448 + source = "registry+https://github.com/rust-lang/crates.io-index" 449 + checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 402 450 403 451 [[package]] 404 452 name = "libc" ··· 469 517 ] 470 518 471 519 [[package]] 520 + name = "number_prefix" 521 + version = "0.4.0" 522 + source = "registry+https://github.com/rust-lang/crates.io-index" 523 + checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 524 + 525 + [[package]] 472 526 name = "pkg-config" 473 527 version = "0.3.27" 474 528 source = "registry+https://github.com/rust-lang/crates.io-index" 475 529 checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" 530 + 531 + [[package]] 532 + name = "portable-atomic" 533 + version = "1.6.0" 534 + source = "registry+https://github.com/rust-lang/crates.io-index" 535 + checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" 476 536 477 537 [[package]] 478 538 name = "predicates" ··· 670 730 version = "1.0.12" 671 731 source = "registry+https://github.com/rust-lang/crates.io-index" 672 732 checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 733 + 734 + [[package]] 735 + name = "unicode-width" 736 + version = "0.1.11" 737 + source = "registry+https://github.com/rust-lang/crates.io-index" 738 + checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" 673 739 674 740 [[package]] 675 741 name = "utf8parse" ··· 729 795 730 796 [[package]] 731 797 name = "windows-sys" 798 + version = "0.45.0" 799 + source = "registry+https://github.com/rust-lang/crates.io-index" 800 + checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 801 + dependencies = [ 802 + "windows-targets 0.42.2", 803 + ] 804 + 805 + [[package]] 806 + name = "windows-sys" 732 807 version = "0.48.0" 733 808 source = "registry+https://github.com/rust-lang/crates.io-index" 734 809 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" ··· 747 822 748 823 [[package]] 749 824 name = "windows-targets" 825 + version = "0.42.2" 826 + source = "registry+https://github.com/rust-lang/crates.io-index" 827 + checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 828 + dependencies = [ 829 + "windows_aarch64_gnullvm 0.42.2", 830 + "windows_aarch64_msvc 0.42.2", 831 + "windows_i686_gnu 0.42.2", 832 + "windows_i686_msvc 0.42.2", 833 + "windows_x86_64_gnu 0.42.2", 834 + "windows_x86_64_gnullvm 0.42.2", 835 + "windows_x86_64_msvc 0.42.2", 836 + ] 837 + 838 + [[package]] 839 + name = "windows-targets" 750 840 version = "0.48.5" 751 841 source = "registry+https://github.com/rust-lang/crates.io-index" 752 842 checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" ··· 777 867 778 868 [[package]] 779 869 name = "windows_aarch64_gnullvm" 870 + version = "0.42.2" 871 + source = "registry+https://github.com/rust-lang/crates.io-index" 872 + checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 873 + 874 + [[package]] 875 + name = "windows_aarch64_gnullvm" 780 876 version = "0.48.5" 781 877 source = "registry+https://github.com/rust-lang/crates.io-index" 782 878 checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" ··· 789 885 790 886 [[package]] 791 887 name = "windows_aarch64_msvc" 888 + version = "0.42.2" 889 + source = "registry+https://github.com/rust-lang/crates.io-index" 890 + checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 891 + 892 + [[package]] 893 + name = "windows_aarch64_msvc" 792 894 version = "0.48.5" 793 895 source = "registry+https://github.com/rust-lang/crates.io-index" 794 896 checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" ··· 798 900 version = "0.52.0" 799 901 source = "registry+https://github.com/rust-lang/crates.io-index" 800 902 checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 903 + 904 + [[package]] 905 + name = "windows_i686_gnu" 906 + version = "0.42.2" 907 + source = "registry+https://github.com/rust-lang/crates.io-index" 908 + checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 801 909 802 910 [[package]] 803 911 name = "windows_i686_gnu" ··· 813 921 814 922 [[package]] 815 923 name = "windows_i686_msvc" 924 + version = "0.42.2" 925 + source = "registry+https://github.com/rust-lang/crates.io-index" 926 + checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 927 + 928 + [[package]] 929 + name = "windows_i686_msvc" 816 930 version = "0.48.5" 817 931 source = "registry+https://github.com/rust-lang/crates.io-index" 818 932 checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" ··· 825 939 826 940 [[package]] 827 941 name = "windows_x86_64_gnu" 942 + version = "0.42.2" 943 + source = "registry+https://github.com/rust-lang/crates.io-index" 944 + checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 945 + 946 + [[package]] 947 + name = "windows_x86_64_gnu" 828 948 version = "0.48.5" 829 949 source = "registry+https://github.com/rust-lang/crates.io-index" 830 950 checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" ··· 837 957 838 958 [[package]] 839 959 name = "windows_x86_64_gnullvm" 960 + version = "0.42.2" 961 + source = "registry+https://github.com/rust-lang/crates.io-index" 962 + checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 963 + 964 + [[package]] 965 + name = "windows_x86_64_gnullvm" 840 966 version = "0.48.5" 841 967 source = "registry+https://github.com/rust-lang/crates.io-index" 842 968 checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" ··· 846 972 version = "0.52.0" 847 973 source = "registry+https://github.com/rust-lang/crates.io-index" 848 974 checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 975 + 976 + [[package]] 977 + name = "windows_x86_64_msvc" 978 + version = "0.42.2" 979 + source = "registry+https://github.com/rust-lang/crates.io-index" 980 + checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 849 981 850 982 [[package]] 851 983 name = "windows_x86_64_msvc"
+3 -2
Cargo.toml
··· 11 11 categories = ["command-line-utilities", "compression"] 12 12 13 13 [dependencies] 14 + bzip2 = "0.4.4" 14 15 clap = { version = "4.2.1", features = ["derive"] } 15 16 flate2 = "1.0" 17 + indicatif = "0.17.7" 18 + is-terminal = "0.4" 16 19 tar = "0.4.38" 17 - is-terminal = "0.4" 18 20 xz2 = "0.1.7" 19 - bzip2 = "0.4.4" 20 21 21 22 [dev-dependencies] 22 23 assert_cmd = "2.0.11"
+1
src/main.rs
··· 1 1 mod bzip2; 2 2 mod gzip; 3 + mod progress; 3 4 mod tar; 4 5 mod utils; 5 6 mod xz;
+49
src/progress.rs
··· 1 + use indicatif::{HumanBytes, ProgressBar}; 2 + 3 + /// Progress bar for the compress process 4 + pub struct Progress { 5 + /// The progress bar 6 + bar: ProgressBar, 7 + /// The number of bytes read from the input 8 + input_read: u64, 9 + /// The number of bytes written to the output 10 + output_written: u64, 11 + } 12 + 13 + impl Progress { 14 + /// Create a new progress bar 15 + pub fn new(input_size: Option<u64>) -> Self { 16 + let bar = match input_size { 17 + Some(size) => ProgressBar::new(size), 18 + None => ProgressBar::new_spinner(), 19 + }; 20 + bar.set_style( 21 + indicatif::ProgressStyle::default_bar() 22 + .template("{spinner:.green} [{elapsed_precise}] ({eta}) [{bar:40.cyan/blue}] {bytes}/{total_bytes} => {msg}").unwrap() 23 + .progress_chars("#>-"), 24 + ); 25 + Progress { 26 + bar, 27 + input_read: 0, 28 + output_written: 0, 29 + } 30 + } 31 + 32 + /// Update the progress bar with the number of bytes read from the input 33 + pub fn update_input(&mut self, bytes_read: u64) { 34 + self.input_read = bytes_read; 35 + self.bar.set_position(self.input_read); 36 + } 37 + 38 + /// Update the progress bar with the number of bytes written to the output 39 + pub fn update_output(&mut self, bytes_written: u64) { 40 + self.output_written = bytes_written; 41 + self.bar 42 + .set_message(HumanBytes(self.output_written).to_string()); 43 + } 44 + 45 + /// Finish the progress bar 46 + pub fn finish(&self) { 47 + self.bar.finish(); 48 + } 49 + }
+61 -7
src/xz.rs
··· 1 - use crate::utils::*; 1 + use crate::{progress::Progress, utils::*}; 2 2 use std::{ 3 3 fs::File, 4 4 io::{self, Read, Write}, ··· 27 27 } 28 28 29 29 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 30 + let mut file_size = None; 30 31 let mut input_stream = match input { 31 32 CmprssInput::Path(paths) => { 32 33 if paths.len() > 1 { 33 34 return cmprss_error("only 1 file can be compressed at a time"); 34 35 } 35 - Box::new(File::open(paths[0].as_path())?) 36 + let file = Box::new(File::open(paths[0].as_path())?); 37 + // Get the file size for the progress bar 38 + if let Ok(metadata) = file.metadata() { 39 + file_size = Some(metadata.len()); 40 + } 41 + file 36 42 } 37 43 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 38 44 }; 45 + // We want to use the progress bar unless this is in the middle of a pipe 46 + let mut progress_bar = false; 39 47 let output_stream: Box<dyn Write + Send> = match output { 40 - CmprssOutput::Path(path) => Box::new(File::create(path)?), 48 + CmprssOutput::Path(path) => { 49 + progress_bar = true; 50 + Box::new(File::create(path)?) 51 + } 41 52 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 42 53 }; 43 54 let mut encoder = XzEncoder::new(output_stream, self.level); 44 - io::copy(&mut input_stream, &mut encoder)?; 55 + if progress_bar { 56 + let mut progress = Progress::new(file_size); 57 + // Copy the input to the output in 8k chunks 58 + let mut buffer = [0; 8192]; 59 + loop { 60 + let bytes_read = input_stream.read(&mut buffer)?; 61 + if bytes_read == 0 { 62 + break; 63 + } 64 + encoder.write_all(&buffer[..bytes_read])?; 65 + progress.update_input(encoder.total_in()); 66 + progress.update_output(encoder.total_out()); 67 + } 68 + progress.finish(); 69 + } else { 70 + io::copy(&mut input_stream, &mut encoder)?; 71 + } 45 72 Ok(()) 46 73 } 47 74 48 75 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result<(), io::Error> { 76 + let mut file_size = None; 49 77 let mut input_stream = match input { 50 78 CmprssInput::Path(paths) => { 51 79 if paths.len() > 1 { 52 80 return cmprss_error("only 1 file can be extracted at a time"); 53 81 } 54 - Box::new(File::open(paths[0].as_path())?) 82 + let file = Box::new(File::open(paths[0].as_path())?); 83 + // Get the file size for the progress bar 84 + if let Ok(metadata) = file.metadata() { 85 + file_size = Some(metadata.len()); 86 + } 87 + file 55 88 } 56 89 CmprssInput::Pipe(pipe) => Box::new(pipe) as Box<dyn Read + Send>, 57 90 }; 91 + // We want to use the progress bar unless this is in the middle of a pipe 92 + let mut progress_bar = false; 58 93 let output_stream: Box<dyn Write + Send> = match output { 59 - CmprssOutput::Path(path) => Box::new(File::create(path)?), 94 + CmprssOutput::Path(path) => { 95 + progress_bar = true; 96 + Box::new(File::create(path)?) 97 + } 60 98 CmprssOutput::Pipe(pipe) => Box::new(pipe) as Box<dyn Write + Send>, 61 99 }; 62 100 let mut decoder = XzDecoder::new(output_stream); 63 - io::copy(&mut input_stream, &mut decoder)?; 101 + if progress_bar { 102 + let mut progress = Progress::new(file_size); 103 + // Copy the input to the output in 8k chunks 104 + let mut buffer = [0; 8192]; 105 + loop { 106 + let bytes_read = input_stream.read(&mut buffer)?; 107 + if bytes_read == 0 { 108 + break; 109 + } 110 + decoder.write_all(&buffer[..bytes_read])?; 111 + progress.update_input(decoder.total_in()); 112 + progress.update_output(decoder.total_out()); 113 + } 114 + progress.finish(); 115 + } else { 116 + io::copy(&mut input_stream, &mut decoder)?; 117 + } 64 118 Ok(()) 65 119 } 66 120 }