Skip to main content

tor_netdoc/encode/
impls.rs

1//! Implementations of our useful traits, on external and parsing-mode types
2
3use super::*;
4
5impl ItemArgument for str {
6    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        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        }
15        out.args_raw_nonempty(&self);
16        Ok(())
17    }
18}
19
20impl ItemArgument for &str {
21    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
22        <str as ItemArgument>::write_arg_onto(self, out)
23    }
24}
25
26impl ItemArgument for Iso8601TimeSp {
27    // Unlike the macro'd formats, contains a space while still being one argument
28    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
29        let arg = self.to_string();
30        out.args_raw_nonempty(&arg.as_str());
31        Ok(())
32    }
33}
34
35impl ItemValueEncodable for Void {
36    fn write_item_value_onto(&self, _out: ItemEncoder) -> Result<(), Bug> {
37        void::unreachable(*self)
38    }
39}
40
41impl 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
50impl<T: NetdocEncodable> NetdocEncodable for Arc<T> {
51    fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
52        <T as NetdocEncodable>::encode_unsigned(self, out)
53    }
54}
55
56impl<T: NetdocEncodableFields> NetdocEncodableFields for Arc<T> {
57    fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> {
58        <T as NetdocEncodableFields>::encode_fields(self, out)
59    }
60}
61
62impl<T: ItemValueEncodable> ItemValueEncodable for Arc<T> {
63    fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
64        <T as ItemValueEncodable>::write_item_value_onto(self, out)
65    }
66}
67
68impl<T: ItemArgument> ItemArgument for Arc<T> {
69    fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
70        <T as ItemArgument>::write_arg_onto(self, out)
71    }
72}
73
74impl<T: ItemObjectEncodable> ItemObjectEncodable for Arc<T> {
75    fn label(&self) -> &str {
76        <T as ItemObjectEncodable>::label(self)
77    }
78    fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
79        <T as ItemObjectEncodable>::write_object_onto(self, b)
80    }
81}
82
83/// Types related to RSA keys
84mod rsa {
85    use super::*;
86    use tor_llcrypto::pk::rsa::PublicKey;
87
88    impl ItemObjectEncodable for PublicKey {
89        fn label(&self) -> &str {
90            "RSA PUBLIC KEY"
91        }
92        fn write_object_onto(&self, b: &mut Vec<u8>) -> Result<(), Bug> {
93            b.extend(self.to_der());
94            Ok(())
95        }
96    }
97
98    impl ItemValueEncodable for PublicKey {
99        fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> {
100            out.object(self);
101            Ok(())
102        }
103    }
104}
105
106/// Protocol versions (from `tor-protover`)
107pub(crate) mod protovers {
108    use super::*;
109    use tor_protover::Protocols;
110
111    impl ItemValueEncodable for Protocols {
112        fn write_item_value_onto(&self, mut out: ItemEncoder) -> Result<(), Bug> {
113            out.args_raw_string(&self);
114            Ok(())
115        }
116    }
117}
118
119/// HS POW
120#[cfg(feature = "hs-pow-full")]
121mod hs_pow {
122    use super::*;
123    use tor_hscrypto::pow::v1;
124
125    impl ItemArgument for v1::Seed {
126        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
127            let mut seed_bytes = vec![];
128            tor_bytes::Writer::write(&mut seed_bytes, &self)?;
129            out.add_arg(&Base64Unpadded::encode_string(&seed_bytes));
130            Ok(())
131        }
132    }
133
134    impl ItemArgument for v1::Effort {
135        fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> {
136            out.add_arg(&<Self as Into<u32>>::into(*self));
137            Ok(())
138        }
139    }
140}