arch_pkg_db/text/archive/
tar.rs1use super::{LoadArchiveError, LoadUncompressedArchiveError};
2use crate::{MultiTextCollection, TextCollection, value::RepositoryName};
3use derive_more::{Display, Error};
4use pipe_trait::Pipe;
5use std::{
6 ffi::OsStr,
7 io::{self, Read},
8};
9
10#[derive(Debug, Display, Error)]
12#[display("Failed to read the tar archive: {_0}")]
13pub struct LoadTarError(io::Error);
14
15impl TextCollection {
16 pub fn extend_from_tar<Bytes: Read>(&mut self, bytes: Bytes) -> Result<(), LoadTarError> {
18 let mut tar = tar::Archive::new(bytes);
19 let entries = tar.entries().map_err(LoadTarError)?;
20
21 for entry in entries {
22 let mut entry = entry.map_err(LoadTarError)?;
23 let path = entry.path().map_err(LoadTarError)?;
24 let file_name = path.file_name().and_then(OsStr::to_str);
25 if file_name != Some("desc") {
26 continue;
27 }
28 let mut text = entry
29 .header()
30 .size()
31 .unwrap_or(0)
32 .pipe(usize::try_from)
33 .unwrap_or(0)
34 .pipe(String::with_capacity);
35 entry.read_to_string(&mut text).map_err(LoadTarError)?;
36 self.insert(text.into());
37 }
38
39 Ok(())
40 }
41
42 pub fn add_tar<Bytes: Read>(mut self, bytes: Bytes) -> Result<Self, LoadTarError> {
44 self.extend_from_tar(bytes)?;
45 Ok(self)
46 }
47
48 pub fn from_tar<Bytes: Read>(bytes: Bytes) -> Result<Self, LoadTarError> {
50 TextCollection::new().add_tar(bytes)
51 }
52}
53
54impl<'a> MultiTextCollection<'a> {
55 pub fn extend_from_tar<Bytes: Read>(
57 &mut self,
58 repository: RepositoryName<'a>,
59 bytes: Bytes,
60 ) -> Result<(), LoadArchiveError> {
61 let collection = TextCollection::from_tar(bytes)?;
62 self.insert(repository, collection);
63 Ok(())
64 }
65
66 pub fn add_tar<Bytes: Read>(
68 mut self,
69 repository: RepositoryName<'a>,
70 bytes: Bytes,
71 ) -> Result<Self, LoadArchiveError> {
72 self.extend_from_tar(repository, bytes)?;
73 Ok(self)
74 }
75
76 pub fn from_tar<Bytes: Read>(
78 repository: RepositoryName<'a>,
79 bytes: Bytes,
80 ) -> Result<Self, LoadArchiveError> {
81 MultiTextCollection::with_capacity(1).add_tar(repository, bytes)
82 }
83}
84
85impl From<LoadTarError> for LoadUncompressedArchiveError {
86 fn from(value: LoadTarError) -> Self {
87 LoadUncompressedArchiveError::Tar(value)
88 }
89}
90
91impl From<LoadTarError> for LoadArchiveError {
92 fn from(value: LoadTarError) -> Self {
93 LoadArchiveError::Tar(value)
94 }
95}