1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
use std::fmt::{Display, Formatter, Result}; use crate::aggregate::AggPrefix; pub struct CiscoPrefixList<'a>(pub &'a str, pub &'a str, pub &'a [AggPrefix]); pub struct CiscoPrefixSet<'a>(pub &'a str, pub &'a str, pub &'a [AggPrefix]); pub struct CiscoEntryFmt<'a>(&'a AggPrefix); impl<'a> Display for CiscoEntryFmt<'a> { fn fmt(&self, f: &mut Formatter) -> Result { if self.0.valid { write!(f, "{}/{}", self.0.prefix, self.0.mask)?; if self.0.mask != self.0.min { write!(f, " ge {}", self.0.min)?; } if self.0.mask != self.0.max { write!(f, " le {}", self.0.max)?; } Ok(()) } else { write!(f, "INVALID") } } } impl<'a> Display for CiscoPrefixList<'a> { fn fmt(&self, f: &mut Formatter) -> Result { let (name, comment, list) = (self.0, self.1, self.2); writeln!( f, "no ip prefix-list {name}\n\ ip prefix-list {name} description {comment}\n\ no ipv6 prefix-list {name}\n\ ipv6 prefix-list {name} description {comment}", name = name, comment = comment, )?; for prefix in list.iter() { assert!(prefix.valid); let family = if prefix.prefix.is_ipv4() { "ip" } else { "ipv6" }; let prefix = CiscoEntryFmt(prefix); writeln!(f, "{} prefix-list {} permit {}", family, name, prefix)?; } Ok(()) } } impl<'a> Display for CiscoPrefixSet<'a> { fn fmt(&self, f: &mut Formatter) -> Result { let (name, comment, list) = (self.0, self.1, self.2); writeln!( f, "no prefix-set {name}\n\ prefix-set {name}\n # {comment}", name = name, comment = comment )?; let mut first = true; for prefix in list.iter().map(CiscoEntryFmt) { if first { write!(f, " {}", prefix)?; first = false; } else { write!(f, ",\n {}", prefix)?; } } writeln!(f, "\nend-set") } }