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

            
3
use tor_basic_utils::intern::Intern;
4

            
5
use super::*;
6

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

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

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

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

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

            
52
impl<T: NetdocEncodable> NetdocEncodable for Arc<T> {
53
    fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
54
        <T as NetdocEncodable>::encode_unsigned(self, out)
55
    }
56
}
57

            
58
impl<T: NetdocEncodableFields> NetdocEncodableFields for Arc<T> {
59
6
    fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
60
6
        <T as NetdocEncodableFields>::encode_fields(self, out)
61
6
    }
62
}
63

            
64
impl<T: ItemValueEncodable> ItemValueEncodable for Arc<T> {
65
28
    fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
66
28
        <T as ItemValueEncodable>::write_item_value_onto(self, out)
67
28
    }
68
}
69

            
70
impl<T: ItemArgument> ItemArgument for Arc<T> {
71
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
72
        <T as ItemArgument>::write_arg_onto(self, out)
73
    }
74
}
75

            
76
impl<T: ItemObjectEncodable> ItemObjectEncodable for Arc<T> {
77
    fn label(&self) -> &str {
78
        <T as ItemObjectEncodable>::label(self)
79
    }
80
    fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
81
        <T as ItemObjectEncodable>::write_object_onto(self, b)
82
    }
83
}
84

            
85
impl<T: NetdocEncodable> NetdocEncodable for Intern<T> {
86
    fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
87
        <T as NetdocEncodable>::encode_unsigned(self, out)
88
    }
89
}
90

            
91
impl<T: NetdocEncodableFields> NetdocEncodableFields for Intern<T> {
92
    fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
93
        <T as NetdocEncodableFields>::encode_fields(self, out)
94
    }
95
}
96

            
97
impl<T: ItemValueEncodable> ItemValueEncodable for Intern<T> {
98
4
    fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
99
4
        <T as ItemValueEncodable>::write_item_value_onto(self, out)
100
4
    }
101
}
102

            
103
impl<T: ItemArgument> ItemArgument for Intern<T> {
104
    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
105
        <T as ItemArgument>::write_arg_onto(self, out)
106
    }
107
}
108

            
109
impl<T: ItemObjectEncodable> ItemObjectEncodable for Intern<T> {
110
    fn label(&self) -> &str {
111
        <T as ItemObjectEncodable>::label(self)
112
    }
113
    fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
114
        <T as ItemObjectEncodable>::write_object_onto(self, b)
115
    }
116
}
117

            
118
/// Types related to RSA keys
119
mod rsa {
120
    use super::*;
121
    use tor_llcrypto::pk::rsa::PublicKey;
122

            
123
    impl ItemObjectEncodable for PublicKey {
124
18
        fn label(&self) -> &str {
125
18
            "RSA PUBLIC KEY"
126
18
        }
127
18
        fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
128
18
            b.extend(self.to_der());
129
18
            Ok(())
130
18
        }
131
    }
132

            
133
    impl ItemValueEncodable for PublicKey {
134
4
        fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
135
4
            out.object(self);
136
4
            Ok(())
137
4
        }
138
    }
139
}
140

            
141
/// Protocol versions (from `tor-protover`)
142
pub(crate) mod protovers {
143
    use super::*;
144
    use tor_protover::Protocols;
145

            
146
    impl ItemValueEncodable for Protocols {
147
66
        fn write_item_value_onto(&self, mut out: ItemEncoder) -> Result<(), Bug> {
148
66
            out.args_raw_string(&self);
149
66
            Ok(())
150
66
        }
151
    }
152
}
153

            
154
/// HS POW
155
#[cfg(feature = "hs-pow-full")]
156
mod hs_pow {
157
    use super::*;
158
    use tor_hscrypto::pow::v1;
159

            
160
    impl ItemArgument for v1::Seed {
161
2
        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
162
2
            let mut seed_bytes = vec![];
163
2
            tor_bytes::Writer::write(&mut seed_bytes, &self)?;
164
2
            out.add_arg(&Base64Unpadded::encode_string(&seed_bytes));
165
2
            Ok(())
166
2
        }
167
    }
168

            
169
    impl ItemArgument for v1::Effort {
170
2
        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
171
2
            out.add_arg(&<Self as Into<u32>>::into(*self));
172
2
            Ok(())
173
2
        }
174
    }
175
}