atagen

jelq

public

an http based roguelike rpg about jelqing

Star0
Watch0
08ffcd6cbba5702c7a8c5fed1f54f9d3e2f51c8b
1
ssh://brewery@pls.lobotomise.me:33/atagen/jelq.git
src/game/outcome.rsRust74 lines1.8 KB
1
use axum::http::{HeaderName, StatusCode};
2
use serde_json::Value;
3
4
pub enum Payload {
5
    Empty,
6
    Json(Value),
7
    Raw(&'static str, Vec<u8>),
8
}
9
10
/// A successful result of a game action, before it becomes an HTTP response.
11
pub struct Outcome {
12
    status: StatusCode,
13
    payload: Payload,
14
    headers: Vec<(HeaderName, String)>,
15
}
16
17
impl Outcome {
18
    pub fn empty(status: StatusCode) -> Self {
19
        Self {
20
            status,
21
            payload: Payload::Empty,
22
            headers: Vec::new(),
23
        }
24
    }
25
26
    pub fn json(status: StatusCode, body: Value) -> Self {
27
        Self {
28
            payload: Payload::Json(body),
29
            ..Self::empty(status)
30
        }
31
    }
32
33
    pub fn raw(status: StatusCode, content_type: &'static str, body: impl Into<Vec<u8>>) -> Self {
34
        Self {
35
            payload: Payload::Raw(content_type, body.into()),
36
            ..Self::empty(status)
37
        }
38
    }
39
40
    pub fn header(mut self, name: HeaderName, value: impl Into<String>) -> Self {
41
        self.headers.push((name, value.into()));
42
        self
43
    }
44
45
    pub fn status(&self) -> StatusCode {
46
        self.status
47
    }
48
49
    pub fn body(&self) -> Option<&Value> {
50
        match &self.payload {
51
            Payload::Json(body) => Some(body),
52
            _ => None,
53
        }
54
    }
55
56
    pub fn header_value(&self, name: &HeaderName) -> Option<&str> {
57
        self.headers
58
            .iter()
59
            .find(|(n, _)| n == name)
60
            .map(|(_, v)| v.as_str())
61
    }
62
63
    pub(super) fn retold(mut self, status: StatusCode, detail: &str) -> Self {
64
        self.status = status;
65
        if let Payload::Json(body) = &mut self.payload {
66
            body["detail"] = Value::from(detail);
67
        }
68
        self
69
    }
70
71
    pub fn into_parts(self) -> (StatusCode, Payload, Vec<(HeaderName, String)>) {
72
        (self.status, self.payload, self.headers)
73
    }
74
}