gitlab_runner/
artifact.rs1use std::{
3 io::{Read, Seek},
4 path::PathBuf,
5};
6
7use zip::{read::ZipFile, result::ZipResult};
8
9pub struct ArtifactFile<'a>(ZipFile<'a>);
13
14impl ArtifactFile<'_> {
15 pub fn name(&self) -> &str {
17 self.0.name()
18 }
19
20 pub fn path(&self) -> Option<PathBuf> {
25 self.0.enclosed_name()
26 }
27}
28
29impl Read for ArtifactFile<'_> {
30 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
31 self.0.read(buf)
32 }
33}
34
35pub(crate) trait ReadSeek: Read + Seek {}
36impl<T> ReadSeek for T where T: Read + Seek {}
37
38pub struct Artifact {
42 zip: zip::ZipArchive<Box<dyn ReadSeek + Send>>,
43}
44
45impl Artifact {
46 pub(crate) fn new(data: Box<dyn ReadSeek + Send>) -> ZipResult<Self> {
47 let zip = zip::ZipArchive::new(data)?;
48 Ok(Self { zip })
49 }
50
51 pub fn file_names(&self) -> impl Iterator<Item = &str> {
56 self.zip.file_names()
57 }
58
59 pub fn file(&mut self, name: &str) -> Option<ArtifactFile> {
61 self.zip.by_name(name).ok().map(ArtifactFile)
62 }
63
64 pub fn by_index(&mut self, i: usize) -> Option<ArtifactFile> {
66 self.zip.by_index(i).ok().map(ArtifactFile)
67 }
68
69 pub fn is_empty(&self) -> bool {
71 self.zip.is_empty()
72 }
73
74 pub fn len(&self) -> usize {
76 self.zip.len()
77 }
78}