tor_hsservice/
anon_level.rs

1//! Define the `Anonymity` type to indicate a level of anonymity.
2
3use 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]
8pub 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.
25const ANON_STRING: &str = "anonymous";
26
27/// A string used to represent `Anonymity::DangerouslyNonAnonymous` in serde.
28const DANGER_STRING: &str = "not_anonymous";
29
30impl 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
42impl<'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}