1 use std::hash::{Hash, Hasher}; 2 use std::cmp::Ordering; 3 4 use crate::packet::Tag; 5 use crate::packet; 6 use crate::Packet; 7 8 /// Holds an unknown packet. 9 /// 10 /// This is used by the parser to hold packets that it doesn't know 11 /// how to process rather than abort. 12 /// 13 /// This packet effectively holds a binary blob. 14 /// 15 /// # A note on equality 16 /// 17 /// Two `Unknown` packets are considered equal if their tags and their 18 /// bodies are equal. 19 #[derive(Debug)] 20 pub struct Unknown { 21 /// CTB packet header fields. 22 pub(crate) common: packet::Common, 23 /// Packet tag. 24 tag: Tag, 25 /// Error that caused parsing or processing to abort. 26 error: anyhow::Error, 27 /// The unknown data packet is a container packet, but cannot 28 /// store packets. 29 /// 30 /// This is written when serialized, and set by the packet parser 31 /// if `buffer_unread_content` is used. 32 container: packet::Container, 33 } 34 35 impl PartialEq for Unknown { eq(&self, other: &Unknown) -> bool36 fn eq(&self, other: &Unknown) -> bool { 37 self.tag == other.tag 38 && self.container == other.container 39 } 40 } 41 42 impl Eq for Unknown { } 43 44 impl Hash for Unknown { hash<H: Hasher>(&self, state: &mut H)45 fn hash<H: Hasher>(&self, state: &mut H) { 46 self.tag.hash(state); 47 self.container.hash(state); 48 } 49 } 50 51 impl Clone for Unknown { clone(&self) -> Self52 fn clone(&self) -> Self { 53 Unknown { 54 common: self.common.clone(), 55 tag: self.tag, 56 error: anyhow::anyhow!("{}", self.error), 57 container: self.container.clone(), 58 } 59 } 60 } 61 62 63 impl Unknown { 64 /// Returns a new `Unknown` packet. new(tag: Tag, error: anyhow::Error) -> Self65 pub fn new(tag: Tag, error: anyhow::Error) -> Self { 66 Unknown { 67 common: Default::default(), 68 tag, 69 error, 70 container: packet::Container::default_unprocessed(), 71 } 72 } 73 74 /// Gets the unknown packet's tag. tag(&self) -> Tag75 pub fn tag(&self) -> Tag { 76 self.tag 77 } 78 79 /// Sets the unknown packet's tag. set_tag(&mut self, tag: Tag) -> Tag80 pub fn set_tag(&mut self, tag: Tag) -> Tag { 81 ::std::mem::replace(&mut self.tag, tag) 82 } 83 84 /// Gets the unknown packet's error. 85 /// 86 /// This is the error that caused parsing or processing to abort. error(&self) -> &anyhow::Error87 pub fn error(&self) -> &anyhow::Error { 88 &self.error 89 } 90 91 /// Sets the unknown packet's error. 92 /// 93 /// This is the error that caused parsing or processing to abort. set_error(&mut self, error: anyhow::Error) -> anyhow::Error94 pub fn set_error(&mut self, error: anyhow::Error) -> anyhow::Error { 95 ::std::mem::replace(&mut self.error, error) 96 } 97 98 /// Best effort Ord implementation. 99 /// 100 /// The Cert canonicalization needs to order Unknown packets. 101 /// However, due to potential streaming, Unknown cannot implement 102 /// Eq. This is cheating a little, we simply ignore the streaming 103 /// case. 104 pub(crate) // For cert/mod.rs best_effort_cmp(&self, other: &Unknown) -> Ordering105 fn best_effort_cmp(&self, other: &Unknown) -> Ordering { 106 self.tag.cmp(&other.tag).then_with(|| self.body().cmp(&other.body())) 107 } 108 } 109 110 impl_body_forwards!(Unknown); 111 112 impl From<Unknown> for Packet { from(s: Unknown) -> Self113 fn from(s: Unknown) -> Self { 114 Packet::Unknown(s) 115 } 116 } 117