1
//! Implementations of our useful traits, on external and parsing-mode types
2

            
3
use super::*;
4

            
5
impl ItemArgument for str {
6
95782
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
7
        // Implements this
8
        // https://gitlab.torproject.org/tpo/core/torspec/-/merge_requests/106
9
2909023
        if self.is_empty() || self.chars().any(|c| !c.is_ascii_graphic()) {
10
            return Err(internal!(
11
                "invalid netdoc keyword line argument syntax {:?}",
12
                self
13
            ));
14
95782
        }
15
95782
        out.args_raw_nonempty(&self);
16
95782
        Ok(())
17
95782
    }
18
}
19

            
20
impl ItemArgument for &str {
21
30622
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
22
30622
        <str as ItemArgument>::write_arg_onto(self, out)
23
30622
    }
24
}
25

            
26
impl ItemArgument for Iso8601TimeSp {
27
    // Unlike the macro'd formats, contains a space while still being one argument
28
10
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
29
10
        let arg = self.to_string();
30
10
        out.args_raw_nonempty(&arg.as_str());
31
10
        Ok(())
32
10
    }
33
}
34

            
35
impl ItemValueEncodable for Void {
36
    fn write_item_value_onto(&self, _out: ItemEncoder) -> Result<(), Bug> {
37
        void::unreachable(*self)
38
    }
39
}
40

            
41
impl ItemObjectEncodable for Void {
42
    fn label(&self) -> &str {
43
        void::unreachable(*self)
44
    }
45
    fn write_object_onto(&self, _: &mut Vec<u8>) -> Result<(), Bug> {
46
        void::unreachable(*self)
47
    }
48
}
49

            
50
/// Types related to RSA keys
51
mod rsa {
52
    use super::*;
53
    use tor_llcrypto::pk::rsa::PublicKey;
54

            
55
    impl ItemObjectEncodable for PublicKey {
56
4
        fn label(&self) -> &str {
57
4
            "RSA PUBLIC KEY"
58
4
        }
59
4
        fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
60
4
            b.extend(self.to_der());
61
4
            Ok(())
62
4
        }
63
    }
64

            
65
    impl ItemValueEncodable for PublicKey {
66
4
        fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
67
4
            out.object(self);
68
4
            Ok(())
69
4
        }
70
    }
71
}
72

            
73
/// HS POW
74
#[cfg(feature = "hs-pow-full")]
75
mod hs_pow {
76
    use super::*;
77
    use tor_hscrypto::pow::v1;
78

            
79
    impl ItemArgument for v1::Seed {
80
2
        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
81
2
            let mut seed_bytes = vec![];
82
2
            tor_bytes::Writer::write(&mut seed_bytes, &self)?;
83
2
            out.add_arg(&Base64Unpadded::encode_string(&seed_bytes));
84
2
            Ok(())
85
2
        }
86
    }
87

            
88
    impl ItemArgument for v1::Effort {
89
2
        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
90
2
            out.add_arg(&<Self as Into<u32>>::into(*self));
91
2
            Ok(())
92
2
        }
93
    }
94
}