//! Implementations of our useful traits, on external and parsing-mode types use tor_basic_utils::intern::Intern; use super::*; impl ItemArgument for str { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { // Implements this // https://gitlab.torproject.org/tpo/core/torspec/-/merge_requests/106 if self.is_empty() || self.chars().any(|c| !c.is_ascii_graphic()) { return Err(internal!( "invalid netdoc keyword line argument syntax {:?}", self )); } out.args_raw_nonempty(&self); Ok(()) } } impl ItemArgument for &str { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { ::write_arg_onto(self, out) } } impl ItemArgument for Iso8601TimeSp { // Unlike the macro'd formats, contains a space while still being one argument fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { let arg = self.to_string(); out.args_raw_nonempty(&arg.as_str()); Ok(()) } } impl ItemValueEncodable for Void { fn write_item_value_onto(&self, _out: ItemEncoder) -> Result<(), Bug> { void::unreachable(*self) } } impl ItemObjectEncodable for Void { fn label(&self) -> &str { void::unreachable(*self) } fn write_object_onto(&self, _: &mut Vec) -> Result<(), Bug> { void::unreachable(*self) } } impl NetdocEncodable for Arc { fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> { ::encode_unsigned(self, out) } } impl NetdocEncodableFields for Arc { fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> { ::encode_fields(self, out) } } impl ItemValueEncodable for Arc { fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> { ::write_item_value_onto(self, out) } } impl ItemArgument for Arc { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { ::write_arg_onto(self, out) } } impl ItemObjectEncodable for Arc { fn label(&self) -> &str { ::label(self) } fn write_object_onto(&self, b: &mut Vec) -> Result<(), Bug> { ::write_object_onto(self, b) } } impl NetdocEncodable for Intern { fn encode_unsigned(&self, out: &mut NetdocEncoder) -> Result<(), Bug> { ::encode_unsigned(self, out) } } impl NetdocEncodableFields for Intern { fn encode_fields(&self, out: &mut NetdocEncoder) -> Result<(), Bug> { ::encode_fields(self, out) } } impl ItemValueEncodable for Intern { fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> { ::write_item_value_onto(self, out) } } impl ItemArgument for Intern { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { ::write_arg_onto(self, out) } } impl ItemObjectEncodable for Intern { fn label(&self) -> &str { ::label(self) } fn write_object_onto(&self, b: &mut Vec) -> Result<(), Bug> { ::write_object_onto(self, b) } } /// Types related to RSA keys mod rsa { use super::*; use tor_llcrypto::pk::rsa::PublicKey; impl ItemObjectEncodable for PublicKey { fn label(&self) -> &str { "RSA PUBLIC KEY" } fn write_object_onto(&self, b: &mut Vec) -> Result<(), Bug> { b.extend(self.to_der()); Ok(()) } } impl ItemValueEncodable for PublicKey { fn write_item_value_onto(&self, out: ItemEncoder) -> Result<(), Bug> { out.object(self); Ok(()) } } } /// Protocol versions (from `tor-protover`) pub(crate) mod protovers { use super::*; use tor_protover::Protocols; impl ItemValueEncodable for Protocols { fn write_item_value_onto(&self, mut out: ItemEncoder) -> Result<(), Bug> { out.args_raw_string(&self); Ok(()) } } } /// HS POW #[cfg(feature = "hs-pow-full")] mod hs_pow { use super::*; use tor_hscrypto::pow::v1; impl ItemArgument for v1::Seed { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { let mut seed_bytes = vec![]; tor_bytes::Writer::write(&mut seed_bytes, &self)?; out.add_arg(&Base64Unpadded::encode_string(&seed_bytes)); Ok(()) } } impl ItemArgument for v1::Effort { fn write_arg_onto(&self, out: &mut ItemEncoder<'_>) -> Result<(), Bug> { out.add_arg(&>::into(*self)); Ok(()) } } }