numbat-exchange-rates-0.5.0/.cargo_vcs_info.json0000644000000001630000000000100152200ustar { "git": { "sha1": "052452492479e1ce5f840e14e7c3ce86c9662457" }, "path_in_vcs": "numbat-exchange-rates" }numbat-exchange-rates-0.5.0/Cargo.toml0000644000000020050000000000100132130ustar # 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" rust-version = "1.70" name = "numbat-exchange-rates" version = "0.5.0" authors = ["David Peter "] description = "A library to fetch and parse currency exchange rates from the ECB" homepage = "https://numbat.dev/" license = "MIT OR Apache-2.0" repository = "https://github.com/sharkdp/numbat" [dependencies.attohttpc] version = "0.27.0" features = ["tls-rustls-webpki-roots"] optional = true default-features = false [dependencies.quick-xml] version = "0.31.0" [features] fetch-exchangerates = ["dep:attohttpc"] numbat-exchange-rates-0.5.0/Cargo.toml.orig000064400000000000000000000010431046102023000166750ustar 00000000000000[package] name = "numbat-exchange-rates" description = "A library to fetch and parse currency exchange rates from the ECB" authors = ["David Peter "] homepage = "https://numbat.dev/" repository = "https://github.com/sharkdp/numbat" version = "0.5.0" edition = "2021" license = "MIT OR Apache-2.0" rust-version = "1.70" [dependencies] attohttpc = { version = "0.27.0", default-features = false, features = ["tls-rustls-webpki-roots"], optional = true } quick-xml = "0.31.0" [features] fetch-exchangerates = ["dep:attohttpc"] numbat-exchange-rates-0.5.0/src/lib.rs000064400000000000000000000031041046102023000157110ustar 00000000000000use std::collections::HashMap; use quick_xml::events::Event; use quick_xml::reader::Reader; pub type ExchangeRates = HashMap; pub fn parse_exchange_rates(xml_content: &str) -> Option { let mut rates = ExchangeRates::default(); let mut reader = Reader::from_str(xml_content); loop { match reader.read_event().ok()? { Event::Eof => break, Event::Empty(e) => { if e.local_name().as_ref() != b"Cube" { continue; } let currency = &e .try_get_attribute("currency") .ok()?? .unescape_value() .ok()?; let rate = &e.try_get_attribute("rate").ok()??.unescape_value().ok()?; let rate = rate.parse().ok()?; rates.insert(currency.to_string(), rate); } _ => {} } } Some(rates) } #[cfg(feature = "fetch-exchangerates")] const ECB_XML_URL: &str = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"; #[cfg(feature = "fetch-exchangerates")] fn fetch_ecb_xml() -> Option { attohttpc::get(ECB_XML_URL).send().ok()?.text().ok() } #[cfg(feature = "fetch-exchangerates")] pub fn fetch_exchange_rates() -> Option { let xml_content = fetch_ecb_xml()?; parse_exchange_rates(&xml_content) } #[cfg(test)] #[cfg(feature = "fetch-exchangerates")] mod tests { use super::*; #[test] fn fetch_exchange_rates_works() { fetch_exchange_rates(); } }