railway-api-0.1.2/.cargo_vcs_info.json0000644000000001510000000000100132500ustar { "git": { "sha1": "6fd1e44b5894991c9f91a494a5b03ac87e0c7b09" }, "path_in_vcs": "railway-api" }railway-api-0.1.2/Cargo.toml0000644000000125620000000000100112570ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2021" name = "railway-api" version = "0.1.2" authors = ["Julian Schmidhuber "] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = "High-level API for the Railway backend" readme = "README.md" keywords = [ "railway-backend", "train", "public-transport", ] license = "AGPL-3.0-or-later OR EUPL-1.2" repository = "https://gitlab.com/schmiddi-on-mobile/railway-backend" [lib] name = "railway_api" path = "src/lib.rs" [dependencies.async-trait] version = "0.1" [dependencies.chrono-tz] version = "0.8" [dependencies.rapi-derive] version = "0.1" package = "railway-api-derive" [dependencies.rcore] version = "0.1" package = "railway-core" [dependencies.rdb] version = "0.1" optional = true default-features = false package = "railway-provider-db-movas" [dependencies.rhafas] version = "0.1" optional = true default-features = false package = "railway-provider-hafas" [dependencies.rmotis] version = "0.2" optional = true default-features = false package = "railway-provider-motis" [dependencies.rsearchch] version = "0.1" optional = true default-features = false package = "railway-provider-search-ch" [dependencies.url] version = "2.5.0" [dev-dependencies.serde] version = "1.0" features = ["derive"] [dev-dependencies.toml] version = "0.8" [features] all-providers = [ "vbb-provider", "oebb-provider", "nahsh-provider", "vvt-provider", "pkp-provider", "irish-rail-provider", "mobiliteit-lu-provider", "dart-provider", "rmv-provider", "cmta-provider", "sbahn-muenchen-provider", "saarvv-provider", "cfl-provider", "nvv-provider", "vsn-provider", "vgi-provider", "vbn-provider", "vrn-provider", "rsag-provider", "vmt-provider", "vos-provider", "avv-provider", "rejseplanen-provider", "ooevv-provider", "salzburg-provider", "verbundlinie-provider", "svv-provider", "vor-provider", "vkg-provider", "vvv-provider", "bls-provider", "kvb-provider", "bart-provider", "ivb-provider", "resrobot-provider", "search-ch-provider", "transitous-provider", "db-provider", ] avv-provider = [ "rhafas", "rhafas/avv-profile", ] bart-provider = [ "rhafas", "rhafas/bart-profile", ] bls-provider = [ "rhafas", "rhafas/bls-profile", ] cfl-provider = [ "rhafas", "rhafas/cfl-profile", ] cmta-provider = [ "rhafas", "rhafas/cmta-profile", ] dart-provider = [ "rhafas", "rhafas/dart-profile", ] db-provider = ["rdb"] default = [ "all-providers", "rcore/reqwest-requester", ] insa-provider = [ "rhafas", "rhafas/insa-profile", ] irish-rail-provider = [ "rhafas", "rhafas/irish-rail-profile", ] ivb-provider = [ "rhafas", "rhafas/ivb-profile", ] kvb-provider = [ "rhafas", "rhafas/kvb-profile", ] mobil-nrw-provider = [ "rhafas", "rhafas/mobil-nrw-profile", ] mobiliteit-lu-provider = [ "rhafas", "rhafas/mobiliteit-lu-profile", ] nahsh-provider = [ "rhafas", "rhafas/nahsh-profile", ] nvv-provider = [ "rhafas", "rhafas/nvv-profile", ] oebb-provider = [ "rhafas", "rhafas/oebb-profile", ] ooevv-provider = [ "rhafas", "rhafas/ooevv-profile", ] pkp-provider = [ "rhafas", "rhafas/pkp-profile", ] polylines = [ "rcore/polylines", "rhafas/polylines", "rsearchch/polylines", "rdb/polylines", ] rejseplanen-provider = [ "rhafas", "rhafas/rejseplanen-profile", ] resrobot-provider = [ "rhafas", "rhafas/resrobot-profile", ] rmv-provider = [ "rhafas", "rhafas/rmv-profile", ] rsag-provider = [ "rhafas", "rhafas/rsag-profile", ] rt-multi-thread = [ "rcore/rt-multi-thread", "rhafas/rt-multi-thread", "rsearchch/rt-multi-thread", "rmotis/rt-multi-thread", "rdb/rt-multi-thread", ] saarvv-provider = [ "rhafas", "rhafas/saarvv-profile", ] salzburg-provider = [ "rhafas", "rhafas/salzburg-profile", ] sbahn-muenchen-provider = [ "rhafas", "rhafas/sbahn-muenchen-profile", ] search-ch-provider = ["rsearchch"] svv-provider = [ "rhafas", "rhafas/svv-profile", ] transitous-provider = ["rmotis"] vbb-provider = [ "rhafas", "rhafas/vbb-profile", ] vbn-provider = [ "rhafas", "rhafas/vbn-profile", ] verbundlinie-provider = [ "rhafas", "rhafas/verbundlinie-profile", ] vgi-provider = [ "rhafas", "rhafas/vgi-profile", ] vkg-provider = [ "rhafas", "rhafas/vkg-profile", ] vmt-provider = [ "rhafas", "rhafas/vmt-profile", ] vor-provider = [ "rhafas", "rhafas/vor-profile", ] vos-provider = [ "rhafas", "rhafas/vos-profile", ] vrn-provider = [ "rhafas", "rhafas/vrn-profile", ] vsn-provider = [ "rhafas", "rhafas/vsn-profile", ] vvt-provider = [ "rhafas", "rhafas/vvt-profile", ] vvv-provider = [ "rhafas", "rhafas/vvv-profile", ] railway-api-0.1.2/Cargo.toml.orig000064400000000000000000000116571046102023000147440ustar 00000000000000[package] name = "railway-api" version = "0.1.2" authors = ["Julian Schmidhuber "] edition = "2021" description = "High-level API for the Railway backend" repository = "https://gitlab.com/schmiddi-on-mobile/railway-backend" license = "AGPL-3.0-or-later OR EUPL-1.2" keywords = ["railway-backend", "train", "public-transport"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rcore = { package = "railway-core", path = "../railway-core", version = "0.1" } rapi-derive = { package = "railway-api-derive", path = "../railway-api-derive", version = "0.1" } rhafas = { package = "railway-provider-hafas", path = "../railway-provider-hafas", version = "0.1", optional = true, default-features = false } rsearchch = { package = "railway-provider-search-ch", path = "../railway-provider-search-ch", version = "0.1", optional = true, default-features = false } rmotis = { package = "railway-provider-motis", path = "../railway-provider-motis", version = "0.2", optional = true, default-features = false } rdb = { package = "railway-provider-db-movas", path = "../railway-provider-db-movas", version = "0.1", optional = true, default-features = false } async-trait = "0.1" chrono-tz = "0.8" url = "2.5.0" [features] default = [ "all-providers", "rcore/reqwest-requester" ] rt-multi-thread = [ "rcore/rt-multi-thread", "rhafas/rt-multi-thread", "rsearchch/rt-multi-thread", "rmotis/rt-multi-thread", "rdb/rt-multi-thread" ] polylines = [ "rcore/polylines", "rhafas/polylines", "rsearchch/polylines", "rdb/polylines"] all-providers = [ # Hafas "vbb-provider", "oebb-provider", "nahsh-provider", "vvt-provider", "pkp-provider", "irish-rail-provider", "mobiliteit-lu-provider", "dart-provider", "rmv-provider", # Currently broken: Always returns "location not found" when searching journeys. # "insa-provider", "cmta-provider", "sbahn-muenchen-provider", "saarvv-provider", "cfl-provider", "nvv-provider", # Currently broken: Migrated to EFA # See . # "mobil-nrw-provider", "vsn-provider", "vgi-provider", "vbn-provider", "vrn-provider", "rsag-provider", "vmt-provider", "vos-provider", "avv-provider", "rejseplanen-provider", "ooevv-provider", "salzburg-provider", "verbundlinie-provider", "svv-provider", "vor-provider", "vkg-provider", "vvv-provider", "bls-provider", "kvb-provider", "bart-provider", "ivb-provider", "resrobot-provider", # Search.ch "search-ch-provider", # Transitous "transitous-provider", # DB Movas "db-provider" ] # Hafas vbb-provider = [ "rhafas", "rhafas/vbb-profile" ] oebb-provider = [ "rhafas", "rhafas/oebb-profile" ] nahsh-provider = [ "rhafas", "rhafas/nahsh-profile" ] vvt-provider = [ "rhafas", "rhafas/vvt-profile" ] pkp-provider = [ "rhafas", "rhafas/pkp-profile" ] irish-rail-provider = [ "rhafas", "rhafas/irish-rail-profile"] mobiliteit-lu-provider = [ "rhafas", "rhafas/mobiliteit-lu-profile"] dart-provider = [ "rhafas", "rhafas/dart-profile" ] rmv-provider = [ "rhafas", "rhafas/rmv-profile" ] insa-provider = [ "rhafas", "rhafas/insa-profile" ] cmta-provider = [ "rhafas", "rhafas/cmta-profile" ] sbahn-muenchen-provider = [ "rhafas", "rhafas/sbahn-muenchen-profile"] saarvv-provider = [ "rhafas", "rhafas/saarvv-profile" ] cfl-provider = [ "rhafas", "rhafas/cfl-profile" ] nvv-provider = [ "rhafas", "rhafas/nvv-profile" ] mobil-nrw-provider = [ "rhafas", "rhafas/mobil-nrw-profile"] vsn-provider = [ "rhafas", "rhafas/vsn-profile" ] vgi-provider = [ "rhafas", "rhafas/vgi-profile" ] vbn-provider = [ "rhafas", "rhafas/vbn-profile" ] vrn-provider = [ "rhafas", "rhafas/vrn-profile" ] rsag-provider = [ "rhafas", "rhafas/rsag-profile" ] vmt-provider = [ "rhafas", "rhafas/vmt-profile" ] vos-provider = [ "rhafas", "rhafas/vos-profile" ] avv-provider = [ "rhafas", "rhafas/avv-profile" ] rejseplanen-provider = [ "rhafas", "rhafas/rejseplanen-profile" ] ooevv-provider = [ "rhafas", "rhafas/ooevv-profile" ] salzburg-provider = [ "rhafas", "rhafas/salzburg-profile" ] verbundlinie-provider = [ "rhafas", "rhafas/verbundlinie-profile" ] svv-provider = [ "rhafas", "rhafas/svv-profile" ] vor-provider = [ "rhafas", "rhafas/vor-profile" ] vkg-provider = [ "rhafas", "rhafas/vkg-profile" ] vvv-provider = [ "rhafas", "rhafas/vvv-profile" ] bls-provider = [ "rhafas", "rhafas/bls-profile" ] kvb-provider = [ "rhafas", "rhafas/kvb-profile" ] bart-provider = [ "rhafas", "rhafas/bart-profile" ] ivb-provider = [ "rhafas", "rhafas/ivb-profile" ] resrobot-provider = [ "rhafas", "rhafas/resrobot-profile" ] # Search.ch search-ch-provider = [ "rsearchch" ] # Transitous transitous-provider = [ "rmotis" ] # DB Movas db-provider = [ "rdb"] [dev-dependencies] rcore = { package = "railway-core", path = "../railway-core", features = [ "reqwest-requester" ] } toml = "0.8" serde = { version = "1.0", features = [ "derive" ] } railway-api-0.1.2/README.md000064400000000000000000000004621046102023000133240ustar 00000000000000# Railway API High-level API for the Railway backend. This crate is part of [railway-backend](https://gitlab.com/schmiddi-on-mobile/railway-backend). You can find a high-level documentation of railway-backend [here](https://gitlab.com/schmiddi-on-mobile/railway-backend/-/tree/main/docs?ref_type=heads). railway-api-0.1.2/src/error.rs000064400000000000000000000012571046102023000143360ustar 00000000000000use std::fmt::{Display, Formatter}; /// A type-erased [`Error`](std::error::Error). #[derive(Debug)] pub struct BoxedError(Box); impl Display for BoxedError { fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> { self.0.fmt(f) } } pub(crate) fn transform_error< R: std::error::Error, P: std::error::Error + Send + Sync + 'static, >( e: rcore::Error, ) -> rcore::Error { match e { rcore::Error::Request(e) => rcore::Error::Request(e), rcore::Error::Provider(e) => rcore::Error::Provider(BoxedError(Box::new(e))), } } impl std::error::Error for BoxedError {} railway-api-0.1.2/src/lib.rs000064400000000000000000000265211046102023000137540ustar 00000000000000#![doc = include_str!("../README.md")] mod error; pub use error::*; use rcore::Requester; // XXX: Ugly that this needs to be hard-coded; most of the enum is general over the requester, but the Motis one is not. type R = rcore::ReqwestRequester; // Note: The derive macro automatically generates the following: // - `RailwayProviderType`: The enum equivalent to this enum without the data for each enum variant. It furthermore generates `FromStr` and `Display` for it. There is also a `RailwayProviderType::variants` which lists all providers that are available. // - `RailwayProvider::new`: Construct `RailwayProvider` from `RailwayProviderType` and `R: Requester` using specified `constructor`. // - `impl Provider for RailwayProvider`: Using error `BoxedError` and directly passing through the wrapped type. // It also looks for `#[cfg(...)]` and enables the specific code only if requested. /// A wrapper around all implemented [`Provider`s](rcore::Provider). /// /// Note that the variants of this enum depend on the features activated via the API. #[derive(Clone, rapi_derive::ProviderApi)] pub enum RailwayProvider { // Hafas #[cfg(feature = "vbb-provider")] #[provider(hafas = rhafas::profile::vbb::VbbProfile {})] Vbb(rhafas::client::HafasClient), #[cfg(feature = "oebb-provider")] #[provider(hafas = rhafas::profile::oebb::OebbProfile {})] Oebb(rhafas::client::HafasClient), #[cfg(feature = "nahsh-provider")] #[provider(hafas = rhafas::profile::nahsh::NahSHProfile {})] NahSh(rhafas::client::HafasClient), #[cfg(feature = "vvt-provider")] #[provider(hafas = rhafas::profile::vvt::VvtProfile {})] Vvt(rhafas::client::HafasClient), #[cfg(feature = "pkp-provider")] #[provider(hafas = rhafas::profile::pkp::PkpProfile {})] Pkp(rhafas::client::HafasClient), #[cfg(feature = "irish-rail-provider")] #[provider(hafas = rhafas::profile::irish_rail::IrishRailProfile {})] IrishRail(rhafas::client::HafasClient), #[cfg(feature = "mobiliteit-lu-provider")] #[provider(hafas = rhafas::profile::mobiliteit_lu::MobiliteitLuProfile {})] MobiliteitLu(rhafas::client::HafasClient), #[cfg(feature = "dart-provider")] #[provider(hafas = rhafas::profile::dart::DartProfile {})] Dart(rhafas::client::HafasClient), #[cfg(feature = "rmv-provider")] #[provider(hafas = rhafas::profile::rmv::RmvProfile {})] Rmv(rhafas::client::HafasClient), #[cfg(feature = "insa-provider")] #[provider(hafas = rhafas::profile::insa::InsaProfile {})] Insa(rhafas::client::HafasClient), #[cfg(feature = "cmta-provider")] #[provider(hafas = rhafas::profile::cmta::CmtaProfile {})] Cmta(rhafas::client::HafasClient), #[cfg(feature = "sbahn-muenchen-provider")] #[provider(hafas = rhafas::profile::sbahn_muenchen::SBahnMuenchenProfile {})] SBahnMuenchen(rhafas::client::HafasClient), #[cfg(feature = "saarvv-provider")] #[provider(hafas = rhafas::profile::saarvv::SaarvvProfile {})] Saarvv(rhafas::client::HafasClient), #[cfg(feature = "cfl-provider")] #[provider(hafas = rhafas::profile::cfl::CflProfile {})] Cfl(rhafas::client::HafasClient), #[cfg(feature = "nvv-provider")] #[provider(hafas = rhafas::profile::nvv::NvvProfile {})] Nvv(rhafas::client::HafasClient), #[cfg(feature = "mobil-nrw-provider")] #[provider(hafas = rhafas::profile::mobil_nrw::MobilNrwProfile {})] MobilNrw(rhafas::client::HafasClient), #[cfg(feature = "vsn-provider")] #[provider(hafas = rhafas::profile::vsn::VsnProfile {})] Vsn(rhafas::client::HafasClient), #[cfg(feature = "vgi-provider")] #[provider(hafas = rhafas::profile::vgi::VgiProfile {})] Vgi(rhafas::client::HafasClient), #[cfg(feature = "vbn-provider")] #[provider(hafas = rhafas::profile::vbn::VbnProfile {})] Vbn(rhafas::client::HafasClient), #[cfg(feature = "vrn-provider")] #[provider(hafas = rhafas::profile::vrn::VrnProfile {})] Vrn(rhafas::client::HafasClient), #[cfg(feature = "rsag-provider")] #[provider(hafas = rhafas::profile::rsag::RsagProfile {})] Rsag(rhafas::client::HafasClient), #[cfg(feature = "vmt-provider")] #[provider(hafas = rhafas::profile::vmt::VmtProfile {})] Vmt(rhafas::client::HafasClient), #[cfg(feature = "vos-provider")] #[provider(hafas = rhafas::profile::vos::VosProfile {})] Vos(rhafas::client::HafasClient), #[cfg(feature = "avv-provider")] #[provider(hafas = rhafas::profile::avv::AvvProfile {})] Avv(rhafas::client::HafasClient), #[cfg(feature = "rejseplanen-provider")] #[provider(hafas = rhafas::profile::rejseplanen::RejseplanenProfile {})] Rejseplanen(rhafas::client::HafasClient), #[cfg(feature = "ooevv-provider")] #[provider(hafas = rhafas::profile::ooevv::OoevvProfile {})] Ooevv(rhafas::client::HafasClient), #[cfg(feature = "salzburg-provider")] #[provider(hafas = rhafas::profile::salzburg::SalzburgProfile {})] Salzburg(rhafas::client::HafasClient), #[cfg(feature = "verbundlinie-provider")] #[provider(hafas = rhafas::profile::verbundlinie::VerbundlinieProfile {})] Verbundlinie(rhafas::client::HafasClient), #[cfg(feature = "svv-provider")] #[provider(hafas = rhafas::profile::svv::SvvProfile {})] Svv(rhafas::client::HafasClient), #[cfg(feature = "vor-provider")] #[provider(hafas = rhafas::profile::vor::VorProfile {})] Vor(rhafas::client::HafasClient), #[cfg(feature = "vkg-provider")] #[provider(hafas = rhafas::profile::vkg::VkgProfile {})] Vkg(rhafas::client::HafasClient), #[cfg(feature = "vvv-provider")] #[provider(hafas = rhafas::profile::vvv::VvvProfile {})] Vvv(rhafas::client::HafasClient), #[cfg(feature = "bls-provider")] #[provider(hafas = rhafas::profile::bls::BlsProfile {})] Bls(rhafas::client::HafasClient), #[cfg(feature = "kvb-provider")] #[provider(hafas = rhafas::profile::kvb::KvbProfile {})] Kvb(rhafas::client::HafasClient), #[cfg(feature = "bart-provider")] #[provider(hafas = rhafas::profile::bart::BartProfile {})] Bart(rhafas::client::HafasClient), #[cfg(feature = "ivb-provider")] #[provider(hafas = rhafas::profile::ivb::IvbProfile {})] Ivb(rhafas::client::HafasClient), #[cfg(feature = "resrobot-provider")] #[provider(hafas = rhafas::profile::resrobot::ResrobotProfile {})] Resrobot(rhafas::client::HafasClient), // Search.ch #[cfg(feature = "search-ch-provider")] #[provider(constructor = rsearchch::SearchChClient::new)] SearchCh(rsearchch::SearchChClient), // Transitous #[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), // DB Movas #[cfg(feature = "db-provider")] #[provider(constructor = rdb::DbMovasClient::new)] Db(rdb::DbMovasClient), } #[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>; } #[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 // Go to profiles-section. .skip_while(|l| l != &"## Profiles") // Go to first table. .skip_while(|l| !l.starts_with("|")) // Skip header. .skip(2) // Take rows .take_while(|l| l.starts_with("|")) // Take first column .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>, } 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"); } } }