diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs index a9d5013c6d..5ecbc2969c 100644 --- a/src/rust/protover/ffi.rs +++ b/src/rust/protover/ffi.rs @@ -9,27 +9,29 @@ use libc::{c_char, c_int, uint32_t}; use std::ffi::CStr; use std::ffi::CString; -use protover::*; use smartlist::*; use tor_allocate::allocate_and_copy_string; +use errors::ProtoverError; +use protover::*; + /// Translate C enums to Rust Proto enums, using the integer value of the C -/// enum to map to its associated Rust enum +/// enum to map to its associated Rust enum. /// /// C_RUST_COUPLED: src/or/protover.h `protocol_type_t` -fn translate_to_rust(c_proto: uint32_t) -> Result { +fn translate_to_rust(c_proto: uint32_t) -> Result { match c_proto { - 0 => Ok(Proto::Link), - 1 => Ok(Proto::LinkAuth), - 2 => Ok(Proto::Relay), - 3 => Ok(Proto::DirCache), - 4 => Ok(Proto::HSDir), - 5 => Ok(Proto::HSIntro), - 6 => Ok(Proto::HSRend), - 7 => Ok(Proto::Desc), - 8 => Ok(Proto::Microdesc), - 9 => Ok(Proto::Cons), - _ => Err("Invalid protocol type"), + 0 => Ok(Protocol::Link), + 1 => Ok(Protocol::LinkAuth), + 2 => Ok(Protocol::Relay), + 3 => Ok(Protocol::DirCache), + 4 => Ok(Protocol::HSDir), + 5 => Ok(Protocol::HSIntro), + 6 => Ok(Protocol::HSRend), + 7 => Ok(Protocol::Desc), + 8 => Ok(Protocol::Microdesc), + 9 => Ok(Protocol::Cons), + _ => Err(ProtoverError::UnknownProtocol), } } diff --git a/src/rust/protover/protover.rs b/src/rust/protover/protover.rs index ae6931d058..30d9e0a897 100644 --- a/src/rust/protover/protover.rs +++ b/src/rust/protover/protover.rs @@ -32,8 +32,8 @@ pub(crate) const MAX_PROTOCOLS_TO_EXPAND: usize = (1<<16); /// Known subprotocols in Tor. Indicates which subprotocol a relay supports. /// /// C_RUST_COUPLED: src/or/protover.h `protocol_type_t` -#[derive(Hash, Eq, PartialEq, Debug)] -pub enum Proto { +#[derive(Clone, Hash, Eq, PartialEq, Debug)] +pub enum Protocol { Cons, Desc, DirCache, @@ -46,7 +46,7 @@ pub enum Proto { Relay, } -impl fmt::Display for Proto { +impl fmt::Display for Protocol { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{:?}", self) } @@ -56,26 +56,51 @@ impl fmt::Display for Proto { /// Error if the string is an unrecognized protocol name. /// /// C_RUST_COUPLED: src/or/protover.c `PROTOCOL_NAMES` -impl FromStr for Proto { +impl FromStr for Protocol { type Err = ProtoverError; fn from_str(s: &str) -> Result { match s { - "Cons" => Ok(Proto::Cons), - "Desc" => Ok(Proto::Desc), - "DirCache" => Ok(Proto::DirCache), - "HSDir" => Ok(Proto::HSDir), - "HSIntro" => Ok(Proto::HSIntro), - "HSRend" => Ok(Proto::HSRend), - "Link" => Ok(Proto::Link), - "LinkAuth" => Ok(Proto::LinkAuth), - "Microdesc" => Ok(Proto::Microdesc), - "Relay" => Ok(Proto::Relay), + "Cons" => Ok(Protocol::Cons), + "Desc" => Ok(Protocol::Desc), + "DirCache" => Ok(Protocol::DirCache), + "HSDir" => Ok(Protocol::HSDir), + "HSIntro" => Ok(Protocol::HSIntro), + "HSRend" => Ok(Protocol::HSRend), + "Link" => Ok(Protocol::Link), + "LinkAuth" => Ok(Protocol::LinkAuth), + "Microdesc" => Ok(Protocol::Microdesc), + "Relay" => Ok(Protocol::Relay), _ => Err(ProtoverError::UnknownProtocol), } } } +/// A protocol string which is not one of the `Protocols` we currently know +/// about. +#[derive(Clone, Debug, Hash, Eq, PartialEq)] +pub struct UnknownProtocol(String); + +impl fmt::Display for UnknownProtocol { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl FromStr for UnknownProtocol { + type Err = ProtoverError; + + fn from_str(s: &str) -> Result { + Ok(UnknownProtocol(s.to_string())) + } +} + +impl From for UnknownProtocol { + fn from(p: Protocol) -> UnknownProtocol { + UnknownProtocol(p.to_string()) + } +} + /// Get a CStr representation of current supported protocols, for /// passing to C, or for converting to a `&str` for Rust. ///