Skip to content

Commit

Permalink
♻️ Introduce enum State
Browse files Browse the repository at this point in the history
  • Loading branch information
ChanTsune committed Apr 18, 2024
1 parent a3faf70 commit 3385b95
Showing 1 changed file with 30 additions and 27 deletions.
57 changes: 30 additions & 27 deletions src/file_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use id_tree::{InsertBehavior, Node, NodeId, Tree, TreeBuilder};
#[cfg(unix)]
use nix::unistd::{Gid, Group, Uid, User};
use pna::{Archive, DataKind, Permission, ReadOption};
use std::cell::OnceCell;
use std::collections::HashMap;
use std::ffi::OsString;
use std::io::Read;
Expand All @@ -13,32 +12,42 @@ use std::{fs, io};

pub type Inode = u64;

pub(crate) struct Entry {
cell: OnceCell<Vec<u8>>,
data: Option<(pna::RegularEntry, ReadOption)>,
pub(crate) struct LoadedEntry {
data: Vec<u8>,
}

pub(crate) struct UnprocessedEntry {
entry: pna::RegularEntry,
option: ReadOption,
}

pub(crate) enum State {
Loaded(LoadedEntry),
Unprocessed(UnprocessedEntry),
}

pub(crate) struct Entry(State);

impl Entry {
fn empty() -> Self {
Self {
cell: Default::default(),
data: None,
Self(State::Loaded(LoadedEntry { data: Vec::new() }))
}

fn load(&mut self) {
if let State::Unprocessed(e) = &self.0 {
let mut buf = Vec::new();
let mut reader = e.entry.reader(e.option.clone()).unwrap();
reader.read_to_end(&mut buf).unwrap();
self.0 = State::Loaded(LoadedEntry { data: buf });
}
}

pub(crate) fn as_slice(&mut self) -> &[u8] {
self.cell
.get_or_init(|| {
if let Some((entry, option)) = self.data.take() {
let mut buf = Vec::new();
let mut reader = entry.reader(option).unwrap();
reader.read_to_end(&mut buf).unwrap();
buf
} else {
Vec::new()
}
})
.as_slice()
self.load();
match &self.0 {
State::Loaded(e) => e.data.as_slice(),
State::Unprocessed(_) => unreachable!(),
}
}
}

Expand Down Expand Up @@ -127,16 +136,10 @@ impl File {
};
let option = ReadOption::with_password(password);
let (data, raw_size) = if let Some(raw_size) = metadata.raw_file_size() {
let data = Entry {
cell: Default::default(),
data: Some((entry, option)),
};
let data = Entry(State::Unprocessed(UnprocessedEntry { entry, option }));
(data, raw_size as usize)
} else {
let mut data = Entry {
cell: Default::default(),
data: Some((entry, option)),
};
let mut data = Entry(State::Unprocessed(UnprocessedEntry { entry, option }));
let raw_size = data.as_slice().len();
(data, raw_size)
};
Expand Down

0 comments on commit 3385b95

Please sign in to comment.