#![doc = include_str!("../README.md")]
mod error;
pub use error::*;
use rcore::Requester;
type R = rcore::ReqwestRequester;
#[derive(Clone, rapi_derive::ProviderApi)]
pub enum RailwayProvider {
#[cfg(feature = "vbb-provider")]
#[provider(hafas = rhafas::profile::vbb::VbbProfile {})]
Vbb(rhafas::client::HafasClient<R>),
#[cfg(feature = "oebb-provider")]
#[provider(hafas = rhafas::profile::oebb::OebbProfile {})]
Oebb(rhafas::client::HafasClient<R>),
#[cfg(feature = "nahsh-provider")]
#[provider(hafas = rhafas::profile::nahsh::NahSHProfile {})]
NahSh(rhafas::client::HafasClient<R>),
#[cfg(feature = "vvt-provider")]
#[provider(hafas = rhafas::profile::vvt::VvtProfile {})]
Vvt(rhafas::client::HafasClient<R>),
#[cfg(feature = "pkp-provider")]
#[provider(hafas = rhafas::profile::pkp::PkpProfile {})]
Pkp(rhafas::client::HafasClient<R>),
#[cfg(feature = "irish-rail-provider")]
#[provider(hafas = rhafas::profile::irish_rail::IrishRailProfile {})]
IrishRail(rhafas::client::HafasClient<R>),
#[cfg(feature = "mobiliteit-lu-provider")]
#[provider(hafas = rhafas::profile::mobiliteit_lu::MobiliteitLuProfile {})]
MobiliteitLu(rhafas::client::HafasClient<R>),
#[cfg(feature = "dart-provider")]
#[provider(hafas = rhafas::profile::dart::DartProfile {})]
Dart(rhafas::client::HafasClient<R>),
#[cfg(feature = "rmv-provider")]
#[provider(hafas = rhafas::profile::rmv::RmvProfile {})]
Rmv(rhafas::client::HafasClient<R>),
#[cfg(feature = "insa-provider")]
#[provider(hafas = rhafas::profile::insa::InsaProfile {})]
Insa(rhafas::client::HafasClient<R>),
#[cfg(feature = "cmta-provider")]
#[provider(hafas = rhafas::profile::cmta::CmtaProfile {})]
Cmta(rhafas::client::HafasClient<R>),
#[cfg(feature = "sbahn-muenchen-provider")]
#[provider(hafas = rhafas::profile::sbahn_muenchen::SBahnMuenchenProfile {})]
SBahnMuenchen(rhafas::client::HafasClient<R>),
#[cfg(feature = "saarvv-provider")]
#[provider(hafas = rhafas::profile::saarvv::SaarvvProfile {})]
Saarvv(rhafas::client::HafasClient<R>),
#[cfg(feature = "cfl-provider")]
#[provider(hafas = rhafas::profile::cfl::CflProfile {})]
Cfl(rhafas::client::HafasClient<R>),
#[cfg(feature = "nvv-provider")]
#[provider(hafas = rhafas::profile::nvv::NvvProfile {})]
Nvv(rhafas::client::HafasClient<R>),
#[cfg(feature = "mobil-nrw-provider")]
#[provider(hafas = rhafas::profile::mobil_nrw::MobilNrwProfile {})]
MobilNrw(rhafas::client::HafasClient<R>),
#[cfg(feature = "vsn-provider")]
#[provider(hafas = rhafas::profile::vsn::VsnProfile {})]
Vsn(rhafas::client::HafasClient<R>),
#[cfg(feature = "vgi-provider")]
#[provider(hafas = rhafas::profile::vgi::VgiProfile {})]
Vgi(rhafas::client::HafasClient<R>),
#[cfg(feature = "vbn-provider")]
#[provider(hafas = rhafas::profile::vbn::VbnProfile {})]
Vbn(rhafas::client::HafasClient<R>),
#[cfg(feature = "vrn-provider")]
#[provider(hafas = rhafas::profile::vrn::VrnProfile {})]
Vrn(rhafas::client::HafasClient<R>),
#[cfg(feature = "rsag-provider")]
#[provider(hafas = rhafas::profile::rsag::RsagProfile {})]
Rsag(rhafas::client::HafasClient<R>),
#[cfg(feature = "vmt-provider")]
#[provider(hafas = rhafas::profile::vmt::VmtProfile {})]
Vmt(rhafas::client::HafasClient<R>),
#[cfg(feature = "vos-provider")]
#[provider(hafas = rhafas::profile::vos::VosProfile {})]
Vos(rhafas::client::HafasClient<R>),
#[cfg(feature = "avv-provider")]
#[provider(hafas = rhafas::profile::avv::AvvProfile {})]
Avv(rhafas::client::HafasClient<R>),
#[cfg(feature = "rejseplanen-provider")]
#[provider(hafas = rhafas::profile::rejseplanen::RejseplanenProfile {})]
Rejseplanen(rhafas::client::HafasClient<R>),
#[cfg(feature = "ooevv-provider")]
#[provider(hafas = rhafas::profile::ooevv::OoevvProfile {})]
Ooevv(rhafas::client::HafasClient<R>),
#[cfg(feature = "salzburg-provider")]
#[provider(hafas = rhafas::profile::salzburg::SalzburgProfile {})]
Salzburg(rhafas::client::HafasClient<R>),
#[cfg(feature = "verbundlinie-provider")]
#[provider(hafas = rhafas::profile::verbundlinie::VerbundlinieProfile {})]
Verbundlinie(rhafas::client::HafasClient<R>),
#[cfg(feature = "svv-provider")]
#[provider(hafas = rhafas::profile::svv::SvvProfile {})]
Svv(rhafas::client::HafasClient<R>),
#[cfg(feature = "vor-provider")]
#[provider(hafas = rhafas::profile::vor::VorProfile {})]
Vor(rhafas::client::HafasClient<R>),
#[cfg(feature = "vkg-provider")]
#[provider(hafas = rhafas::profile::vkg::VkgProfile {})]
Vkg(rhafas::client::HafasClient<R>),
#[cfg(feature = "vvv-provider")]
#[provider(hafas = rhafas::profile::vvv::VvvProfile {})]
Vvv(rhafas::client::HafasClient<R>),
#[cfg(feature = "bls-provider")]
#[provider(hafas = rhafas::profile::bls::BlsProfile {})]
Bls(rhafas::client::HafasClient<R>),
#[cfg(feature = "kvb-provider")]
#[provider(hafas = rhafas::profile::kvb::KvbProfile {})]
Kvb(rhafas::client::HafasClient<R>),
#[cfg(feature = "bart-provider")]
#[provider(hafas = rhafas::profile::bart::BartProfile {})]
Bart(rhafas::client::HafasClient<R>),
#[cfg(feature = "ivb-provider")]
#[provider(hafas = rhafas::profile::ivb::IvbProfile {})]
Ivb(rhafas::client::HafasClient<R>),
#[cfg(feature = "resrobot-provider")]
#[provider(hafas = rhafas::profile::resrobot::ResrobotProfile {})]
Resrobot(rhafas::client::HafasClient<R>),
#[cfg(feature = "search-ch-provider")]
#[provider(constructor = rsearchch::SearchChClient::new)]
SearchCh(rsearchch::SearchChClient<R>),
#[cfg(feature = "transitous-provider")]
#[provider(constructor = |r| rmotis::MotisClient::new(url::Url::parse(rmotis::TRANSITOUS_URL).expect("Failed to parse TRANSITOUS_URL"), r))]
Transitous(rmotis::MotisClient),
#[cfg(feature = "db-provider")]
#[provider(constructor = rdb::DbMovasClient::new)]
Db(rdb::DbMovasClient<R>),
}
#[cfg(test)]
mod api_test {
use super::*;
#[test]
#[cfg(feature = "db-provider")]
fn macro_creates_enum_types() {
let _ = RailwayProviderType::Db;
}
#[test]
#[cfg(feature = "db-provider")]
fn macro_creates_enum_type_variants() {
let list = RailwayProviderType::variants();
assert!(list.len() >= 1);
}
#[test]
#[cfg(feature = "db-provider")]
fn macro_creates_enum_from_to_string() {
use std::str::FromStr;
assert_eq!(
RailwayProviderType::from_str("db").unwrap(),
RailwayProviderType::Db
);
assert_eq!(RailwayProviderType::Db.to_string(), "db".to_owned());
}
#[test]
#[cfg(feature = "db-provider")]
fn macro_creates_constructor() {
let _ = RailwayProvider::new(
RailwayProviderType::Db,
rcore::ReqwestRequesterBuilder::default(),
);
}
#[test]
#[cfg(feature = "db-provider")]
fn macro_implements_provider() {
use rcore::Provider;
let client = RailwayProvider::new(
RailwayProviderType::Db,
rcore::ReqwestRequesterBuilder::default(),
);
let _ = Box::new(client) as Box<dyn Provider<rcore::ReqwestRequester, Error = BoxedError>>;
}
#[test]
#[cfg(feature = "all-providers")]
fn readme_supported_up_to_date() {
use std::collections::HashSet;
let supported: HashSet<_> = RailwayProviderType::variants()
.into_iter()
.map(|p| p.to_string().to_lowercase().replace(&['-', '_'], ""))
.collect();
let readme = include_str!("../../README.md").lines();
let entries: HashSet<_> = readme
.skip_while(|l| l != &"## Profiles")
.skip_while(|l| !l.starts_with("|"))
.skip(2)
.take_while(|l| l.starts_with("|"))
.flat_map(|r| r.split('|').nth(1))
.map(|s| s.trim().to_lowercase().replace(&['-', '_', '.'], ""))
.collect();
let extra: HashSet<_> = entries.difference(&supported).collect();
let missing: HashSet<_> = supported.difference(&entries).collect();
if !(extra.is_empty() && missing.is_empty()) {
println!("Extra Providers: {:#?}", extra);
println!("Missing Providers: {:#?}", missing);
panic!("Mismatched README and available providers");
}
}
#[test]
#[cfg(feature = "all-providers")]
fn hafas_all_providers_up_to_date() {
use serde::Deserialize;
use std::collections::{HashMap, HashSet};
use toml;
#[derive(Deserialize)]
struct CrateCargo {
features: HashMap<String, Vec<String>>,
}
let hafas_cargo = include_str!("../../railway-provider-hafas/Cargo.toml");
let cargo: CrateCargo = toml::from_str(hafas_cargo).unwrap();
let hafas_supported_profiles: HashSet<_> = cargo
.features
.keys()
.filter_map(|s| s.strip_suffix("-profile"))
.map(|p| p.to_string().to_lowercase().replace(['-', '_'], ""))
.collect();
let hafas_all_profiles: HashSet<_> = cargo.features["all-profiles"]
.iter()
.map(|p| {
p.strip_suffix("-profile")
.unwrap_or_default()
.to_string()
.to_lowercase()
.replace(['-', '_'], "")
})
.collect();
let supported: HashSet<_> = RailwayProviderType::variants()
.iter()
.map(|p| p.to_string().to_lowercase().replace(['-', '_'], ""))
.collect();
let supported_hafas = supported
.intersection(&hafas_supported_profiles)
.map(|s| s.to_string())
.collect();
let extra: HashSet<_> = hafas_all_profiles.difference(&supported_hafas).collect();
let missing: HashSet<_> = supported_hafas.difference(&hafas_all_profiles).collect();
if !(extra.is_empty() && missing.is_empty()) {
println!("Extra Providers: {:#?}", extra);
println!("Missing Providers: {:#?}", missing);
panic!("Mismatched README and available providers");
}
}
}