atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
53bce0d930007b21fb1f130865979bbd959edcc5
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/lube.rsRust103 lines2.8 KB
1
use axum::http::StatusCode;
2
use serde_json::json;
3
4
use super::Item;
5
use crate::problem::Problem;
6
7
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
8
pub enum Lube {
9
    BabyOil,
10
    CoconutOil,
11
    Lotion,
12
    Vaseline,
13
    Spit,
14
}
15
16
impl Lube {
17
    const ALL: [Self; 5] = [
18
        Self::BabyOil,
19
        Self::CoconutOil,
20
        Self::Lotion,
21
        Self::Vaseline,
22
        Self::Spit,
23
    ];
24
25
    pub fn content_types() -> [&'static str; 5] {
26
        Self::ALL.map(Self::content_type)
27
    }
28
29
    fn content_type(self) -> &'static str {
30
        match self {
31
            Self::BabyOil => "application/baby-oil",
32
            Self::CoconutOil => "application/coconut-oil",
33
            Self::Lotion => "application/lotion",
34
            Self::Vaseline => "application/vaseline",
35
            Self::Spit => "text/plain; charset=spit",
36
        }
37
    }
38
39
    pub fn from_content_type(content_type: Option<&str>) -> Result<Option<Self>, Problem> {
40
        let Some(raw) = content_type else {
41
            return Ok(None);
42
        };
43
        let lowered = raw.to_ascii_lowercase();
44
        let mut parts = lowered.split(';').map(str::trim);
45
        let essence = parts.next().unwrap_or_default();
46
        let spit = parts.any(|p| p.replace(' ', "") == "charset=spit");
47
        if let Some(lube) = Self::ALL.into_iter().find(|l| l.content_type() == essence) {
48
            return Ok(Some(lube));
49
        }
50
        match essence {
51
            "text/plain" if spit => Ok(Some(Self::Spit)),
52
            e if e.starts_with("image/") || e.starts_with("video/") => Err(Problem::new(
53
                StatusCode::UNSUPPORTED_MEDIA_TYPE,
54
                "no",
55
                "No.",
56
            )),
57
            _ => Err(Problem::new(
58
                StatusCode::UNSUPPORTED_MEDIA_TYPE,
59
                "unsupported-lubricant",
60
                format!("{essence} is not a lubricant."),
61
            )
62
            .with("lubricants", json!(Self::content_types()))),
63
        }
64
    }
65
66
    pub fn modifier(self) -> i32 {
67
        match self {
68
            Self::BabyOil => 1,
69
            Self::CoconutOil => 3,
70
            Self::Lotion => 0,
71
            Self::Vaseline => 2,
72
            Self::Spit => -2,
73
        }
74
    }
75
76
    /// The bottle this lube comes in. Spit has none and never runs out.
77
    pub fn item(self) -> Option<Item> {
78
        match self {
79
            Self::Spit => None,
80
            Self::BabyOil => Some(Item::BabyOil),
81
            Self::CoconutOil => Some(Item::CoconutOil),
82
            Self::Lotion => Some(Item::Lotion),
83
            Self::Vaseline => Some(Item::Vaseline),
84
        }
85
    }
86
}
87
88
#[derive(Clone, Copy)]
89
pub enum LubeRule {
90
    Required,
91
    Forbidden,
92
    Optional,
93
}
94
95
impl LubeRule {
96
    pub(super) fn name(self) -> &'static str {
97
        match self {
98
            Self::Required => "required",
99
            Self::Forbidden => "forbidden",
100
            Self::Optional => "optional",
101
        }
102
    }
103
}