1
//! Define the `Anonymity` type to indicate a level of anonymity.
2

            
3
use crate::internal_prelude::*;
4

            
5
/// The level of anonymity that an onion service should try to run with.
6
#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
7
#[non_exhaustive]
8
pub enum Anonymity {
9
    /// Try to keep the location of the onion service private.
10
    ///
11
    /// Can be represented in a serde-based configuration as `true` or
12
    /// `"anonymous"` (case insensitive).
13
    #[default]
14
    Anonymous,
15
    /// Do not try to keep the location of the onion service private.
16
    ///
17
    /// (This is implemented using our "single onion service" design.)
18
    ///
19
    /// Can be represented in a serde-based configuration as`"non_anonymous"`
20
    /// (case insensitive).
21
    DangerouslyNonAnonymous,
22
}
23

            
24
/// A string used to represent `Anonymity::Anonymous` in serde.
25
const ANON_STRING: &str = "anonymous";
26

            
27
/// A string used to represent `Anonymity::DangerouslyNonAnonymous` in serde.
28
const DANGER_STRING: &str = "not_anonymous";
29

            
30
impl Serialize for Anonymity {
31
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32
    where
33
        S: Serializer,
34
    {
35
        match self {
36
            Anonymity::Anonymous => serializer.serialize_bool(true),
37
            Anonymity::DangerouslyNonAnonymous => serializer.serialize_str(DANGER_STRING),
38
        }
39
    }
40
}
41

            
42
impl<'de> Deserialize<'de> for Anonymity {
43
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
44
    where
45
        D: Deserializer<'de>,
46
    {
47
        /// Visitor struct to deserialize an Anonymity object.
48
        struct Vis;
49
        impl<'de> serde::de::Visitor<'de> for Vis {
50
            type Value = Anonymity;
51

            
52
            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53
                write!(
54
                    formatter,
55
                    r#"`true`, `{:?}`, or `{:?}`"#,
56
                    ANON_STRING, DANGER_STRING
57
                )
58
            }
59
            fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
60
            where
61
                E: serde::de::Error,
62
            {
63
                if v {
64
                    Ok(Anonymity::Anonymous)
65
                } else {
66
                    Err(E::invalid_value(serde::de::Unexpected::Bool(v), &self))
67
                }
68
            }
69
            fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
70
            where
71
                E: serde::de::Error,
72
            {
73
                if s.eq_ignore_ascii_case(ANON_STRING) {
74
                    Ok(Anonymity::Anonymous)
75
                } else if s.eq_ignore_ascii_case(DANGER_STRING) {
76
                    Ok(Anonymity::DangerouslyNonAnonymous)
77
                } else {
78
                    Err(E::invalid_value(serde::de::Unexpected::Str(s), &self))
79
                }
80
            }
81
        }
82
        deserializer.deserialize_any(Vis)
83
    }
84
}