arch_pkg_db/text/archive/
gz.rs

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