alpm_compress/tarball/
builder.rs1use std::{fmt, fmt::Debug, fs::File};
4
5use fluent_i18n::t;
6use tar::Builder;
7
8use crate::{
9 Error,
10 compression::{CompressionEncoder, CompressionSettings},
11};
12
13pub struct TarballBuilder<'c> {
18 inner: Builder<CompressionEncoder<'c>>,
19}
20
21impl Debug for TarballBuilder<'_> {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 f.debug_struct("TarballBuilder")
24 .field("inner", &"Builder<CompressionEncoder>")
25 .finish()
26 }
27}
28
29impl<'c> TarballBuilder<'c> {
30 pub fn new(file: File, settings: &CompressionSettings) -> Result<Self, Error> {
37 CompressionEncoder::new(file, settings).map(Self::from)
38 }
39
40 pub fn inner_mut(&mut self) -> &mut Builder<CompressionEncoder<'c>> {
57 &mut self.inner
58 }
59
60 pub fn finish(self) -> Result<(), Error> {
68 self.inner
69 .into_inner()
70 .map_err(|source| Error::IoWrite {
71 context: t!("error-io-write-archive"),
72 source,
73 })?
74 .finish()?;
75 Ok(())
76 }
77}
78
79impl<'c> From<CompressionEncoder<'c>> for TarballBuilder<'c> {
80 fn from(encoder: CompressionEncoder<'c>) -> Self {
82 Self {
83 inner: Builder::new(encoder),
84 }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use std::io::Write;
91
92 use rstest::rstest;
93 use tempfile::{NamedTempFile, tempfile};
94 use testresult::TestResult;
95
96 use super::*;
97 use crate::compression::{
98 Bzip2CompressionLevel,
99 CompressionSettings,
100 GzipCompressionLevel,
101 XzCompressionLevel,
102 ZstdCompressionLevel,
103 ZstdThreads,
104 };
105
106 #[rstest]
107 #[case::bzip2(CompressionSettings::Bzip2 { compression_level: Bzip2CompressionLevel::default() })]
108 #[case::gzip(CompressionSettings::Gzip { compression_level: GzipCompressionLevel::default() })]
109 #[case::xz(CompressionSettings::Xz { compression_level: XzCompressionLevel::default() })]
110 #[case::zstd(CompressionSettings::Zstd { compression_level: ZstdCompressionLevel::default(), threads: ZstdThreads::all() })]
111 #[case::no_compression(CompressionSettings::None)]
112 fn test_tarball_builder_write_file(
113 #[case] compression_settings: CompressionSettings,
114 ) -> TestResult {
115 let mut builder = TarballBuilder::new(tempfile()?, &compression_settings)?;
116 let test_file = NamedTempFile::new()?;
117 {
118 let mut f = test_file.reopen()?;
119 f.write_all(b"alpm4ever")?;
120 f.flush()?;
121 }
122
123 builder
124 .inner_mut()
125 .append_path_with_name(test_file.path(), "testfile")?;
126 builder.finish()?;
127
128 Ok(())
129 }
130
131 #[rstest]
132 #[case::bzip2(CompressionSettings::Bzip2 { compression_level: Bzip2CompressionLevel::default() })]
133 #[case::gzip(CompressionSettings::Gzip { compression_level: GzipCompressionLevel::default() })]
134 #[case::xz(CompressionSettings::Xz { compression_level: XzCompressionLevel::default() })]
135 #[case::zstd(CompressionSettings::Zstd { compression_level: ZstdCompressionLevel::default(), threads: ZstdThreads::all() })]
136 #[case::no_compression(CompressionSettings::None)]
137 fn test_tarball_builder_debug(#[case] compression_settings: CompressionSettings) -> TestResult {
138 let builder = TarballBuilder::new(tempfile()?, &compression_settings)?;
139 let dbg = format!("{:?}", builder);
140 assert!(dbg.contains("TarballBuilder"));
141 Ok(())
142 }
143}