• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use super::*;
2 
3 /// "Catch all" error for all `from_slice` errors (supports automatic conversion from all
4 /// other slice errors).
5 ///
6 /// This type aggregates all errors that can be caused by decoding from a slice.
7 ///
8 /// This type can be used as a "catch all" type for errors caused by `from_slice` functions
9 /// as all errors from these functions can be converted into this type.
10 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
11 pub enum FromSliceError {
12     /// Error when parsing had to be aborted because of a length error (usually
13     /// not enough data being available).
14     Len(LenError),
15 
16     /// Error when decoding an Linux SLL header.
17     LinuxSll(linux_sll::HeaderError),
18 
19     /// Error while parsing a double vlan header.
20     DoubleVlan(double_vlan::HeaderError),
21 
22     /// Error while parsing a IP header.
23     Ip(ip::HeaderError),
24 
25     /// Error while parsing a IP authentication header.
26     IpAuth(ip_auth::HeaderError),
27 
28     /// Error while parsing a IPv4 header.
29     Ipv4(ipv4::HeaderError),
30 
31     /// Error while parsing a IPv6 header.
32     Ipv6(ipv6::HeaderError),
33 
34     /// Error while parsing a IPv6 extension header.
35     Ipv6Exts(ipv6_exts::HeaderError),
36 
37     /// Error while parsing a TCP extension header.
38     Tcp(tcp::HeaderError),
39 }
40 
41 impl FromSliceError {
len(&self) -> Option<&LenError>42     pub fn len(&self) -> Option<&LenError> {
43         match self {
44             FromSliceError::Len(err) => Some(err),
45             _ => None,
46         }
47     }
linux_sll(&self) -> Option<&linux_sll::HeaderError>48     pub fn linux_sll(&self) -> Option<&linux_sll::HeaderError> {
49         match self {
50             FromSliceError::LinuxSll(err) => Some(err),
51             _ => None,
52         }
53     }
double_vlan(&self) -> Option<&double_vlan::HeaderError>54     pub fn double_vlan(&self) -> Option<&double_vlan::HeaderError> {
55         match self {
56             FromSliceError::DoubleVlan(err) => Some(err),
57             _ => None,
58         }
59     }
ip(&self) -> Option<&ip::HeaderError>60     pub fn ip(&self) -> Option<&ip::HeaderError> {
61         match self {
62             FromSliceError::Ip(err) => Some(err),
63             _ => None,
64         }
65     }
ip_auth(&self) -> Option<&ip_auth::HeaderError>66     pub fn ip_auth(&self) -> Option<&ip_auth::HeaderError> {
67         match self {
68             FromSliceError::IpAuth(err) => Some(err),
69             _ => None,
70         }
71     }
ipv4(&self) -> Option<&ipv4::HeaderError>72     pub fn ipv4(&self) -> Option<&ipv4::HeaderError> {
73         match self {
74             FromSliceError::Ipv4(err) => Some(err),
75             _ => None,
76         }
77     }
ipv6(&self) -> Option<&ipv6::HeaderError>78     pub fn ipv6(&self) -> Option<&ipv6::HeaderError> {
79         match self {
80             FromSliceError::Ipv6(err) => Some(err),
81             _ => None,
82         }
83     }
ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError>84     pub fn ipv6_exts(&self) -> Option<&ipv6_exts::HeaderError> {
85         match self {
86             FromSliceError::Ipv6Exts(err) => Some(err),
87             _ => None,
88         }
89     }
tcp(&self) -> Option<&tcp::HeaderError>90     pub fn tcp(&self) -> Option<&tcp::HeaderError> {
91         match self {
92             FromSliceError::Tcp(err) => Some(err),
93             _ => None,
94         }
95     }
96 }
97 
98 impl core::fmt::Display for FromSliceError {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result99     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100         use FromSliceError::*;
101         match self {
102             Len(err) => err.fmt(f),
103             LinuxSll(err) => err.fmt(f),
104             DoubleVlan(err) => err.fmt(f),
105             Ip(err) => err.fmt(f),
106             IpAuth(err) => err.fmt(f),
107             Ipv4(err) => err.fmt(f),
108             Ipv6(err) => err.fmt(f),
109             Ipv6Exts(err) => err.fmt(f),
110             Tcp(err) => err.fmt(f),
111         }
112     }
113 }
114 
115 #[cfg(feature = "std")]
116 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
117 impl std::error::Error for FromSliceError {
source(&self) -> Option<&(dyn std::error::Error + 'static)>118     fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
119         match self {
120             FromSliceError::Len(err) => Some(err),
121             FromSliceError::LinuxSll(err) => Some(err),
122             FromSliceError::DoubleVlan(err) => Some(err),
123             FromSliceError::Ip(err) => Some(err),
124             FromSliceError::IpAuth(err) => Some(err),
125             FromSliceError::Ipv4(err) => Some(err),
126             FromSliceError::Ipv6(err) => Some(err),
127             FromSliceError::Ipv6Exts(err) => Some(err),
128             FromSliceError::Tcp(err) => Some(err),
129         }
130     }
131 }
132 
133 // len error conversions
134 
135 impl From<LenError> for FromSliceError {
from(value: LenError) -> Self136     fn from(value: LenError) -> Self {
137         FromSliceError::Len(value)
138     }
139 }
140 
141 // linux sll conversions
142 
143 impl From<linux_sll::HeaderError> for FromSliceError {
from(value: linux_sll::HeaderError) -> Self144     fn from(value: linux_sll::HeaderError) -> Self {
145         FromSliceError::LinuxSll(value)
146     }
147 }
148 
149 impl From<linux_sll::HeaderSliceError> for FromSliceError {
from(value: linux_sll::HeaderSliceError) -> Self150     fn from(value: linux_sll::HeaderSliceError) -> Self {
151         use linux_sll::HeaderSliceError::*;
152         match value {
153             Len(err) => FromSliceError::Len(err),
154             Content(err) => FromSliceError::LinuxSll(err),
155         }
156     }
157 }
158 
159 // double vlan error conversions
160 
161 impl From<double_vlan::HeaderError> for FromSliceError {
from(value: double_vlan::HeaderError) -> Self162     fn from(value: double_vlan::HeaderError) -> Self {
163         FromSliceError::DoubleVlan(value)
164     }
165 }
166 
167 impl From<double_vlan::HeaderSliceError> for FromSliceError {
from(value: double_vlan::HeaderSliceError) -> Self168     fn from(value: double_vlan::HeaderSliceError) -> Self {
169         use double_vlan::HeaderSliceError::*;
170         match value {
171             Len(err) => FromSliceError::Len(err),
172             Content(err) => FromSliceError::DoubleVlan(err),
173         }
174     }
175 }
176 
177 // ip error conversions
178 
179 impl From<ip::HeaderError> for FromSliceError {
from(value: ip::HeaderError) -> Self180     fn from(value: ip::HeaderError) -> Self {
181         FromSliceError::Ip(value)
182     }
183 }
184 
185 impl From<ip::HeadersError> for FromSliceError {
from(value: ip::HeadersError) -> Self186     fn from(value: ip::HeadersError) -> Self {
187         match value {
188             ip::HeadersError::Ip(err) => FromSliceError::Ip(err),
189             ip::HeadersError::Ipv4Ext(err) => FromSliceError::IpAuth(err),
190             ip::HeadersError::Ipv6Ext(err) => FromSliceError::Ipv6Exts(err),
191         }
192     }
193 }
194 
195 impl From<ip::HeadersSliceError> for FromSliceError {
from(value: ip::HeadersSliceError) -> Self196     fn from(value: ip::HeadersSliceError) -> Self {
197         use ip::HeadersSliceError::*;
198         match value {
199             Len(err) => FromSliceError::Len(err),
200             Content(err) => err.into(),
201         }
202     }
203 }
204 
205 impl From<ip::SliceError> for FromSliceError {
from(value: ip::SliceError) -> Self206     fn from(value: ip::SliceError) -> Self {
207         use ip::SliceError::*;
208         match value {
209             Len(err) => FromSliceError::Len(err),
210             IpHeaders(err) => err.into(),
211         }
212     }
213 }
214 
215 // ip auth error conversions
216 
217 impl From<ip_auth::HeaderError> for FromSliceError {
from(value: ip_auth::HeaderError) -> Self218     fn from(value: ip_auth::HeaderError) -> Self {
219         FromSliceError::IpAuth(value)
220     }
221 }
222 
223 impl From<ip_auth::HeaderSliceError> for FromSliceError {
from(value: ip_auth::HeaderSliceError) -> Self224     fn from(value: ip_auth::HeaderSliceError) -> Self {
225         use ip_auth::HeaderSliceError::*;
226         match value {
227             Len(err) => FromSliceError::Len(err),
228             Content(err) => FromSliceError::IpAuth(err),
229         }
230     }
231 }
232 
233 // ipv4 error conversions
234 
235 impl From<ipv4::HeaderError> for FromSliceError {
from(value: ipv4::HeaderError) -> Self236     fn from(value: ipv4::HeaderError) -> Self {
237         FromSliceError::Ipv4(value)
238     }
239 }
240 
241 impl From<ipv4::HeaderSliceError> for FromSliceError {
from(value: ipv4::HeaderSliceError) -> Self242     fn from(value: ipv4::HeaderSliceError) -> Self {
243         use ipv4::HeaderSliceError::*;
244         match value {
245             Len(err) => FromSliceError::Len(err),
246             Content(err) => FromSliceError::Ipv4(err),
247         }
248     }
249 }
250 
251 impl From<ipv4::SliceError> for FromSliceError {
from(value: ipv4::SliceError) -> Self252     fn from(value: ipv4::SliceError) -> Self {
253         use ipv4::SliceError::*;
254         match value {
255             Len(err) => FromSliceError::Len(err),
256             Header(err) => FromSliceError::Ipv4(err),
257             Exts(err) => FromSliceError::IpAuth(err),
258         }
259     }
260 }
261 
262 // ipv6 error conversions
263 
264 impl From<ipv6::HeaderError> for FromSliceError {
from(value: ipv6::HeaderError) -> Self265     fn from(value: ipv6::HeaderError) -> Self {
266         FromSliceError::Ipv6(value)
267     }
268 }
269 
270 impl From<ipv6::HeaderSliceError> for FromSliceError {
from(value: ipv6::HeaderSliceError) -> Self271     fn from(value: ipv6::HeaderSliceError) -> Self {
272         use ipv6::HeaderSliceError::*;
273         match value {
274             Len(err) => FromSliceError::Len(err),
275             Content(err) => FromSliceError::Ipv6(err),
276         }
277     }
278 }
279 
280 impl From<ipv6::SliceError> for FromSliceError {
from(value: ipv6::SliceError) -> Self281     fn from(value: ipv6::SliceError) -> Self {
282         use ipv6::SliceError::*;
283         match value {
284             Len(err) => FromSliceError::Len(err),
285             Header(err) => FromSliceError::Ipv6(err),
286             Exts(err) => FromSliceError::Ipv6Exts(err),
287         }
288     }
289 }
290 
291 // ipv6 exts error conversions
292 
293 impl From<ipv6_exts::HeaderError> for FromSliceError {
from(value: ipv6_exts::HeaderError) -> Self294     fn from(value: ipv6_exts::HeaderError) -> Self {
295         FromSliceError::Ipv6Exts(value)
296     }
297 }
298 
299 impl From<ipv6_exts::HeaderSliceError> for FromSliceError {
from(value: ipv6_exts::HeaderSliceError) -> Self300     fn from(value: ipv6_exts::HeaderSliceError) -> Self {
301         use ipv6_exts::HeaderSliceError::*;
302         match value {
303             Len(err) => FromSliceError::Len(err),
304             Content(err) => FromSliceError::Ipv6Exts(err),
305         }
306     }
307 }
308 
309 // packet error conversions
310 
311 impl From<packet::SliceError> for FromSliceError {
from(value: packet::SliceError) -> Self312     fn from(value: packet::SliceError) -> Self {
313         use packet::SliceError::*;
314         match value {
315             Len(err) => FromSliceError::Len(err),
316             LinuxSll(err) => FromSliceError::LinuxSll(err),
317             Ip(err) => FromSliceError::Ip(err),
318             Ipv4(err) => FromSliceError::Ipv4(err),
319             Ipv6(err) => FromSliceError::Ipv6(err),
320             Ipv4Exts(err) => FromSliceError::IpAuth(err),
321             Ipv6Exts(err) => FromSliceError::Ipv6Exts(err),
322             Tcp(err) => FromSliceError::Tcp(err),
323         }
324     }
325 }
326 
327 // tcp error conversions
328 
329 impl From<tcp::HeaderError> for FromSliceError {
from(value: tcp::HeaderError) -> Self330     fn from(value: tcp::HeaderError) -> Self {
331         FromSliceError::Tcp(value)
332     }
333 }
334 
335 impl From<tcp::HeaderSliceError> for FromSliceError {
from(value: tcp::HeaderSliceError) -> Self336     fn from(value: tcp::HeaderSliceError) -> Self {
337         use tcp::HeaderSliceError::*;
338         match value {
339             Len(err) => FromSliceError::Len(err),
340             Content(err) => FromSliceError::Tcp(err),
341         }
342     }
343 }
344 
345 #[cfg(test)]
346 mod tests {
347     use crate::{ArpHardwareId, EtherType, LenSource};
348 
349     use super::{FromSliceError::*, *};
350     use core::hash::{Hash, Hasher};
351     use std::collections::hash_map::DefaultHasher;
352     use std::error::Error;
353     use std::format;
354 
355     #[test]
clone_eq_hash()356     fn clone_eq_hash() {
357         let value = Len(LenError {
358             required_len: 0,
359             len: 0,
360             len_source: LenSource::Slice,
361             layer: Layer::Icmpv4,
362             layer_start_offset: 0,
363         });
364         assert_eq!(value, value.clone());
365         let h1 = {
366             let mut h = DefaultHasher::new();
367             value.hash(&mut h);
368             h.finish()
369         };
370         let h2 = {
371             let mut h = DefaultHasher::new();
372             value.clone().hash(&mut h);
373             h.finish()
374         };
375         assert_eq!(h1, h2);
376     }
377 
378     #[test]
debug_source()379     fn debug_source() {
380         let test_values: [(&str, FromSliceError); 8] = [
381             (
382                 "Len",
383                 Len(LenError {
384                     required_len: 0,
385                     len: 0,
386                     len_source: LenSource::Slice,
387                     layer: Layer::Icmpv4,
388                     layer_start_offset: 0,
389                 }),
390             ),
391             (
392                 "DoubleVlan",
393                 DoubleVlan(double_vlan::HeaderError::NonVlanEtherType {
394                     unexpected_ether_type: EtherType(123),
395                 }),
396             ),
397             (
398                 "Ip",
399                 Ip(ip::HeaderError::UnsupportedIpVersion {
400                     version_number: 123,
401                 }),
402             ),
403             ("IpAuth", IpAuth(ip_auth::HeaderError::ZeroPayloadLen)),
404             (
405                 "Ipv4",
406                 Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }),
407             ),
408             (
409                 "Ipv6",
410                 Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }),
411             ),
412             (
413                 "Ipv6Exts",
414                 Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart),
415             ),
416             (
417                 "Tcp",
418                 Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }),
419             ),
420         ];
421         for (prefix, value) in &test_values {
422             // display
423             assert_eq!(
424                 format!("{:?}", value),
425                 format!("{}({:?})", prefix, value.source().unwrap())
426             );
427         }
428     }
429 
430     #[test]
display_source()431     fn display_source() {
432         let test_values: [FromSliceError; 9] = [
433             Len(LenError {
434                 required_len: 0,
435                 len: 0,
436                 len_source: LenSource::Slice,
437                 layer: Layer::Icmpv4,
438                 layer_start_offset: 0,
439             }),
440             LinuxSll(linux_sll::HeaderError::UnsupportedArpHardwareId {
441                 arp_hardware_type: ArpHardwareId::ETHERNET,
442             }),
443             DoubleVlan(double_vlan::HeaderError::NonVlanEtherType {
444                 unexpected_ether_type: EtherType(123),
445             }),
446             Ip(ip::HeaderError::UnsupportedIpVersion {
447                 version_number: 123,
448             }),
449             IpAuth(ip_auth::HeaderError::ZeroPayloadLen),
450             Ipv4(ipv4::HeaderError::UnexpectedVersion { version_number: 1 }),
451             Ipv6(ipv6::HeaderError::UnexpectedVersion { version_number: 1 }),
452             Ipv6Exts(ipv6_exts::HeaderError::HopByHopNotAtStart),
453             Tcp(tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 }),
454         ];
455         for value in &test_values {
456             // display
457             assert_eq!(format!("{}", value), format!("{}", value.source().unwrap()));
458         }
459     }
460 
461     #[test]
accessors()462     fn accessors() {
463         use FromSliceError::*;
464         let len_error = || LenError {
465             required_len: 0,
466             len: 0,
467             len_source: LenSource::Slice,
468             layer: Layer::Icmpv4,
469             layer_start_offset: 0,
470         };
471         let linux_sll_error = || linux_sll::HeaderError::UnsupportedArpHardwareId {
472             arp_hardware_type: ArpHardwareId::ETHERNET,
473         };
474         let double_vlan_error = || double_vlan::HeaderError::NonVlanEtherType {
475             unexpected_ether_type: EtherType(1),
476         };
477         let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 };
478         let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
479         let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
480         let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen;
481         let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
482         let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
483 
484         // len
485         assert_eq!(Len(len_error()).len(), Some(&len_error()));
486         assert_eq!(Ipv4(ipv4_error()).len(), None);
487 
488         // linux_sll
489         assert_eq!(
490             LinuxSll(linux_sll_error()).linux_sll(),
491             Some(&linux_sll_error())
492         );
493         assert_eq!(Ipv4(ipv4_error()).linux_sll(), None);
494 
495         // double_vlan
496         assert_eq!(
497             DoubleVlan(double_vlan_error()).double_vlan(),
498             Some(&double_vlan_error())
499         );
500         assert_eq!(Ipv4(ipv4_error()).double_vlan(), None);
501 
502         // ip
503         assert_eq!(Ip(ip_error()).ip(), Some(&ip_error()));
504         assert_eq!(Ipv4(ipv4_error()).ip(), None);
505 
506         // ip_auth
507         assert_eq!(IpAuth(ip_auth_error()).ip_auth(), Some(&ip_auth_error()));
508         assert_eq!(Ipv4(ipv4_error()).ip_auth(), None);
509 
510         // ipv4
511         assert_eq!(Ipv4(ipv4_error()).ipv4(), Some(&ipv4_error()));
512         assert_eq!(IpAuth(ip_auth_error()).ipv4(), None);
513 
514         // ipv6
515         assert_eq!(Ipv6(ipv6_error()).ipv6(), Some(&ipv6_error()));
516         assert_eq!(IpAuth(ip_auth_error()).ipv6(), None);
517 
518         // ipv6_exts
519         assert_eq!(
520             Ipv6Exts(ipv6_exts_error()).ipv6_exts(),
521             Some(&ipv6_exts_error())
522         );
523         assert_eq!(IpAuth(ip_auth_error()).ipv6_exts(), None);
524 
525         // tcp
526         assert_eq!(Tcp(tcp_error()).tcp(), Some(&tcp_error()));
527         assert_eq!(IpAuth(ip_auth_error()).tcp(), None);
528     }
529 
530     #[test]
from()531     fn from() {
532         let len_error = || -> LenError {
533             LenError {
534                 required_len: 0,
535                 len: 0,
536                 len_source: LenSource::Slice,
537                 layer: Layer::Icmpv4,
538                 layer_start_offset: 0,
539             }
540         };
541 
542         // len
543         assert_eq!(
544             &len_error(),
545             FromSliceError::from(len_error()).len().unwrap()
546         );
547 
548         // linux sll
549         {
550             let header_error = || linux_sll::HeaderError::UnsupportedArpHardwareId {
551                 arp_hardware_type: ArpHardwareId::ETHERNET,
552             };
553             assert_eq!(
554                 &header_error(),
555                 FromSliceError::from(header_error()).linux_sll().unwrap()
556             );
557             assert_eq!(
558                 &header_error(),
559                 FromSliceError::from(linux_sll::HeaderSliceError::Content(header_error()))
560                     .linux_sll()
561                     .unwrap()
562             );
563             assert_eq!(
564                 &len_error(),
565                 FromSliceError::from(linux_sll::HeaderSliceError::Len(len_error()))
566                     .len()
567                     .unwrap()
568             );
569             assert_eq!(
570                 &header_error(),
571                 FromSliceError::from(linux_sll::HeaderSliceError::Content(header_error()))
572                     .linux_sll()
573                     .unwrap()
574             );
575         }
576 
577         // double vlan errors
578         {
579             let header_error = || double_vlan::HeaderError::NonVlanEtherType {
580                 unexpected_ether_type: EtherType(123),
581             };
582             assert_eq!(
583                 &header_error(),
584                 FromSliceError::from(header_error()).double_vlan().unwrap()
585             );
586             assert_eq!(
587                 &header_error(),
588                 FromSliceError::from(double_vlan::HeaderSliceError::Content(header_error()))
589                     .double_vlan()
590                     .unwrap()
591             );
592             assert_eq!(
593                 &len_error(),
594                 FromSliceError::from(double_vlan::HeaderSliceError::Len(len_error()))
595                     .len()
596                     .unwrap()
597             );
598             assert_eq!(
599                 &header_error(),
600                 FromSliceError::from(double_vlan::HeaderSliceError::Content(header_error()))
601                     .double_vlan()
602                     .unwrap()
603             );
604         }
605 
606         // ip errors
607         {
608             let header_error = || ip::HeaderError::UnsupportedIpVersion {
609                 version_number: 123,
610             };
611             assert_eq!(
612                 &header_error(),
613                 FromSliceError::from(header_error()).ip().unwrap()
614             );
615             assert_eq!(
616                 &header_error(),
617                 FromSliceError::from(ip::HeadersSliceError::Content(ip::HeadersError::Ip(
618                     header_error()
619                 )))
620                 .ip()
621                 .unwrap()
622             );
623             assert_eq!(
624                 &len_error(),
625                 FromSliceError::from(ip::HeadersSliceError::Len(len_error()))
626                     .len()
627                     .unwrap()
628             );
629             assert_eq!(
630                 &len_error(),
631                 FromSliceError::from(ip::SliceError::Len(len_error()))
632                     .len()
633                     .unwrap()
634             );
635             assert_eq!(
636                 &header_error(),
637                 FromSliceError::from(ip::SliceError::IpHeaders(ip::HeadersError::Ip(
638                     header_error()
639                 )))
640                 .ip()
641                 .unwrap()
642             );
643         }
644 
645         // ip auth errors
646         {
647             let header_error = || ip_auth::HeaderError::ZeroPayloadLen;
648             assert_eq!(
649                 &header_error(),
650                 FromSliceError::from(header_error()).ip_auth().unwrap()
651             );
652             assert_eq!(
653                 &header_error(),
654                 FromSliceError::from(ip_auth::HeaderSliceError::Content(header_error()))
655                     .ip_auth()
656                     .unwrap()
657             );
658             assert_eq!(
659                 &len_error(),
660                 FromSliceError::from(ip_auth::HeaderSliceError::Len(len_error()))
661                     .len()
662                     .unwrap()
663             );
664             assert_eq!(
665                 &header_error(),
666                 FromSliceError::from(ip_auth::HeaderSliceError::Content(header_error()))
667                     .ip_auth()
668                     .unwrap()
669             );
670         }
671 
672         // ipv4 errors
673         {
674             let header_error = || ipv4::HeaderError::UnexpectedVersion {
675                 version_number: 123,
676             };
677             let exts_error = || ip_auth::HeaderError::ZeroPayloadLen;
678             assert_eq!(
679                 &header_error(),
680                 FromSliceError::from(header_error()).ipv4().unwrap()
681             );
682             assert_eq!(
683                 &header_error(),
684                 FromSliceError::from(ipv4::HeaderSliceError::Content(header_error()))
685                     .ipv4()
686                     .unwrap()
687             );
688             assert_eq!(
689                 &len_error(),
690                 FromSliceError::from(ipv4::HeaderSliceError::Len(len_error()))
691                     .len()
692                     .unwrap()
693             );
694             assert_eq!(
695                 &header_error(),
696                 FromSliceError::from(ipv4::HeaderSliceError::Content(header_error()))
697                     .ipv4()
698                     .unwrap()
699             );
700             assert_eq!(
701                 &len_error(),
702                 FromSliceError::from(ipv4::SliceError::Len(len_error()))
703                     .len()
704                     .unwrap()
705             );
706             assert_eq!(
707                 &header_error(),
708                 FromSliceError::from(ipv4::SliceError::Header(header_error()))
709                     .ipv4()
710                     .unwrap()
711             );
712             assert_eq!(
713                 &exts_error(),
714                 FromSliceError::from(ipv4::SliceError::Exts(exts_error()))
715                     .ip_auth()
716                     .unwrap()
717             );
718         }
719 
720         // ipv6 errors
721         {
722             let header_error = || ipv6::HeaderError::UnexpectedVersion {
723                 version_number: 123,
724             };
725             let exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
726             assert_eq!(
727                 &header_error(),
728                 FromSliceError::from(header_error()).ipv6().unwrap()
729             );
730             assert_eq!(
731                 &header_error(),
732                 FromSliceError::from(ipv6::HeaderSliceError::Content(header_error()))
733                     .ipv6()
734                     .unwrap()
735             );
736             assert_eq!(
737                 &len_error(),
738                 FromSliceError::from(ipv6::HeaderSliceError::Len(len_error()))
739                     .len()
740                     .unwrap()
741             );
742             assert_eq!(
743                 &header_error(),
744                 FromSliceError::from(ipv6::HeaderSliceError::Content(header_error()))
745                     .ipv6()
746                     .unwrap()
747             );
748             assert_eq!(
749                 &len_error(),
750                 FromSliceError::from(ipv6::SliceError::Len(len_error()))
751                     .len()
752                     .unwrap()
753             );
754             assert_eq!(
755                 &header_error(),
756                 FromSliceError::from(ipv6::SliceError::Header(header_error()))
757                     .ipv6()
758                     .unwrap()
759             );
760             assert_eq!(
761                 &exts_error(),
762                 FromSliceError::from(ipv6::SliceError::Exts(exts_error()))
763                     .ipv6_exts()
764                     .unwrap()
765             );
766         }
767 
768         // ipv6 exts errors
769         {
770             let header_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
771             assert_eq!(
772                 &header_error(),
773                 FromSliceError::from(header_error()).ipv6_exts().unwrap()
774             );
775             assert_eq!(
776                 &header_error(),
777                 FromSliceError::from(ipv6_exts::HeaderSliceError::Content(header_error()))
778                     .ipv6_exts()
779                     .unwrap()
780             );
781             assert_eq!(
782                 &len_error(),
783                 FromSliceError::from(ipv6_exts::HeaderSliceError::Len(len_error()))
784                     .len()
785                     .unwrap()
786             );
787             assert_eq!(
788                 &header_error(),
789                 FromSliceError::from(ipv6_exts::HeaderSliceError::Content(header_error()))
790                     .ipv6_exts()
791                     .unwrap()
792             );
793         }
794 
795         // packet error
796         {
797             let ip_error = || ip::HeaderError::UnsupportedIpVersion { version_number: 0 };
798             let ipv4_error = || ipv4::HeaderError::UnexpectedVersion { version_number: 1 };
799             let ipv6_error = || ipv6::HeaderError::UnexpectedVersion { version_number: 1 };
800             let ip_auth_error = || ip_auth::HeaderError::ZeroPayloadLen;
801             let ipv6_exts_error = || ipv6_exts::HeaderError::HopByHopNotAtStart;
802             let tcp_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
803 
804             // SliceError
805             assert_eq!(
806                 &len_error(),
807                 FromSliceError::from(packet::SliceError::Len(len_error()))
808                     .len()
809                     .unwrap()
810             );
811             assert_eq!(
812                 &ip_error(),
813                 FromSliceError::from(packet::SliceError::Ip(ip_error()))
814                     .ip()
815                     .unwrap()
816             );
817             assert_eq!(
818                 &ipv4_error(),
819                 FromSliceError::from(packet::SliceError::Ipv4(ipv4_error()))
820                     .ipv4()
821                     .unwrap()
822             );
823             assert_eq!(
824                 &ipv6_error(),
825                 FromSliceError::from(packet::SliceError::Ipv6(ipv6_error()))
826                     .ipv6()
827                     .unwrap()
828             );
829             assert_eq!(
830                 &ip_auth_error(),
831                 FromSliceError::from(packet::SliceError::Ipv4Exts(ip_auth_error()))
832                     .ip_auth()
833                     .unwrap()
834             );
835             assert_eq!(
836                 &ipv6_exts_error(),
837                 FromSliceError::from(packet::SliceError::Ipv6Exts(ipv6_exts_error()))
838                     .ipv6_exts()
839                     .unwrap()
840             );
841             assert_eq!(
842                 &tcp_error(),
843                 FromSliceError::from(packet::SliceError::Tcp(tcp_error()))
844                     .tcp()
845                     .unwrap()
846             );
847         }
848 
849         // tcp errors
850         {
851             let header_error = || tcp::HeaderError::DataOffsetTooSmall { data_offset: 1 };
852             assert_eq!(
853                 &header_error(),
854                 FromSliceError::from(header_error()).tcp().unwrap()
855             );
856             assert_eq!(
857                 &header_error(),
858                 FromSliceError::from(tcp::HeaderSliceError::Content(header_error()))
859                     .tcp()
860                     .unwrap()
861             );
862             assert_eq!(
863                 &len_error(),
864                 FromSliceError::from(tcp::HeaderSliceError::Len(len_error()))
865                     .len()
866                     .unwrap()
867             );
868             assert_eq!(
869                 &header_error(),
870                 FromSliceError::from(tcp::HeaderSliceError::Content(header_error()))
871                     .tcp()
872                     .unwrap()
873             );
874         }
875     }
876 } // mod tests
877