axum_resp_result/extra_flag/
flags.rs

1use std::{
2    fmt::Debug,
3    ops::{Add, AddAssign},
4};
5
6use http::{header::HeaderName, HeaderValue, StatusCode};
7
8use crate::expect_ext::ExpectExt;
9
10#[derive(Debug, Hash, PartialEq, Eq)]
11/// the basic flag that can be using
12pub enum ExtraFlag {
13    /// set the respond body to empty
14    EmptyBody,
15    /// overwrite the default status code
16    SetStatus(StatusCode),
17    /// set the header value
18    SetHeader(HeaderName, HeaderValue, HeaderType),
19    /// remove a header
20    RemoveHeader(HeaderName),
21}
22#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
23/// the action of set header
24pub enum HeaderType {
25    /// insert new header, if the header exist will push into the [`HeaderValue`] list
26    Insert,
27    /// append new header, if the header exist will overwrite old [`HeaderValue`]
28    Append,
29}
30
31impl ExtraFlag {
32    /// create [`ExtraFlag::EmptyBody`] flag
33    #[inline]
34    pub const fn empty_body() -> Self {
35        Self::EmptyBody
36    }
37
38    #[inline]
39    /// create [`ExtraFlag::SetStatus`] flag
40    pub const fn status(status: StatusCode) -> Self {
41        Self::SetStatus(status)
42    }
43
44    #[inline]
45    /// create [`ExtraFlag::SetHeader`] flag with type [`HeaderType::Append`]
46    pub fn append_header<K, V>(key: K, value: V) -> Self
47    where
48        K: TryInto<HeaderName>,
49        K::Error: Debug,
50        V: TryInto<HeaderValue>,
51        V::Error: Debug,
52    {
53        Self::SetHeader(
54            key.try_into().with_expect("Bad Header Name"),
55            value.try_into().with_expect("Bad Header Value"),
56            HeaderType::Append,
57        )
58    }
59
60    #[inline]
61    /// create [`ExtraFlag::SetHeader`] flag with type [`HeaderType::Append`]
62    pub fn insert_header<K, V>(key: K, value: V) -> Self
63    where
64        K: TryInto<HeaderName>,
65        K::Error: Debug,
66        V: TryInto<HeaderValue>,
67        V::Error: Debug,
68    {
69        Self::SetHeader(
70            key.try_into().with_expect("Bad Header Name"),
71            value.try_into().with_expect("Bad Header Value"),
72            HeaderType::Insert,
73        )
74    }
75
76    #[inline]
77    /// create [`ExtraFlag::RemoveHeader`] flag
78    pub fn remove_header<K>(key: K) -> Self
79    where
80        K: TryInto<HeaderName>,
81        K::Error: Debug,
82    {
83        Self::RemoveHeader(key.try_into().with_expect("Bad Header Name"))
84    }
85}
86
87/// a set of extra flags
88/// can using `+` or `+=` combine multiple [`ExtraFlag`]
89///
90/// # Example
91///
92/// ```rust
93///
94/// use crate::{ExtraFlag,ExtraFlags};
95/// use http::StatusCode;
96///
97/// let mut flags: ExtraFlags = ExtraFlag::empty_body() + ExtraFlag::status(StatusCode::BAD_REQUEST);
98///
99///flags += ExtraFlag::append_header("bar","foo");
100///
101/// ```
102pub struct ExtraFlags {
103    pub(crate) flags: Vec<ExtraFlag>,
104}
105
106impl From<()> for ExtraFlags {
107    fn from(_: ()) -> Self {
108        ExtraFlags { flags: vec![] }
109    }
110}
111
112impl From<ExtraFlag> for ExtraFlags {
113    fn from(flag: ExtraFlag) -> Self {
114        Self {
115            flags: Vec::from_iter([flag]),
116        }
117    }
118}
119
120impl Add for ExtraFlag {
121    type Output = ExtraFlags;
122
123    fn add(self, rhs: Self) -> Self::Output {
124        ExtraFlags {
125            flags: Vec::from([self, rhs]),
126        }
127    }
128}
129
130impl Add<ExtraFlags> for ExtraFlag {
131    type Output = ExtraFlags;
132
133    fn add(self, mut rhs: ExtraFlags) -> Self::Output {
134        rhs.flags.push(self);
135        rhs
136    }
137}
138
139impl Add<ExtraFlag> for ExtraFlags {
140    type Output = ExtraFlags;
141
142    fn add(mut self, rhs: ExtraFlag) -> Self::Output {
143        self.flags.push(rhs);
144        self
145    }
146}
147
148impl AddAssign for ExtraFlags {
149    fn add_assign(&mut self, rhs: Self) {
150        self.flags.extend(rhs.flags);
151    }
152}
153
154impl AddAssign<ExtraFlag> for ExtraFlags {
155    fn add_assign(&mut self, rhs: ExtraFlag) {
156        self.flags.push(rhs)
157    }
158}