diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 72122089..912233e0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -19,14 +19,14 @@ jobs: release: ${{ github.base_ref == 'main' }} upload-artifact: true secrets: - SHEET_ID: ${{ vars.SHEET_ID }} + SHEET_ID: ${{ github.base_ref == 'main' && secrets.SHEET_ID_main || secrets.SHEET_ID_dev }} build_flutter_apk: uses: ./.github/workflows/build_flutter_apk.yml with: upload-artifact: true secrets: - SHEET_ID: ${{ vars.SHEET_ID }} + SHEET_ID: ${{ github.base_ref == 'main' && secrets.SHEET_ID_main || secrets.SHEET_ID_dev }} # It should wait untill all checks will pass auto-merge: diff --git a/.github/workflows/build_and_test_bot.yml b/.github/workflows/build_and_test_bot.yml index 5903a615..51e62869 100644 --- a/.github/workflows/build_and_test_bot.yml +++ b/.github/workflows/build_and_test_bot.yml @@ -24,6 +24,23 @@ jobs: if: inputs.release run: curl -L "docs.google.com/spreadsheets/d/${{ secrets.SHEET_ID }}/gviz/tq?tqx=out:csv&sheet=Ukrainian" -o table.csv + - uses: baptiste0928/cargo-install@v2 + with: + crate: cargo-expand + - uses: baptiste0928/cargo-install@v2 + with: + crate: flutter_rust_bridge_codegen + version: 2.0.0-dev.32 + - uses: subosito/flutter-action@v2 + with: + channel: "stable" + cache: true + - name: Update bindings + run: flutter_rust_bridge_codegen generate + working-directory: app + env: + SHEET_ID: ${{ secrets.SHEET_ID }} + RUST_LOG: info - name: Test and build release if: inputs.release env: diff --git a/.github/workflows/build_flutter_apk.yml b/.github/workflows/build_flutter_apk.yml index 5334ec94..fa929482 100644 --- a/.github/workflows/build_flutter_apk.yml +++ b/.github/workflows/build_flutter_apk.yml @@ -45,7 +45,7 @@ jobs: with: crate: cargo-expand # - run: flutter_rust_bridge_codegen build && flutter build apk --release - - run: flutter build apk --release + - run: flutter_rust_bridge_codegen generate && flutter build apk --release env: SHEET_ID: ${{ secrets.SHEET_ID }} - uses: actions/upload-artifact@v3 diff --git a/Cargo.lock b/Cargo.lock index 7e06146b..1aa0b394 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,9 +106,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "aquamarine" @@ -201,7 +201,7 @@ dependencies = [ "anyhow", "first_aid_bot_core", "futures", - "itertools 0.12.1", + "itertools 0.13.0", "log", "pretty_env_logger", "rand", @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "encoding_rs" @@ -511,9 +511,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -702,9 +702,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1006,9 +1006,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] @@ -1328,9 +1328,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" dependencies = [ "unicode-ident", ] @@ -1639,11 +1639,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -1688,9 +1688,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -1963,18 +1963,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", diff --git a/app/pubspec.lock b/app/pubspec.lock index 936c9c0f..1c323034 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -95,26 +95,26 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1" + sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "4.0.0" flutter_platform_widgets: dependency: "direct main" description: name: flutter_platform_widgets - sha256: c483c0591d845d2adb84e341a1cfb746f1a8a7aff4c72a5957772446020601f4 + sha256: "1a52147c03f0265b4f64d607f05ccfce5b2390224c6d40435ebc212f23576fff" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "7.0.0" flutter_rust_bridge: dependency: "direct main" description: name: flutter_rust_bridge - sha256: d65dbdd271de6050d3204bab69a8ae25a291deb359403cd4f95a86055cab66c3 + sha256: efb018e387c5e844095e35e9d6c6bd1610c49f25de109f4988b7c45aeca60a9a url: "https://pub.dev" source: hosted - version: "2.0.0-dev.32" + version: "2.0.0-dev.36" flutter_test: dependency: "direct dev" description: flutter @@ -142,34 +142,34 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" lints: dependency: transitive description: name: lints - sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 + sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" matcher: dependency: transitive description: @@ -190,10 +190,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" nested: dependency: transitive description: @@ -306,10 +306,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" vector_math: dependency: transitive description: @@ -322,10 +322,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" webdriver: dependency: transitive description: @@ -336,4 +336,4 @@ packages: version: "3.0.3" sdks: dart: ">=3.3.4 <4.0.0" - flutter: ">=3.16.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/app/pubspec.yaml b/app/pubspec.yaml index b86abfbe..a51d04c5 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -37,9 +37,9 @@ dependencies: cupertino_icons: ^1.0.6 rust_lib_app: path: rust_builder - flutter_rust_bridge: 2.0.0-dev.32 + flutter_rust_bridge: 2.0.0-dev.36 provider: ^6.1.2 - flutter_platform_widgets: ^6.1.0 + flutter_platform_widgets: ^7.0.0 dev_dependencies: flutter_test: @@ -50,7 +50,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^3.0.0 + flutter_lints: ^4.0.0 integration_test: sdk: flutter diff --git a/bot/Cargo.toml b/bot/Cargo.toml index 62f1b8c6..0eb1de98 100644 --- a/bot/Cargo.toml +++ b/bot/Cargo.toml @@ -12,7 +12,7 @@ teloxide = { version = "0.12", features = ["macros", "redis-storage", "bincode-serializer", "throttle"] } redis = { version = "0.25", features = ["tokio-comp"] } rand = "0.8" -itertools = "0.12" +itertools = "0.13" futures = "0.3" anyhow = { workspace = true } diff --git a/bot/src/bot/dialogue/commands.rs b/bot/src/bot/dialogue/commands.rs index 36cefa52..12cc8175 100644 --- a/bot/src/bot/dialogue/commands.rs +++ b/bot/src/bot/dialogue/commands.rs @@ -37,7 +37,7 @@ pub async fn commands_handler( dialogue: FADialogue, ) -> anyhow::Result<()> { match cmd { - FACommands::Start => start_endpoint(bot, msg, dialogue).await, + FACommands::Start => start_endpoint(bot, msg, dialogue, Lang::default()).await, } } diff --git a/bot/src/bot/dialogue/endpoints.rs b/bot/src/bot/dialogue/endpoints.rs index 4e8a7467..58d8d0c3 100644 --- a/bot/src/bot/dialogue/endpoints.rs +++ b/bot/src/bot/dialogue/endpoints.rs @@ -7,11 +7,19 @@ use first_aid_bot_core::prelude::*; use rand::random; use teloxide::{requests::Requester, types::Message}; -pub async fn start_endpoint(bot: FABot, msg: Message, dialogue: FADialogue) -> Result<()> { +pub async fn start_endpoint( + bot: FABot, + msg: Message, + dialogue: FADialogue, + lang: Lang, +) -> Result<()> { if is_admin(&msg) && random::() % 50 == 0 { easter_egg(&bot, &msg).await?; } - let ctx = FAContext::default(); + let ctx = FAContext { + lang, + ..FAContext::default() + }; move_to_state(&bot, &msg, &dialogue, &*DATA.get_state(&ctx).await?, ctx).await } @@ -21,13 +29,11 @@ pub async fn transition_endpoint( dialogue: FADialogue, (lang, context): (String, Vec), ) -> Result<()> { - let f = || async { - let lang = lang.as_str().try_into()?; - transition_logic(&bot, &msg, &dialogue, FAContext { lang, context }).await - }; + let lang = lang.as_str().try_into()?; + let f = || async { transition_logic(&bot, &msg, &dialogue, FAContext { lang, context }).await }; if let Err(e) = f().await { - start_endpoint(bot, msg, dialogue).await?; + start_endpoint(bot, msg, dialogue, lang).await?; bail!(e); } Ok(()) @@ -43,7 +49,7 @@ pub async fn broadcast_endpoint( let _ = bot .send_message(msg.chat.id, "WTF you are not an admin bye") .await; - return start_endpoint(bot, msg, dialogue).await; + return start_endpoint(bot, msg, dialogue, Lang::default()).await; } process_broadcast(&bot, &msg, &dialogue, message).await?; Ok(()) diff --git a/bot/src/bot/dialogue/logic/broadcast.rs b/bot/src/bot/dialogue/logic/broadcast.rs index be4c225b..5108d591 100644 --- a/bot/src/bot/dialogue/logic/broadcast.rs +++ b/bot/src/bot/dialogue/logic/broadcast.rs @@ -78,7 +78,7 @@ async fn broadcast_if_confirmed( async fn ask_to_confirm(bot: &FABot, id: ChatId, text: &str, dialogue: &FADialogue) -> Result<()> { bot.send_message(id, "Your message is:").await?; let vec = vec![MSG_CONFIRM]; - let keyboard = make_keyboard(&vec, Lang::Ua, 42, true); + let keyboard = make_keyboard(&vec, Lang::En, 42, true); bot.send_message(id, text).reply_markup(keyboard).await?; let message = Some(text.to_string()); dialogue.update(State::Broadcast { message }).await?; @@ -86,7 +86,7 @@ async fn ask_to_confirm(bot: &FABot, id: ChatId, text: &str, dialogue: &FADialog } async fn wait_for_message(bot: &FABot, id: ChatId) -> Result<()> { - let kbd = make_keyboard(&Vec::new(), Lang::Ua, 42, true); + let kbd = make_keyboard(&Vec::new(), Lang::En, 42, true); bot.send_message(id, MSG_REQUEST).reply_markup(kbd).await?; Ok(()) } diff --git a/bot/src/bot/dialogue/logic/keyboard.rs b/bot/src/bot/dialogue/logic/keyboard.rs index 076d9b0d..5bdae1e0 100644 --- a/bot/src/bot/dialogue/logic/keyboard.rs +++ b/bot/src/bot/dialogue/logic/keyboard.rs @@ -16,16 +16,18 @@ pub fn make_keyboard(keys: &[&str], lang: Lang, depth: usize, is_admin: bool) -> keyboard.push(vec![KeyboardButton::new(lang.details().broadcast)]); } - let special_keys = if depth == 0 { - let f = |lang: Lang| KeyboardButton::new(lang.details().button_lang); - Lang::iter().filter(|&l| l != lang).map(f).collect() - } else { - let mut special_keys = vec![KeyboardButton::new(lang.details().button_back)]; - if depth > 1 { - special_keys.push(KeyboardButton::new(lang.details().button_home)); - }; - special_keys - }; + let ld = lang.details(); + let special_keys = match depth { + 0 => Lang::iter() + .filter(|&l| l != lang) + .map(|l| l.details().button_lang) + .collect(), + 1 => vec![ld.button_back], + 2.. => vec![ld.button_back, ld.button_home], + } + .into_iter() + .map(KeyboardButton::new) + .collect(); keyboard.push(special_keys); ReplyMarkup::Keyboard(KeyboardMarkup::new(keyboard).resize_keyboard(true)) diff --git a/core/src/model/data.rs b/core/src/model/data.rs index 090f0af5..9b4d579b 100644 --- a/core/src/model/data.rs +++ b/core/src/model/data.rs @@ -14,9 +14,10 @@ impl Data { Self { data: None } } pub fn cached() -> Result { - log::info!("Cached data!"); - let data = Some(get_data_from_file("table.csv")?); - Ok(Self { data }) + unimplemented!("There is no multiple language support yet!"); + // log::info!("Cached data!"); + // let data = Some(get_data_from_file("table.csv")?); + // Ok(Self { data }) } pub async fn download() -> Result { log::info!("Downloading data!"); @@ -39,18 +40,23 @@ impl<'a> CowMultLangFsExt<'a> for Cow<'a, MultilangFs> { fn get_state(self, ctx: &FAContext) -> Result> { let err_lang = anyhow!("No such lang: {}", ctx.lang); let err_ctx = |key| move || anyhow!("Cannot find {key} for context {:?}", ctx.context); + match self { Cow::Borrowed(v) => { - Ok(Cow::Borrowed(ctx.context.iter().try_fold( - v.get(&ctx.lang).ok_or(err_lang)?, - |fs, key| fs.next_states.get(key).ok_or_else(err_ctx(key)), - )?)) + let init = v.get(&ctx.lang).ok_or(err_lang)?; + Ok(Cow::Borrowed( + ctx.context.iter().try_fold(init, |fs, key| { + fs.next_states.get(key).ok_or_else(err_ctx(key)) + })?, + )) } Cow::Owned(mut v) => { - Ok(Cow::Owned(ctx.context.iter().try_fold( - v.remove(&ctx.lang).ok_or(err_lang)?, - |mut fs, key| fs.next_states.swap_remove(key).ok_or_else(err_ctx(key)), - )?)) + let init = v.remove(&ctx.lang).ok_or(err_lang)?; + Ok(Cow::Owned( + ctx.context.iter().try_fold(init, |mut fs, key| { + fs.next_states.swap_remove(key).ok_or_else(err_ctx(key)) + })?, + )) } } } diff --git a/core/src/model/lang.rs b/core/src/model/lang.rs index 01c7fd5b..5e210410 100644 --- a/core/src/model/lang.rs +++ b/core/src/model/lang.rs @@ -11,20 +11,21 @@ use std::fmt::Display; pub enum Lang { #[default] Ua, - /* En, - Ru, */ + En, + // Ru } impl Lang { // https://github.com/rust-lang/rfcs/issues/284 pub fn iter() -> impl Iterator { - [Lang::Ua /* En, Ru */].into_iter() + // [Lang::Ua].into_iter() + [Lang::Ua, Lang::En].into_iter() } pub const fn details(self) -> LangDetails { match self { Lang::Ua => UA_LD, - /* En => EN_LD, - Ru => RU_LD, */ + Lang::En => EN_LD, + // Lang::Ru => RU_LD, } } pub fn name(self) -> String { @@ -88,13 +89,23 @@ const UA_LD: LangDetails = LangDetails { broadcast: "Транслювати", }; -// const EN_LD: LangDetails = LangDetails { -// name: "English", -// button_lang_name: "English", -// error: "An error occured, please tell us about it at " + HELP_CHAT_URL, -// use_buttons_text: "Use buttons, or restart bot i\f something is wrong (/start)", -// greeting: "What happened?", -// }; +const EN_LD: LangDetails = LangDetails { + name: "English", + button_lang: "English", + button_back: "◀️ Back", + button_home: "◀️ Home", + error: concatcp!( + "An error occurred :( Restart the bot (/start), and if that doesn't help, please report it in ", + HELP_CHAT_URL + ), + error_due_to_update: concatcp!( + "It seems that the bot has been updated. Returning to the beginning. If the bot still doesn't work, please report it in ", + HELP_CHAT_URL + ), + use_buttons_text: "Use buttons, or restart bot if something is wrong (/start)", + greeting: "What happened?", + broadcast: "Broadcast", +}; // const RU_LD: LangDetails = LangDetails { // name: "Russian", diff --git a/core/src/model/mod.rs b/core/src/model/mod.rs index 0c12ed70..9c9fcdec 100644 --- a/core/src/model/mod.rs +++ b/core/src/model/mod.rs @@ -52,24 +52,28 @@ fn get_finite_state(rdr: Reader, lang: Lang) -> anyhow::Result { Ok(Fs::entry(lang, get_next_states_for_key(&rows, "")?)) } -// This file is only for Ukrainian. If we will want to add more languages, it should be changed -pub fn get_data_from_file(filename: &str) -> anyhow::Result { +pub fn get_data_from_file(_filename: &str) -> anyhow::Result { + unimplemented!("There is no multiple language support yet! There has to be multiple filenames"); // let rdr = Reader::from_reader(BufReader::new(File::open(filename)?)); - let rdr = Reader::from_path(filename)?; - assert!(Lang::iter().count() == 1, "Only one language is supported"); - let lang = Lang::iter().next().unwrap(); - Ok([(lang, get_finite_state(rdr, lang)?)].into()) + // assert!(Lang::iter().count() == 1, "Only one language is supported"); + // let lang = Lang::iter().next().unwrap(); + // Ok([(lang, get_finite_state(rdr, lang)?)].into()) + // Lang::iter() + // .map(|lang| Ok((lang, get_finite_state(Reader::from_path(filename)?, lang)?))) + // .collect() } pub async fn get_data_from_web() -> anyhow::Result { let sheet_id = env!("SHEET_ID"); - assert!(Lang::iter().count() == 1, "Only one language is supported"); - let lang = Lang::iter().next().unwrap(); - let sheet_name = lang.name(); - let url = format!( - "https://docs.google.com/spreadsheets/d/{}/gviz/tq?tqx=out:csv&sheet={}", - sheet_id, sheet_name - ); - let rdr = Reader::from_reader(reqwest::get(url).await?.bytes().await?.reader()); - Ok([(lang, get_finite_state(rdr, lang)?)].into()) + let mut ret = MultilangFs::default(); + for lang in Lang::iter() { + let url = format!( + "https://docs.google.com/spreadsheets/d/{}/gviz/tq?tqx=out:csv&sheet={}", + sheet_id, + lang.name() + ); + let rdr = Reader::from_reader(reqwest::get(url).await?.bytes().await?.reader()); + ret.insert(lang, get_finite_state(rdr, lang)?); + } + Ok(ret) } diff --git a/core/tests/test_data.rs b/core/tests/test_data.rs index 3573410a..07dba576 100644 --- a/core/tests/test_data.rs +++ b/core/tests/test_data.rs @@ -76,6 +76,13 @@ pre-formatted fixed-width code block written in the Python programming language }; assert!(!data.is_empty()); assert!(data.iter().all(|(_, fs)| fs.num_nodes() > 1)); + assert!(Lang::iter().all(|lang| data.contains_key(&lang))); + for (lang, fs) in &data { + log::info!("First keys for lang {lang} are: "); + for key in fs.next_states.keys() { + log::info!("{}", key); + } + } data.into_iter() .inspect(|(lang, fs)| log::info!("Testing {lang} with {} nodes", fs.num_nodes())) .try_for_each(|(_, fs)| test_fs(fs))?;