arch_pkg_db/text/archive/
xz.rs

1use super::{LoadArchiveError, LoadUncompressedArchiveError, LzmaError};
2use crate::{MultiTextCollection, TextCollection, value::RepositoryName};
3use derive_more::{Display, Error};
4use lzma_rs::xz_decompress;
5use std::io::{BufReader, Read};
6
7/// Error when trying to load data from an xz archive.
8#[derive(Debug, Display, Error)]
9pub enum LoadXzError {
10    #[display("Failed to load the xz archive: {_0}")]
11    Xz(LzmaError),
12    #[display("Failed to extract data from the internal archive: {_0}")]
13    InternalArchive(LoadUncompressedArchiveError),
14}
15
16impl TextCollection {
17    /// Extract an xz archive and add contents from its `desc` files to the text collection.
18    pub fn extend_from_xz<Bytes: Read>(&mut self, bytes: Bytes) -> Result<(), LoadXzError> {
19        let mut buf_reader = BufReader::new(bytes);
20        let mut tar = Vec::new();
21        xz_decompress(&mut buf_reader, &mut tar).map_err(LoadXzError::Xz)?;
22        self.extend_from_uncompressed_archive(&tar)
23            .map_err(LoadXzError::InternalArchive)
24    }
25
26    /// Extract an xz archive and add contents from its `desc` files to the text collection.
27    pub fn add_xz<Bytes: Read>(mut self, bytes: Bytes) -> Result<Self, LoadXzError> {
28        self.extend_from_xz(bytes)?;
29        Ok(self)
30    }
31
32    /// Extract an xz archive and add contents from its `desc` files to the text collection.
33    pub fn from_xz<Bytes: Read>(bytes: Bytes) -> Result<Self, LoadXzError> {
34        TextCollection::new().add_xz(bytes)
35    }
36}
37
38impl<'a> MultiTextCollection<'a> {
39    /// Extract an xz archive and add contents from its `desc` files to the multi-collection.
40    pub fn extend_from_xz<Bytes: Read>(
41        &mut self,
42        repository: RepositoryName<'a>,
43        bytes: Bytes,
44    ) -> Result<(), LoadArchiveError> {
45        let collection = TextCollection::from_xz(bytes)?;
46        self.insert(repository, collection);
47        Ok(())
48    }
49
50    /// Extract an xz archive and add contents from its `desc` files to the multi-collection.
51    pub fn add_xz<Bytes: Read>(
52        mut self,
53        repository: RepositoryName<'a>,
54        bytes: Bytes,
55    ) -> Result<Self, LoadArchiveError> {
56        self.extend_from_xz(repository, bytes)?;
57        Ok(self)
58    }
59
60    /// Extract an xz archive and add contents from its `desc` files to the multi-collection.
61    pub fn from_xz<Bytes: Read>(
62        repository: RepositoryName<'a>,
63        bytes: Bytes,
64    ) -> Result<Self, LoadArchiveError> {
65        MultiTextCollection::with_capacity(1).add_xz(repository, bytes)
66    }
67}
68
69impl From<LoadXzError> for LoadArchiveError {
70    fn from(value: LoadXzError) -> Self {
71        match value {
72            LoadXzError::Xz(error) => LoadArchiveError::Xz(error),
73            LoadXzError::InternalArchive(error) => LoadArchiveError::InternalArchive(error),
74        }
75    }
76}