this repo has no description
1use super::stream::{copy_stream, guard_file_output, open_input, prepare_output};
2use crate::{
3 progress::ProgressArgs,
4 utils::{
5 CmprssInput, CmprssOutput, CommonArgs, CompressionLevelValidator, Compressor,
6 DefaultCompressionValidator, LevelArgs, Result,
7 },
8};
9use clap::Args;
10use xz2::read::XzDecoder;
11use xz2::write::XzEncoder;
12
13#[derive(Args, Debug)]
14pub struct XzArgs {
15 #[clap(flatten)]
16 pub common_args: CommonArgs,
17
18 #[clap(flatten)]
19 progress_args: ProgressArgs,
20
21 #[clap(flatten)]
22 pub level_args: LevelArgs,
23}
24
25#[derive(Clone)]
26pub struct Xz {
27 pub level: i32,
28 pub progress_args: ProgressArgs,
29}
30
31impl Default for Xz {
32 fn default() -> Self {
33 let validator = DefaultCompressionValidator;
34 Xz {
35 level: validator.default_level(),
36 progress_args: ProgressArgs::default(),
37 }
38 }
39}
40
41impl Xz {
42 pub fn new(args: &XzArgs) -> Xz {
43 Xz {
44 level: args.level_args.resolve(&DefaultCompressionValidator),
45 progress_args: args.progress_args,
46 }
47 }
48}
49
50impl Compressor for Xz {
51 /// The standard extension for the xz format.
52 fn extension(&self) -> &str {
53 "xz"
54 }
55
56 /// Full name for xz.
57 fn name(&self) -> &str {
58 "xz"
59 }
60
61 fn compress(&self, input: CmprssInput, output: CmprssOutput) -> Result {
62 guard_file_output(&output, "Xz")?;
63 let (input_stream, file_size, pipeline_inner) = open_input(input, "Xz")?;
64 let (writer, target) = prepare_output(output)?;
65 let mut encoder = XzEncoder::new(writer, self.level as u32);
66 copy_stream(
67 input_stream,
68 &mut encoder,
69 file_size,
70 pipeline_inner,
71 &self.progress_args,
72 target,
73 )?;
74 encoder.finish()?;
75 Ok(())
76 }
77
78 fn extract(&self, input: CmprssInput, output: CmprssOutput) -> Result {
79 guard_file_output(&output, "Xz")?;
80 let (input_stream, file_size, pipeline_inner) = open_input(input, "Xz")?;
81 let decoder = XzDecoder::new(input_stream);
82 let (writer, target) = prepare_output(output)?;
83 copy_stream(
84 decoder,
85 writer,
86 file_size,
87 pipeline_inner,
88 &self.progress_args,
89 target,
90 )?;
91 Ok(())
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98 use crate::test_utils::*;
99
100 /// Test the basic interface of the Xz compressor
101 #[test]
102 fn test_xz_interface() {
103 let compressor = Xz::default();
104 test_compressor_interface(&compressor, "xz", Some("xz"));
105 }
106
107 /// Test the default compression level
108 #[test]
109 fn test_xz_default_compression() -> Result {
110 let compressor = Xz::default();
111 test_compression(&compressor)
112 }
113
114 /// Test fast compression level
115 #[test]
116 fn test_xz_fast_compression() -> Result {
117 let fast_compressor = Xz {
118 level: 1,
119 progress_args: ProgressArgs::default(),
120 };
121 test_compression(&fast_compressor)
122 }
123
124 /// Test best compression level
125 #[test]
126 fn test_xz_best_compression() -> Result {
127 let best_compressor = Xz {
128 level: 9,
129 progress_args: ProgressArgs::default(),
130 };
131 test_compression(&best_compressor)
132 }
133}