rpkg_rs/misc/
hash_path_list.rs1use crate::misc::resource_id::ResourceID;
2use crate::resource::runtime_resource_id::RuntimeResourceID;
3use rayon::iter::ParallelIterator;
4use rayon::prelude::IntoParallelIterator;
5use std::collections::HashMap;
6use std::fs::read_to_string;
7use std::path::Path;
8use std::str::FromStr;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12pub enum PathListError {
13 #[error("{0}")]
14 IoError(#[from] std::io::Error),
15
16 #[error("Invalid RuntimeResourceID entry")]
17 InvalidRuntimeResourceID,
18}
19
20#[derive(Default, Debug)]
22pub struct PathList {
23 pub entries: HashMap<RuntimeResourceID, Option<ResourceID>>,
24}
25
26impl PathList {
27 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn parse_into<P: AsRef<Path>>(&mut self, path: P) -> Result<&Self, PathListError> {
47 let file_as_string = read_to_string(path).map_err(PathListError::IoError)?;
48 let lines: Vec<_> = file_as_string.lines().map(String::from).collect();
49
50 let lines_par = lines.into_par_iter();
51
52 self.entries = lines_par
53 .filter_map(|line_res| {
54 if line_res.starts_with('#') {
55 return None;
56 };
57
58 let (hash, path) = match line_res.split_once(',') {
59 Some((h, p)) => (h.split_once('.').unwrap().0, Some(p)),
60 None => (line_res.as_str(), None),
61 };
62
63 if let Ok(id) = u64::from_str_radix(hash, 16) {
64 if let Some(path) = path {
65 if let Ok(rid) = ResourceID::from_str(path) {
66 if rid.is_valid() {
67 return Some((RuntimeResourceID::from(id), Some(rid)));
68 }
69 }
70 }
71 Some((RuntimeResourceID::from(id), None))
72 } else {
73 None
74 }
75 })
76 .collect::<Vec<_>>()
77 .into_iter()
78 .collect();
79
80 Ok(self)
81 }
82
83 pub fn get(&self, key: &RuntimeResourceID) -> Option<&ResourceID> {
84 if let Some(value) = self.entries.get(key) {
85 if let Some(path) = value {
86 return Some(path);
87 }
88 return None;
89 }
90 None
91 }
92}