use crate::err::BgpModelsError;
use ipnet::IpNet;
use serde::{Deserialize, Serialize, Serializer};
use std::fmt::{Display, Formatter};
use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;
#[derive(Debug, Clone, Serialize, Copy)]
pub struct AddrMeta {
pub afi: Afi,
pub asn_len: AsnLength,
}
#[derive(Debug, Clone, Serialize, Copy, Deserialize, PartialEq, Eq)]
pub enum AsnLength {
Bits16,
Bits32,
}
#[derive(Debug, Clone, Copy, Eq)]
pub struct Asn {
pub asn: u32,
pub len: AsnLength,
}
impl PartialEq for Asn {
fn eq(&self, other: &Self) -> bool {
self.asn == other.asn
}
}
impl PartialEq<i32> for Asn {
fn eq(&self, other: &i32) -> bool {
self.asn as i32 == *other
}
}
impl PartialEq<u32> for Asn {
fn eq(&self, other: &u32) -> bool {
self.asn == *other
}
}
impl From<u32> for Asn {
fn from(v: u32) -> Self {
Asn {
asn: v,
len: AsnLength::Bits32,
}
}
}
impl From<i32> for Asn {
fn from(v: i32) -> Self {
Asn {
asn: v as u32,
len: AsnLength::Bits32,
}
}
}
impl From<Asn> for i32 {
fn from(val: Asn) -> Self {
val.asn as i32
}
}
impl From<Asn> for u32 {
fn from(value: Asn) -> Self {
value.asn
}
}
impl Serialize for Asn {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_u32(self.asn)
}
}
#[derive(Debug, PartialEq, Primitive, Clone, Copy, Serialize, Eq)]
pub enum Afi {
Ipv4 = 1,
Ipv6 = 2,
}
#[derive(Debug, PartialEq, Primitive, Clone, Copy, Serialize, Eq)]
pub enum Safi {
Unicast = 1,
Multicast = 2,
UnicastMulticast = 3,
}
#[derive(Debug, PartialEq, Copy, Clone, Serialize, Eq)]
pub enum NextHopAddress {
Ipv4(Ipv4Addr),
Ipv6(Ipv6Addr),
Ipv6LinkLocal(Ipv6Addr, Ipv6Addr),
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct NetworkPrefix {
pub prefix: IpNet,
pub path_id: u32,
}
impl Serialize for NetworkPrefix {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.to_string().as_str())
}
}
impl FromStr for NetworkPrefix {
type Err = BgpModelsError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let prefix = IpNet::from_str(s)?;
Ok(NetworkPrefix { prefix, path_id: 0 })
}
}
impl NetworkPrefix {
pub fn new(prefix: IpNet, path_id: u32) -> NetworkPrefix {
NetworkPrefix { prefix, path_id }
}
}
impl Display for NetworkPrefix {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.prefix)
}
}
impl Display for Asn {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.asn)
}
}