actix_settings/settings/
keep_alive.rs1use std::fmt;
2
3use once_cell::sync::Lazy;
4use regex::Regex;
5use serde::de;
6
7use crate::{AsResult, Error, Parse};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub enum KeepAlive {
15 Default,
17
18 Disabled,
20
21 Os,
25
26 Seconds(usize),
28}
29
30impl Parse for KeepAlive {
31 fn parse(string: &str) -> AsResult<Self> {
32 pub(crate) static FMT: Lazy<Regex> =
33 Lazy::new(|| Regex::new(r"^\d+ seconds$").expect("Failed to compile regex: FMT"));
34
35 pub(crate) static DIGITS: Lazy<Regex> =
36 Lazy::new(|| Regex::new(r"^\d+").expect("Failed to compile regex: FMT"));
37
38 macro_rules! invalid_value {
39 ($got:expr) => {
40 Err(InvalidValue! {
41 expected: "a string of the format \"N seconds\" where N is an integer > 0",
42 got: $got,
43 })
44 };
45 }
46
47 let digits_in = |m: regex::Match<'_>| &string[m.start()..m.end()];
48 match string {
49 "default" => Ok(KeepAlive::Default),
50 "disabled" => Ok(KeepAlive::Disabled),
51 "OS" | "os" => Ok(KeepAlive::Os),
52 string if !FMT.is_match(string) => invalid_value!(string),
53 string => match DIGITS.find(string) {
54 None => invalid_value!(string),
55 Some(mat) => match digits_in(mat).parse() {
56 Ok(val) => Ok(KeepAlive::Seconds(val)),
57 Err(_) => invalid_value!(string),
58 },
59 },
60 }
61 }
62}
63
64impl<'de> de::Deserialize<'de> for KeepAlive {
65 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66 where
67 D: de::Deserializer<'de>,
68 {
69 struct KeepAliveVisitor;
70
71 impl de::Visitor<'_> for KeepAliveVisitor {
72 type Value = KeepAlive;
73
74 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 let msg = "Either \"default\", \"disabled\", \"os\", or a string of the format \"N seconds\" where N is an integer > 0";
76 f.write_str(msg)
77 }
78
79 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
80 where
81 E: de::Error,
82 {
83 match KeepAlive::parse(value) {
84 Ok(keep_alive) => Ok(keep_alive),
85 Err(Error::InvalidValue { expected, got, .. }) => Err(
86 de::Error::invalid_value(de::Unexpected::Str(&got), &expected),
87 ),
88 Err(_) => unreachable!(),
89 }
90 }
91 }
92
93 deserializer.deserialize_string(KeepAliveVisitor)
94 }
95}