route_verification_ir/
set.rs1use lazy_regex::regex_captures;
2
3use super::*;
4
5#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
7pub struct AsSet {
8 pub body: String,
9 pub members: Vec<u32>,
11 pub set_members: Vec<String>,
12 pub is_any: bool,
13}
14
15impl AsSet {
16 pub fn new(mut body: String, mut members: Vec<u32>, mut set_members: Vec<String>) -> Self {
17 body.shrink_to_fit();
18 members.shrink_to_fit();
19 members.sort_unstable();
20 set_members.shrink_to_fit();
21 Self {
22 body,
23 members,
24 set_members,
25 is_any: false,
26 }
27 }
28
29 pub fn new_any(mut body: String) -> Self {
30 body.shrink_to_fit();
31 Self {
32 body,
33 members: vec![],
34 set_members: vec![],
35 is_any: true,
36 }
37 }
38}
39
40pub fn is_route_set_name(attr: &str) -> bool {
41 regex!(formatcp!("^{}$", ROUTE_SET)).is_match(attr)
42}
43
44#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
53pub struct RouteSet {
54 pub body: String,
55 pub members: Vec<RouteSetMember>,
58}
59
60#[derive(Clone, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
61pub enum RouteSetMember {
62 RSRange(AddrPfxRange),
64 NameOp(String, RangeOperator),
66}
67
68impl std::fmt::Debug for RouteSetMember {
69 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70 use RouteSetMember::*;
71 match self {
72 RSRange(arg0) => f.debug_tuple("RSRange").field(arg0).finish(),
73 NameOp(arg0, arg1) => {
74 let mut r = f.debug_tuple("NameOp");
75 r.field(arg0);
76 if *arg1 != RangeOperator::NoOp {
77 r.field(arg1);
78 }
79 r.finish()
80 }
81 }
82 }
83}
84
85impl From<String> for RouteSetMember {
86 fn from(value: String) -> Self {
87 if let Ok(range) = value.parse() {
88 Self::RSRange(range)
89 } else if let Ok((name, op)) = try_parse_name_operator(&value) {
90 Self::NameOp(name.into(), op)
91 } else {
92 Self::NameOp(value, RangeOperator::NoOp)
93 }
94 }
95}
96
97pub fn try_parse_name_operator(s: &str) -> Result<(&str, RangeOperator)> {
98 let (_, name, operator) =
99 get_name_operator(s).context(format!("{s} is not in valid NameOp form"))?;
100 let op = operator.parse().context(format!("parsing {s} as NameOp"))?;
101 Ok((name, op))
102}
103
104pub fn get_name_operator(s: &str) -> Option<(&str, &str, &str)> {
105 regex_captures!(r"(\S+)(\^[-+\d]+)", s)
106}
107
108#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
109pub struct PeeringSet {
110 pub body: String,
111 pub peerings: Vec<Peering>,
112}
113
114#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
115pub struct FilterSet {
116 pub body: String,
117 pub filters: Vec<Filter>,
118}