Skip to main content

tor_netdoc/encode/
impls.rs

1//! Implementations of our useful traits, on external and parsing-mode types
2
3use tor_basic_utils::intern::Intern;
4
5use super::*;
6
7impl ItemArgument for str {
8    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        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        }
17        out.args_raw_nonempty(&self);
18        Ok(())
19    }
20}
21
22impl ItemArgument for &str {
23    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
24        <str as ItemArgument>::write_arg_onto(self, out)
25    }
26}
27
28impl ItemArgument for Iso8601TimeSp {
29    // Unlike the macro'd formats, contains a space while still being one argument
30    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
31        let arg = self.to_string();
32        out.args_raw_nonempty(&arg.as_str());
33        Ok(())
34    }
35}
36
37impl ItemValueEncodable for Void {
38    fn write_item_value_onto(&self, _out: ItemEncoder) -> Result<(), Bug> {
39        void::unreachable(*self)
40    }
41}
42
43impl 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
52impl<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
58impl<T: NetdocEncodableFields> NetdocEncodableFields for Arc<T> {
59    fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
60        <T as NetdocEncodableFields>::encode_fields(self, out)
61    }
62}
63
64impl<T: ItemValueEncodable> ItemValueEncodable for Arc<T> {
65    fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
66        <T as ItemValueEncodable>::write_item_value_onto(self, out)
67    }
68}
69
70impl<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
76impl<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
85impl<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
91impl<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
97impl<T: ItemValueEncodable> ItemValueEncodable for Intern<T> {
98    fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
99        <T as ItemValueEncodable>::write_item_value_onto(self, out)
100    }
101}
102
103impl<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
109impl<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
119mod rsa {
120    use super::*;
121    use tor_llcrypto::pk::rsa::PublicKey;
122
123    impl ItemObjectEncodable for PublicKey {
124        fn label(&self) -> &str {
125            "RSA PUBLIC KEY"
126        }
127        fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
128            b.extend(self.to_der());
129            Ok(())
130        }
131    }
132
133    impl ItemValueEncodable for PublicKey {
134        fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
135            out.object(self);
136            Ok(())
137        }
138    }
139}
140
141/// Protocol versions (from `tor-protover`)
142pub(crate) mod protovers {
143    use super::*;
144    use tor_protover::Protocols;
145
146    impl ItemValueEncodable for Protocols {
147        fn write_item_value_onto(&self, mut out: ItemEncoder) -> Result<(), Bug> {
148            out.args_raw_string(&self);
149            Ok(())
150        }
151    }
152}
153
154/// HS POW
155#[cfg(feature = "hs-pow-full")]
156mod hs_pow {
157    use super::*;
158    use tor_hscrypto::pow::v1;
159
160    impl ItemArgument for v1::Seed {
161        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
162            let mut seed_bytes = vec![];
163            tor_bytes::Writer::write(&mut seed_bytes, &self)?;
164            out.add_arg(&Base64Unpadded::encode_string(&seed_bytes));
165            Ok(())
166        }
167    }
168
169    impl ItemArgument for v1::Effort {
170        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
171            out.add_arg(&<Self as Into<u32>>::into(*self));
172            Ok(())
173        }
174    }
175}