ibdl_core/
lib.rs

1#![deny(clippy::nursery)]
2#![allow(clippy::module_name_repetitions)]
3#![allow(clippy::missing_panics_doc)]
4#![allow(clippy::missing_errors_doc)]
5#![allow(clippy::struct_field_names)]
6pub use clap;
7use clap::ValueEnum;
8use ibdl_common::{post::rating::Rating, ImageBoards};
9pub use owo_colors;
10use std::ops::Deref;
11use std::path::{Path, PathBuf};
12
13pub mod async_queue;
14pub mod cli;
15pub mod error;
16pub mod progress_bars;
17
18#[derive(Debug, Clone, Copy)]
19#[repr(transparent)]
20pub struct ImageBoardArg(ImageBoards);
21
22#[derive(Debug, Clone, Copy)]
23#[repr(transparent)]
24pub struct RatingArg(pub Rating);
25
26impl ValueEnum for RatingArg {
27    fn value_variants<'a>() -> &'a [Self] {
28        &[
29            Self(Rating::Safe),
30            Self(Rating::Questionable),
31            Self(Rating::Explicit),
32        ]
33    }
34    fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
35        match self.0 {
36            Rating::Safe => {
37                Some(clap::builder::PossibleValue::new("safe").help(
38                    "Represents posts that are don't involve nothing suggestive or sensitive",
39                ))
40            }
41            Rating::Questionable => Some(clap::builder::PossibleValue::new("questionable").help(
42                "Represents posts that have some degree of nudity or sexually suggestive elements",
43            )),
44            Rating::Explicit => Some(clap::builder::PossibleValue::new("explicit").help(
45                "Represents posts that have explicit elements of pornography, gore, death, etc",
46            )),
47            _ => None,
48        }
49    }
50}
51
52impl Deref for RatingArg {
53    type Target = Rating;
54
55    fn deref(&self) -> &Self::Target {
56        &self.0
57    }
58}
59
60#[inline]
61pub fn generate_output_path(
62    main_path: &Path,
63    imageboard: ImageBoards,
64    tags: &[String],
65    cbz_mode: bool,
66    pool_id: Option<u32>,
67) -> PathBuf {
68    let tag_string = tags.join(" ");
69    let tag_path_string = if tag_string.contains("fav:") {
70        String::from("Favorites")
71    } else if cfg!(windows) {
72        tag_string.replace(':', "_")
73    } else if let Some(id) = pool_id {
74        id.to_string()
75    } else {
76        tag_string
77    };
78
79    let pbuf = main_path.join(Path::new(&imageboard.to_string()));
80
81    if cbz_mode {
82        return pbuf.join(Path::new(&format!("{}.cbz", tag_path_string)));
83    }
84    pbuf.join(Path::new(&tag_path_string))
85}
86
87/// This function creates the destination directory without creating additional ones related to
88/// the selected imageboard or tags used.
89#[inline]
90pub fn generate_output_path_precise(main_path: &Path, cbz_mode: bool) -> PathBuf {
91    if cbz_mode {
92        return PathBuf::from(&format!("{}.cbz", main_path.display()));
93    }
94    main_path.to_path_buf()
95}