arcs_ctf_yaml_parser/categories/
structs.rs

1use std::fmt::Debug;
2
3#[allow(unused)]
4static CATEGORY_DEFAULTS: [&str; 5] = ["misc", "binex", "foren", "crypto", "webex"];
5
6use lazy_static::lazy_static;
7use std::collections::HashSet;
8lazy_static!{
9    static ref CATEGORY_RAW_ENV_VAR: Option<String> = std::env::var("CATEGORIES").ok();
10
11    pub static ref CATEGORIES: HashSet<String> = CATEGORY_RAW_ENV_VAR.as_ref().map_or_else(
12        || CATEGORY_DEFAULTS.into_iter().map(str::to_string).collect(),
13        |val| val.split(',').map(|part| part.trim().to_string()).collect(),
14    );
15}
16
17#[derive(PartialEq)]
18pub struct Category {
19    name: String,
20}
21
22impl Category {
23    pub fn try_new(name: &'_ str) -> Option<Self> {
24        // CATEGORIES.get(name).map(|name| Self { name })
25        Some(Self { name: name.to_string() })
26    }
27    pub fn as_str(&self) -> &str {
28        &self.name
29    }
30}
31
32impl Debug for Category {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        write!(f, "Category< {} >", self.name)
35    }
36}
37
38#[derive(PartialEq)]
39pub struct Categories(Vec<Category>);
40
41impl Categories {
42    pub fn try_new<'a>(category_names: impl IntoIterator<Item = &'a str>) -> Result<Categories, Vec<&'a str>> {
43        let mut good_cats = vec![];
44        let mut invalid_cat_names = vec![];
45
46        for name in category_names {
47            if let Some(cat) = Category::try_new(name) {
48                good_cats.push(cat);
49            } else {
50                invalid_cat_names.push(name);
51            }
52        }
53
54        if invalid_cat_names.is_empty() {
55            Ok(Self(good_cats))
56        } else {
57            Err(invalid_cat_names)
58        }
59    }
60
61    pub fn iter(&self) -> impl Iterator<Item = &Category> {
62        self.0.iter()
63    }
64
65    pub fn slice(&self) -> &[Category] {
66        &self.0
67    }
68}
69
70impl Debug for Categories {
71    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72        write!(f, "Categories< ")?;
73        if let Some(cat) = self.0.first() {
74            write!(f, "{}", cat.name)?;
75
76            for cat in self.0.iter().skip(1) {
77                write!(f, ", {}", cat.name)?;
78            }
79        }
80        write!(f, " >")
81    }
82}
83