use crate::errors::{load_methods, modules};
use crate::{BgpkitCommonsError, Result};
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize, Serializer};
use std::cmp::Ordering;
use std::fmt::{Display, Formatter};
mod peers;
mod riperis;
mod routeviews;
use crate::BgpkitCommons;
pub use peers::{MrtCollectorPeer, get_mrt_collector_peers};
pub use riperis::get_riperis_collectors;
pub use routeviews::get_routeviews_collectors;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub enum MrtCollectorProject {
RouteViews,
RipeRis,
}
fn serialize_project<S>(
project: &MrtCollectorProject,
serializer: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(match project {
MrtCollectorProject::RouteViews => "routeview",
MrtCollectorProject::RipeRis => "riperis",
})
}
impl Display for MrtCollectorProject {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
MrtCollectorProject::RouteViews => {
write!(f, "routeviews")
}
MrtCollectorProject::RipeRis => {
write!(f, "riperis")
}
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct MrtCollector {
pub name: String,
#[serde(serialize_with = "serialize_project")]
pub project: MrtCollectorProject,
pub data_url: String,
pub activated_on: NaiveDateTime,
pub deactivated_on: Option<NaiveDateTime>,
pub country: String,
}
pub trait ToMrtCollector {
fn to_mrt_collector(&self) -> Option<MrtCollector>;
}
impl PartialOrd<Self> for MrtCollector {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for MrtCollector {
fn cmp(&self, other: &Self) -> Ordering {
self.activated_on.cmp(&other.activated_on)
}
}
pub fn get_all_collectors() -> Result<Vec<MrtCollector>> {
let mut collectors = vec![];
collectors.extend(get_routeviews_collectors()?);
collectors.extend(get_riperis_collectors()?);
Ok(collectors)
}
impl BgpkitCommons {
pub fn mrt_collectors_all(&self) -> Result<Vec<MrtCollector>> {
if self.mrt_collectors.is_none() {
return Err(BgpkitCommonsError::module_not_loaded(
modules::MRT_COLLECTORS,
load_methods::LOAD_MRT_COLLECTORS,
));
}
Ok(self.mrt_collectors.clone().unwrap())
}
pub fn mrt_collectors_by_name(&self, name: &str) -> Result<Option<MrtCollector>> {
if self.mrt_collectors.is_none() {
return Err(BgpkitCommonsError::module_not_loaded(
modules::MRT_COLLECTORS,
load_methods::LOAD_MRT_COLLECTORS,
));
}
Ok(self
.mrt_collectors
.as_ref()
.unwrap()
.iter()
.find(|x| x.name == name)
.cloned())
}
pub fn mrt_collectors_by_country(&self, country: &str) -> Result<Vec<MrtCollector>> {
match &self.mrt_collectors {
Some(c) => Ok(c.iter().filter(|x| x.country == country).cloned().collect()),
None => Err(BgpkitCommonsError::module_not_loaded(
modules::MRT_COLLECTORS,
load_methods::LOAD_MRT_COLLECTORS,
)),
}
}
pub fn mrt_collector_peers_all(&self) -> Result<Vec<MrtCollectorPeer>> {
if self.mrt_collector_peers.is_none() {
return Err(BgpkitCommonsError::module_not_loaded(
modules::MRT_COLLECTOR_PEERS,
load_methods::LOAD_MRT_COLLECTOR_PEERS,
));
}
Ok(self.mrt_collector_peers.clone().unwrap())
}
pub fn mrt_collector_peers_full_feed(&self) -> Result<Vec<MrtCollectorPeer>> {
if self.mrt_collector_peers.is_none() {
return Err(BgpkitCommonsError::module_not_loaded(
modules::MRT_COLLECTOR_PEERS,
load_methods::LOAD_MRT_COLLECTOR_PEERS,
));
}
Ok(self
.mrt_collector_peers
.as_ref()
.unwrap()
.iter()
.filter(|x| x.is_full_feed())
.cloned()
.collect())
}
}