eureka_mmanager_core/data_pulls/chapter/
images.rs1use std::{fs::read_dir, path::Path};
2
3use uuid::Uuid;
4
5use crate::{data_pulls::Pull, DirsOptions, ManagerCoreResult};
6
7#[derive(Debug, Clone, Hash, Default)]
8#[cfg_attr(feature = "actix", derive(actix::MessageResponse))]
9pub struct ChapterImagesData {
10 pub data: Vec<String>,
11 pub data_saver: Vec<String>,
12}
13
14impl ChapterImagesData {
15 pub fn is_empty(&self) -> bool {
16 self.data.is_empty() && self.data_saver.is_empty()
17 }
18}
19
20fn m_read_dir<P: AsRef<Path>>(path: P) -> Vec<String> {
21 read_dir(path)
22 .map(|dir| {
23 dir.flatten()
24 .filter(|f| {
25 f.path().is_file()
26 && f.path()
27 .extension()
28 .map(|ext| ext != "json")
29 .unwrap_or_default()
30 })
31 .filter_map(|e| {
32 if let Some(len) = e.metadata().ok().map(|md| md.len()) {
33 if len == 0 {
34 return None::<String>;
35 }
36 }
37 e.file_name().to_str().map(String::from)
38 })
39 .collect::<Vec<_>>()
40 })
41 .unwrap_or_default()
42}
43
44fn string_f_usize_sort(data: &mut [String]) -> Result<(), regex::Error> {
45 let regex = regex::Regex::new(r"\d+")?;
46 data.sort_by(|a, b| {
47 let a = regex
48 .captures(a)
49 .and_then(|c| c.get(0)?.as_str().parse::<usize>().ok());
50 let b = regex
51 .captures(b)
52 .and_then(|c| c.get(0)?.as_str().parse::<usize>().ok());
53 a.cmp(&b)
54 });
55 Ok(())
56}
57
58impl Pull<ChapterImagesData, Uuid> for DirsOptions {
59 type Error = crate::Error;
60 fn pull(&self, id: Uuid) -> ManagerCoreResult<ChapterImagesData> {
61 let mut data = m_read_dir(self.chapters_id_data_add(id));
62 string_f_usize_sort(&mut data)?;
63 let mut data_saver = m_read_dir(self.chapters_id_data_saver_add(id));
64 string_f_usize_sort(&mut data_saver)?;
65 let images = ChapterImagesData { data, data_saver };
66 if images.is_empty() {
67 Err(crate::Error::NoChapterImages(id))
68 } else {
69 Ok(images)
70 }
71 }
72}