diff --git a/Cargo.lock b/Cargo.lock index 6d39eca..5cf99b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,6 +213,7 @@ dependencies = [ "serde", "serde_json", "smallvec", + "smartstring", "strum", "strum_macros", "teloxide", @@ -1826,6 +1827,18 @@ dependencies = [ "serde", ] +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + [[package]] name = "smawk" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 5752c25..72acd21 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,3 +29,4 @@ lazy_static = "1.4.0" moka = { version = "0.11.1", features = ["future"] } axum = "0.6.18" smallvec = { version = "1.10.0", features = ["serde"] } +smartstring = { version = "1.0.1", features = ["serde"] } diff --git a/src/bots/approved_bot/mod.rs b/src/bots/approved_bot/mod.rs index 597ae3a..95ce285 100644 --- a/src/bots/approved_bot/mod.rs +++ b/src/bots/approved_bot/mod.rs @@ -2,6 +2,8 @@ pub mod modules; pub mod services; mod tools; +use smartstring::alias::String as SmartString; + use moka::future::Cache; use smallvec::SmallVec; use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}}; @@ -24,7 +26,7 @@ async fn _update_activity( me: teloxide::types::Me, user: teloxide::types::User, activity_cache: Cache, - user_langs_cache: Cache>, + user_langs_cache: Cache>, ) -> Option<()> { if activity_cache.contains_key(&user.id) { return None; diff --git a/src/bots/approved_bot/modules/book.rs b/src/bots/approved_bot/modules/book.rs index 2fcd928..acf1ac8 100644 --- a/src/bots/approved_bot/modules/book.rs +++ b/src/bots/approved_bot/modules/book.rs @@ -1,6 +1,8 @@ use core::fmt::Debug; use std::str::FromStr; +use smartstring::alias::String as SmartString; + use moka::future::Cache; use regex::Regex; use smallvec::SmallVec; @@ -119,8 +121,8 @@ async fn send_book_handler( message: Message, bot: CacheMe>, command: BookCommand, - books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, - user_langs_cache: Cache>, + books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut, + user_langs_cache: Cache>, ) -> crate::bots::BotHandlerInternal where T: Format + Clone + Debug, @@ -191,8 +193,8 @@ async fn send_pagination_book_handler( cq: CallbackQuery, bot: CacheMe>, callback_data: BookCallbackData, - books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, - user_langs_cache: Cache>, + books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut, + user_langs_cache: Cache>, ) -> crate::bots::BotHandlerInternal where T: Format + Clone + Debug, diff --git a/src/bots/approved_bot/modules/download.rs b/src/bots/approved_bot/modules/download.rs index f3e2bc1..e230420 100644 --- a/src/bots/approved_bot/modules/download.rs +++ b/src/bots/approved_bot/modules/download.rs @@ -438,7 +438,7 @@ async fn download_archive( object_id: id, object_type: task_type, file_format: file_type, - allowed_langs: allowed_langs.into_vec(), + allowed_langs, }).await; let mut task = match task { diff --git a/src/bots/approved_bot/modules/random.rs b/src/bots/approved_bot/modules/random.rs index d808314..fa33f3f 100644 --- a/src/bots/approved_bot/modules/random.rs +++ b/src/bots/approved_bot/modules/random.rs @@ -1,4 +1,5 @@ use moka::future::Cache; +use smartstring::alias::String as SmartString; use smallvec::SmallVec; use strum_macros::{Display, EnumIter}; use teloxide::{ @@ -169,8 +170,8 @@ where async fn get_random_item_handler( cq: CallbackQuery, bot: CacheMe>, - item_getter: fn(allowed_langs: SmallVec<[String; 3]>) -> Fut, - user_langs_cache: Cache>, + item_getter: fn(allowed_langs: SmallVec<[SmartString; 3]>) -> Fut, + user_langs_cache: Cache>, ) -> BotHandlerInternal where T: Format, @@ -243,7 +244,7 @@ async fn get_genres_by_meta_handler( } }; - let mut buttons: Vec> = book_library::get_genres(meta.to_string()).await? + let mut buttons: Vec> = book_library::get_genres(meta.into()).await? .items .into_iter() .map(|genre| { @@ -294,7 +295,7 @@ async fn get_random_book_by_genre( cq: CallbackQuery, bot: CacheMe>, genre_id: u32, - user_langs_cache: Cache>, + user_langs_cache: Cache>, ) -> BotHandlerInternal { let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await; diff --git a/src/bots/approved_bot/modules/search.rs b/src/bots/approved_bot/modules/search.rs index 9d873cc..3def819 100644 --- a/src/bots/approved_bot/modules/search.rs +++ b/src/bots/approved_bot/modules/search.rs @@ -1,6 +1,8 @@ use core::fmt::Debug; use std::str::FromStr; +use smartstring::alias::String as SmartString; + use moka::future::Cache; use regex::Regex; use smallvec::SmallVec; @@ -112,8 +114,8 @@ async fn generic_search_pagination_handler( cq: CallbackQuery, bot: CacheMe>, search_data: SearchCallbackData, - items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, - user_langs_cache: Cache>, + items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut, + user_langs_cache: Cache>, ) -> BotHandlerInternal where T: Format + Clone + Debug, diff --git a/src/bots/approved_bot/modules/settings.rs b/src/bots/approved_bot/modules/settings.rs index 2cebe5c..65d31a2 100644 --- a/src/bots/approved_bot/modules/settings.rs +++ b/src/bots/approved_bot/modules/settings.rs @@ -1,4 +1,6 @@ -use std::{collections::HashSet, str::FromStr, vec}; +use std::{collections::HashSet, str::FromStr}; + +use smartstring::alias::String as SmartString; use crate::{bots::{ approved_bot::{ @@ -28,8 +30,8 @@ enum SettingsCommand { #[derive(Clone)] enum SettingsCallbackData { Settings, - On { code: String }, - Off { code: String }, + On { code: SmartString }, + Off { code: SmartString }, } impl FromStr for SettingsCallbackData { @@ -52,8 +54,8 @@ impl FromStr for SettingsCallbackData { let code = caps["code"].to_string(); match action { - "on" => Ok(SettingsCallbackData::On { code }), - "off" => Ok(SettingsCallbackData::Off { code }), + "on" => Ok(SettingsCallbackData::On { code: code.into() }), + "off" => Ok(SettingsCallbackData::Off { code: code.into() }), _ => Err(strum::ParseError::VariantNotFound), } } @@ -88,7 +90,7 @@ async fn settings_handler(message: Message, bot: CacheMe>) -> BotH Ok(()) } -fn get_lang_keyboard(all_langs: Vec, allowed_langs: HashSet) -> InlineKeyboardMarkup { +fn get_lang_keyboard(all_langs: Vec, allowed_langs: HashSet) -> InlineKeyboardMarkup { let buttons = all_langs .into_iter() .map(|lang| { @@ -120,7 +122,7 @@ async fn settings_callback_handler( bot: CacheMe>, callback_data: SettingsCallbackData, me: Me, - user_langs_cache: Cache>, + user_langs_cache: Cache>, ) -> BotHandlerInternal { let message = match cq.message { Some(v) => v, @@ -134,7 +136,7 @@ async fn settings_callback_handler( let allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await; - let mut allowed_langs_set: HashSet = HashSet::new(); + let mut allowed_langs_set: HashSet = HashSet::new(); allowed_langs.into_iter().for_each(|v| { allowed_langs_set.insert(v); }); diff --git a/src/bots/approved_bot/modules/update_history.rs b/src/bots/approved_bot/modules/update_history.rs index afd9a1f..2658881 100644 --- a/src/bots/approved_bot/modules/update_history.rs +++ b/src/bots/approved_bot/modules/update_history.rs @@ -152,8 +152,8 @@ async fn update_log_pagination_handler( let mut items_page = get_uploaded_books( update_callback_data.page, - update_callback_data.from.format("%Y-%m-%d").to_string(), - update_callback_data.to.format("%Y-%m-%d").to_string(), + update_callback_data.from.format("%Y-%m-%d").to_string().into(), + update_callback_data.to.format("%Y-%m-%d").to_string().into(), ) .await?; @@ -168,8 +168,8 @@ async fn update_log_pagination_handler( if update_callback_data.page > items_page.pages { items_page = get_uploaded_books( items_page.pages, - update_callback_data.from.format("%Y-%m-%d").to_string(), - update_callback_data.to.format("%Y-%m-%d").to_string(), + update_callback_data.from.format("%Y-%m-%d").to_string().into(), + update_callback_data.to.format("%Y-%m-%d").to_string().into(), ).await?; } diff --git a/src/bots/approved_bot/services/batch_downloader.rs b/src/bots/approved_bot/services/batch_downloader.rs index 9541918..9e75481 100644 --- a/src/bots/approved_bot/services/batch_downloader.rs +++ b/src/bots/approved_bot/services/batch_downloader.rs @@ -1,3 +1,6 @@ +use smallvec::SmallVec; +use smartstring::alias::String as SmartString; + use serde::{Deserialize, Serialize}; use crate::config; @@ -23,7 +26,7 @@ pub struct CreateTaskData { pub object_id: u32, pub object_type: TaskObjectType, pub file_format: String, - pub allowed_langs: Vec, + pub allowed_langs: SmallVec<[SmartString; 3]>, } #[derive(Deserialize)] diff --git a/src/bots/approved_bot/services/book_library/mod.rs b/src/bots/approved_bot/services/book_library/mod.rs index fb6c2f0..fb69dbd 100644 --- a/src/bots/approved_bot/services/book_library/mod.rs +++ b/src/bots/approved_bot/services/book_library/mod.rs @@ -1,6 +1,8 @@ pub mod formaters; pub mod types; +use smartstring::alias::String as SmartString; + use serde::de::DeserializeOwned; use smallvec::SmallVec; @@ -8,7 +10,7 @@ use crate::config; use self::types::Empty; -fn get_allowed_langs_params(allowed_langs: SmallVec<[String; 3]>) -> Vec<(&'static str, String)> { +fn get_allowed_langs_params(allowed_langs: SmallVec<[SmartString; 3]>) -> Vec<(&'static str, SmartString)> { allowed_langs .into_iter() .map(|lang| ("allowed_langs", lang)) @@ -17,7 +19,7 @@ fn get_allowed_langs_params(allowed_langs: SmallVec<[String; 3]>) -> Vec<(&'stat async fn _make_request( url: &str, - params: Vec<(&str, String)>, + params: Vec<(&str, SmartString)>, ) -> Result> where T: DeserializeOwned, @@ -46,34 +48,34 @@ pub async fn get_book( } pub async fn get_random_book_by_genre( - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, genre: Option, ) -> Result> { - let mut params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs); + let mut params = get_allowed_langs_params(allowed_langs); if let Some(v) = genre { - params.push(("genre", v.to_string())); + params.push(("genre", v.to_string().into())); } _make_request("/api/v1/books/random", params).await } pub async fn get_random_book( - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result> { get_random_book_by_genre(allowed_langs, None).await } pub async fn get_random_author( - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result> { - let params: Vec<(&str, String)> = get_allowed_langs_params(allowed_langs); + let params = get_allowed_langs_params(allowed_langs); _make_request("/api/v1/authors/random", params).await } pub async fn get_random_sequence( - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result> { let params = get_allowed_langs_params(allowed_langs); @@ -85,7 +87,7 @@ pub async fn get_genre_metas() -> Result, Box Result, Box> { let params = vec![("meta", meta)]; @@ -97,12 +99,12 @@ const PAGE_SIZE: &str = "5"; pub async fn search_book( query: String, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/books/search/{query}").as_str(), params).await } @@ -110,12 +112,12 @@ pub async fn search_book( pub async fn search_author( query: String, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/authors/search/{query}").as_str(), params).await } @@ -123,12 +125,12 @@ pub async fn search_author( pub async fn search_sequence( query: String, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/sequences/search/{query}").as_str(), params).await } @@ -136,12 +138,12 @@ pub async fn search_sequence( pub async fn search_translator( query: String, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request( format!("/api/v1/translators/search/{query}").as_str(), @@ -165,12 +167,12 @@ pub async fn get_author_annotation( pub async fn get_author_books( id: u32, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/authors/{id}/books").as_str(), params).await } @@ -178,12 +180,12 @@ pub async fn get_author_books( pub async fn get_translator_books( id: u32, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/translators/{id}/books").as_str(), params).await } @@ -191,27 +193,27 @@ pub async fn get_translator_books( pub async fn get_sequence_books( id: u32, page: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let mut params = get_allowed_langs_params(allowed_langs); - params.push(("page", page.to_string())); - params.push(("size", PAGE_SIZE.to_string())); + params.push(("page", page.to_string().into())); + params.push(("size", PAGE_SIZE.to_string().into())); _make_request(format!("/api/v1/sequences/{id}/books").as_str(), params).await } pub async fn get_uploaded_books( page: u32, - uploaded_gte: String, - uploaded_lte: String, + uploaded_gte: SmartString, + uploaded_lte: SmartString, ) -> Result, Box> { let params = vec![ - ("page", page.to_string()), - ("size", PAGE_SIZE.to_string()), + ("page", page.to_string().into()), + ("size", PAGE_SIZE.to_string().into()), ("uploaded_gte", uploaded_gte), ("uploaded_lte", uploaded_lte), - ("is_deleted", "false".to_string()), + ("is_deleted", "false".into()), ]; _make_request("/api/v1/books/", params).await @@ -219,7 +221,7 @@ pub async fn get_uploaded_books( pub async fn get_author_books_available_types( id: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let params = get_allowed_langs_params(allowed_langs); @@ -228,7 +230,7 @@ pub async fn get_author_books_available_types( pub async fn get_translator_books_available_types( id: u32, - allowed_langs: SmallVec<[String; 3]>, + allowed_langs: SmallVec<[SmartString; 3]>, ) -> Result, Box> { let params = get_allowed_langs_params(allowed_langs); @@ -237,7 +239,7 @@ pub async fn get_translator_books_available_types( pub async fn get_sequence_books_available_types( id: u32, - allowed_langs: SmallVec<[String; 3]> + allowed_langs: SmallVec<[SmartString; 3]> ) -> Result, Box> { let params = get_allowed_langs_params(allowed_langs); diff --git a/src/bots/approved_bot/services/user_settings/mod.rs b/src/bots/approved_bot/services/user_settings/mod.rs index ea52576..e60d7bb 100644 --- a/src/bots/approved_bot/services/user_settings/mod.rs +++ b/src/bots/approved_bot/services/user_settings/mod.rs @@ -2,24 +2,25 @@ use moka::future::Cache; use serde::Deserialize; use serde_json::json; use smallvec::{SmallVec, smallvec}; -use teloxide::{types::{UserId, ChatId}}; +use teloxide::types::{UserId, ChatId}; +use smartstring::alias::String as SmartString; use crate::config; #[derive(Deserialize, Debug, Clone)] pub struct Lang { // pub id: u32, - pub label: String, - pub code: String, + pub label: SmartString, + pub code: SmartString, } #[derive(Deserialize, Debug, Clone)] pub struct UserSettings { pub user_id: u64, - pub last_name: String, - pub first_name: String, - pub username: String, - pub source: String, + pub last_name: SmartString, + pub first_name: SmartString, + pub username: SmartString, + pub source: SmartString, pub allowed_langs: SmallVec<[Lang; 3]>, } @@ -42,17 +43,21 @@ pub async fn get_user_settings( pub async fn get_user_or_default_lang_codes( user_id: UserId, - cache: Cache> -) -> SmallVec<[String; 3]> { + cache: Cache> +) -> SmallVec<[SmartString; 3]> { if let Some(cached_langs) = cache.get(&user_id) { return cached_langs; } - let default_lang_codes = smallvec![String::from("ru"), String::from("be"), String::from("uk")]; + let default_lang_codes = smallvec![ + "ru".into(), + "be".into(), + "uk".into() + ]; match get_user_settings(user_id).await { Ok(v) => { - let langs: SmallVec<[String; 3]> = v.allowed_langs.into_iter().map(|lang| lang.code).collect(); + let langs: SmallVec<[SmartString; 3]> = v.allowed_langs.into_iter().map(|lang| lang.code).collect(); cache.insert(user_id, langs.clone()).await; langs }, @@ -66,8 +71,8 @@ pub async fn create_or_update_user_settings( first_name: String, username: String, source: String, - allowed_langs: SmallVec<[String; 3]>, - cache: Cache> + allowed_langs: SmallVec<[SmartString; 3]>, + cache: Cache> ) -> Result> { cache.invalidate(&user_id).await; diff --git a/src/bots_manager/mod.rs b/src/bots_manager/mod.rs index 559060d..453cd7e 100644 --- a/src/bots_manager/mod.rs +++ b/src/bots_manager/mod.rs @@ -1,5 +1,7 @@ pub mod bot_manager_client; +use smartstring::alias::String as SmartString; + use std::collections::HashMap; use std::net::SocketAddr; use std::sync::atomic::{AtomicBool, Ordering}; @@ -26,7 +28,7 @@ use crate::config; #[derive(Clone)] pub struct AppState { pub user_activity_cache: Cache, - pub user_langs_cache: Cache>, + pub user_langs_cache: Cache>, pub chat_donation_notifications_cache: Cache, }