diff --git a/.vscode/settings.json b/.vscode/settings.json index f3902d3..db29320 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -11,5 +11,13 @@ "Cargo.lock": true, "riot.txt": true, "target": true, - } + }, + "rust-analyzer.cargo.features": [ + "fetch", + "exec", + "search", + "telegram", + "discord", + "matrix", + ] } \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index e4ac71b..61d7835 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,32 +16,28 @@ rustdoc-args = ["--document-private-items"] [dependencies] -# base +# required log = { version = "0.4.17" } itertools = { version = "0.10.3" } regex = { version = "1.6.0" } lazy_static = { version = "1.4.0" } data-encoding = { version = "2.3.2" } varint-rs = { version = "2.2.0" } -# exec -pretty_env_logger = { version = "0.4.0", optional = true } -glob = { version = "0.3.0", optional = true } -# data serde = { version = "1.0.140", features = ["derive"] } serde_json = { version = "1.0.82" } -# search +# optional +reqwest = { version = "0.11.11", features = ["json"], optional = true } +pretty_env_logger = { version = "0.4.0", optional = true } +glob = { version = "0.3.0", optional = true } tantivy = { version = "0.18.0", optional = true } -# telegram teloxide = { version = "0.10.1", optional = true } -reqwest = { version = "0.11.11", optional = true } tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"], optional = true } md5 = { version = "0.7.0", optional = true } -# discord -# matrix [features] # data = [] # Always included +fetch = ["reqwest"] exec = ["pretty_env_logger", "glob"] search = ["tantivy"] telegram = ["exec", "search", "teloxide", "reqwest", "tokio", "md5"] diff --git a/src/data/anybundle/outcomes.rs b/src/data/anybundle/outcomes.rs index f852fbd..c19dfed 100644 --- a/src/data/anybundle/outcomes.rs +++ b/src/data/anybundle/outcomes.rs @@ -9,12 +9,14 @@ pub enum LoadingError { GettingLocale, /// Could not get the bundle name from the operating system. GettingBundleName, - /// Could not convert the bundle name from a [OsString](std::ffi::OsString) to a [String]. - ConvertingBundleName, /// Could not use [File::open](std::fs::File::open) on a data file. OpeningFile(std::io::Error), /// Could not deserialize a data file. Deserializing(serde_json::Error), + /// Could not fetch a data file from a remote location. + RemoteFetching(reqwest::Error), + /// Could not deserialize a data file from a remote location. + RemoteDeserializing(reqwest::Error), } /// The result of the loading of a Legends of Runeterra bundle. diff --git a/src/data/corebundle/mod.rs b/src/data/corebundle/mod.rs index c05c4b5..033d6d1 100644 --- a/src/data/corebundle/mod.rs +++ b/src/data/corebundle/mod.rs @@ -21,12 +21,6 @@ pub mod vocabterm; /// [Core Bundle]: https://developer.riotgames.com/docs/lor#data-dragon_core-bundles #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct CoreBundle { - /// The name of the root directory of the bundle. - pub name: String, - - /// The contents of the `metadata.json` file. - pub metadata: BundleMetadata, - /// The contents of the `[locale]/data/globals-[locale].json` file. pub globals: globals::LocalizedGlobalsVecs, } @@ -36,13 +30,6 @@ impl CoreBundle { pub fn load(bundle_path: &Path) -> LoadingResult { let metadata = BundleMetadata::load(&bundle_path.join("metadata.json"))?; - let name = bundle_path - .file_name() - .ok_or(LoadingError::GettingBundleName)? - .to_str() - .ok_or(LoadingError::ConvertingBundleName)? - .to_string(); - let locale = metadata.locale().ok_or(LoadingError::GettingLocale)?; let globals_path = &bundle_path @@ -53,9 +40,44 @@ impl CoreBundle { let globals = globals::LocalizedGlobalsVecs::load(globals_path)?; Ok(CoreBundle { - name, - metadata, globals, }) } + + /// Fetch from `base_url` the Core Bundle data with the given `locale`. + #[cfg(feature = "fetch")] + pub async fn fetch(client: &reqwest::Client, base_url: &str, locale: &str) -> LoadingResult { + let globals = client + .get(format!("{base_url}/core/{locale}/data/globals-{locale}.json")) + .send() + .await + .map_err(LoadingError::RemoteFetching)? + .json::() + .await + .map_err(LoadingError::RemoteDeserializing)?; + + Ok(Self {globals}) + } } + + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! test_fetch { + ( $id:ident, $version:literal, $locale:literal ) => { + #[cfg(feature = "fetch")] + #[tokio::test] + async fn $id() { + let client = reqwest::Client::new(); + let result = CoreBundle::fetch(&client, &format!("https://dd.b.pvp.net/{}", $version), $locale).await; + assert!(result.is_ok()); + } + }; + } + + test_fetch!(test_fetch_3_17_0_en_us, "3_17_0", "en_us"); + test_fetch!(test_fetch_3_17_0_it_it, "3_17_0", "it_it"); + test_fetch!(test_fetch_latest_en_us, "latest", "en_us"); +} \ No newline at end of file diff --git a/src/data/setbundle/mod.rs b/src/data/setbundle/mod.rs index 2785076..b0f038a 100644 --- a/src/data/setbundle/mod.rs +++ b/src/data/setbundle/mod.rs @@ -24,15 +24,10 @@ pub mod r#type; /// /// [Data Dragon]: https://developer.riotgames.com/docs/lor#data-dragon /// [Set Bundle]: https://developer.riotgames.com/docs/lor#data-dragon_set-bundles +#[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct SetBundle { - /// The contents of the `metadata.json` file. - pub metadata: BundleMetadata, - /// The contents of the `[locale]/data/globals-[locale].json` file. pub cards: Vec, - - /// The name of the root directory of the bundle. - pub name: String, } impl SetBundle { @@ -53,20 +48,70 @@ impl SetBundle { &bundle_path.join(&locale).join("data").join(&json_filename) }; - let name = name - .to_str() - .ok_or(LoadingError::ConvertingBundleName)? - .to_string(); - let cards = File::open(data_path).map_err(LoadingError::OpeningFile)?; let cards = serde_json::de::from_reader::>(cards) .map_err(LoadingError::Deserializing)?; Ok(SetBundle { - metadata, cards, - name, }) } + + /// Fetch from `base_url` the Set Bundle data of the given `set` with the given `locale`. + #[cfg(feature = "fetch")] + pub async fn fetch(client: &reqwest::Client, base_url: &str, locale: &str, set: &str) -> LoadingResult { + let cards = client + .get(format!("{base_url}/{set}/{locale}/data/{set}-{locale}.json")) + .send() + .await + .map_err(LoadingError::RemoteFetching)? + .json::>() + .await + .map_err(LoadingError::RemoteDeserializing)?; + + Ok(Self {cards}) + } +} + + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! test_fetch { + ( $id:ident, $version:literal, $locale:literal, $set:literal ) => { + #[cfg(feature = "fetch")] + #[tokio::test] + async fn $id() { + let client = reqwest::Client::new(); + let result = SetBundle::fetch(&client, &format!("https://dd.b.pvp.net/{}", $version), $locale, $set).await; + assert!(result.is_ok()); + } + }; + } + + test_fetch!(test_fetch_3_17_0_en_us_set1, "3_17_0", "en_us", "set1"); + test_fetch!(test_fetch_3_17_0_en_us_set2, "3_17_0", "en_us", "set2"); + test_fetch!(test_fetch_3_17_0_en_us_set3, "3_17_0", "en_us", "set3"); + test_fetch!(test_fetch_3_17_0_en_us_set4, "3_17_0", "en_us", "set4"); + test_fetch!(test_fetch_3_17_0_en_us_set5, "3_17_0", "en_us", "set5"); + test_fetch!(test_fetch_3_17_0_en_us_set6, "3_17_0", "en_us", "set6"); + test_fetch!(test_fetch_3_17_0_en_us_set6cde, "3_17_0", "en_us", "set6cde"); + + test_fetch!(test_fetch_3_17_0_it_it_set1, "3_17_0", "it_it", "set1"); + test_fetch!(test_fetch_3_17_0_it_it_set2, "3_17_0", "it_it", "set2"); + test_fetch!(test_fetch_3_17_0_it_it_set3, "3_17_0", "it_it", "set3"); + test_fetch!(test_fetch_3_17_0_it_it_set4, "3_17_0", "it_it", "set4"); + test_fetch!(test_fetch_3_17_0_it_it_set5, "3_17_0", "it_it", "set5"); + test_fetch!(test_fetch_3_17_0_it_it_set6, "3_17_0", "it_it", "set6"); + test_fetch!(test_fetch_3_17_0_it_it_set6cde, "3_17_0", "it_it", "set6cde"); + + test_fetch!(test_fetch_latest_en_us_set1, "latest", "en_us", "set1"); + test_fetch!(test_fetch_latest_en_us_set2, "latest", "en_us", "set2"); + test_fetch!(test_fetch_latest_en_us_set3, "latest", "en_us", "set3"); + test_fetch!(test_fetch_latest_en_us_set4, "latest", "en_us", "set4"); + test_fetch!(test_fetch_latest_en_us_set5, "latest", "en_us", "set5"); + test_fetch!(test_fetch_latest_en_us_set6, "latest", "en_us", "set6"); + test_fetch!(test_fetch_latest_en_us_set6cde, "latest", "en_us", "set6cde"); }