This commit is contained in:
2023-06-21 13:38:17 +02:00
parent a369f470b8
commit 9e7922d03c
13 changed files with 113 additions and 78 deletions

13
Cargo.lock generated
View File

@@ -213,6 +213,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"smallvec", "smallvec",
"smartstring",
"strum", "strum",
"strum_macros", "strum_macros",
"teloxide", "teloxide",
@@ -1826,6 +1827,18 @@ dependencies = [
"serde", "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]] [[package]]
name = "smawk" name = "smawk"
version = "0.3.1" version = "0.3.1"

View File

@@ -29,3 +29,4 @@ lazy_static = "1.4.0"
moka = { version = "0.11.1", features = ["future"] } moka = { version = "0.11.1", features = ["future"] }
axum = "0.6.18" axum = "0.6.18"
smallvec = { version = "1.10.0", features = ["serde"] } smallvec = { version = "1.10.0", features = ["serde"] }
smartstring = { version = "1.0.1", features = ["serde"] }

View File

@@ -2,6 +2,8 @@ pub mod modules;
pub mod services; pub mod services;
mod tools; mod tools;
use smartstring::alias::String as SmartString;
use moka::future::Cache; use moka::future::Cache;
use smallvec::SmallVec; use smallvec::SmallVec;
use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}}; use teloxide::{prelude::*, types::BotCommand, adaptors::{Throttle, CacheMe}};
@@ -24,7 +26,7 @@ async fn _update_activity(
me: teloxide::types::Me, me: teloxide::types::Me,
user: teloxide::types::User, user: teloxide::types::User,
activity_cache: Cache<UserId, ()>, activity_cache: Cache<UserId, ()>,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> Option<()> { ) -> Option<()> {
if activity_cache.contains_key(&user.id) { if activity_cache.contains_key(&user.id) {
return None; return None;

View File

@@ -1,6 +1,8 @@
use core::fmt::Debug; use core::fmt::Debug;
use std::str::FromStr; use std::str::FromStr;
use smartstring::alias::String as SmartString;
use moka::future::Cache; use moka::future::Cache;
use regex::Regex; use regex::Regex;
use smallvec::SmallVec; use smallvec::SmallVec;
@@ -119,8 +121,8 @@ async fn send_book_handler<T, P, Fut>(
message: Message, message: Message,
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
command: BookCommand, command: BookCommand,
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> crate::bots::BotHandlerInternal ) -> crate::bots::BotHandlerInternal
where where
T: Format + Clone + Debug, T: Format + Clone + Debug,
@@ -191,8 +193,8 @@ async fn send_pagination_book_handler<T, P, Fut>(
cq: CallbackQuery, cq: CallbackQuery,
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
callback_data: BookCallbackData, callback_data: BookCallbackData,
books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, books_getter: fn(id: u32, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> crate::bots::BotHandlerInternal ) -> crate::bots::BotHandlerInternal
where where
T: Format + Clone + Debug, T: Format + Clone + Debug,

View File

@@ -438,7 +438,7 @@ async fn download_archive(
object_id: id, object_id: id,
object_type: task_type, object_type: task_type,
file_format: file_type, file_format: file_type,
allowed_langs: allowed_langs.into_vec(), allowed_langs,
}).await; }).await;
let mut task = match task { let mut task = match task {

View File

@@ -1,4 +1,5 @@
use moka::future::Cache; use moka::future::Cache;
use smartstring::alias::String as SmartString;
use smallvec::SmallVec; use smallvec::SmallVec;
use strum_macros::{Display, EnumIter}; use strum_macros::{Display, EnumIter};
use teloxide::{ use teloxide::{
@@ -169,8 +170,8 @@ where
async fn get_random_item_handler<T, Fut>( async fn get_random_item_handler<T, Fut>(
cq: CallbackQuery, cq: CallbackQuery,
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
item_getter: fn(allowed_langs: SmallVec<[String; 3]>) -> Fut, item_getter: fn(allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> BotHandlerInternal ) -> BotHandlerInternal
where where
T: Format, T: Format,
@@ -243,7 +244,7 @@ async fn get_genres_by_meta_handler(
} }
}; };
let mut buttons: Vec<Vec<InlineKeyboardButton>> = book_library::get_genres(meta.to_string()).await? let mut buttons: Vec<Vec<InlineKeyboardButton>> = book_library::get_genres(meta.into()).await?
.items .items
.into_iter() .into_iter()
.map(|genre| { .map(|genre| {
@@ -294,7 +295,7 @@ async fn get_random_book_by_genre(
cq: CallbackQuery, cq: CallbackQuery,
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
genre_id: u32, genre_id: u32,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> BotHandlerInternal { ) -> BotHandlerInternal {
let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await; let allowed_langs = get_user_or_default_lang_codes(cq.from.id, user_langs_cache).await;

View File

@@ -1,6 +1,8 @@
use core::fmt::Debug; use core::fmt::Debug;
use std::str::FromStr; use std::str::FromStr;
use smartstring::alias::String as SmartString;
use moka::future::Cache; use moka::future::Cache;
use regex::Regex; use regex::Regex;
use smallvec::SmallVec; use smallvec::SmallVec;
@@ -112,8 +114,8 @@ async fn generic_search_pagination_handler<T, P, Fut>(
cq: CallbackQuery, cq: CallbackQuery,
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
search_data: SearchCallbackData, search_data: SearchCallbackData,
items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[String; 3]>) -> Fut, items_getter: fn(query: String, page: u32, allowed_langs: SmallVec<[SmartString; 3]>) -> Fut,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> BotHandlerInternal ) -> BotHandlerInternal
where where
T: Format + Clone + Debug, T: Format + Clone + Debug,

View File

@@ -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::{ use crate::{bots::{
approved_bot::{ approved_bot::{
@@ -28,8 +30,8 @@ enum SettingsCommand {
#[derive(Clone)] #[derive(Clone)]
enum SettingsCallbackData { enum SettingsCallbackData {
Settings, Settings,
On { code: String }, On { code: SmartString },
Off { code: String }, Off { code: SmartString },
} }
impl FromStr for SettingsCallbackData { impl FromStr for SettingsCallbackData {
@@ -52,8 +54,8 @@ impl FromStr for SettingsCallbackData {
let code = caps["code"].to_string(); let code = caps["code"].to_string();
match action { match action {
"on" => Ok(SettingsCallbackData::On { code }), "on" => Ok(SettingsCallbackData::On { code: code.into() }),
"off" => Ok(SettingsCallbackData::Off { code }), "off" => Ok(SettingsCallbackData::Off { code: code.into() }),
_ => Err(strum::ParseError::VariantNotFound), _ => Err(strum::ParseError::VariantNotFound),
} }
} }
@@ -88,7 +90,7 @@ async fn settings_handler(message: Message, bot: CacheMe<Throttle<Bot>>) -> BotH
Ok(()) Ok(())
} }
fn get_lang_keyboard(all_langs: Vec<Lang>, allowed_langs: HashSet<String>) -> InlineKeyboardMarkup { fn get_lang_keyboard(all_langs: Vec<Lang>, allowed_langs: HashSet<SmartString>) -> InlineKeyboardMarkup {
let buttons = all_langs let buttons = all_langs
.into_iter() .into_iter()
.map(|lang| { .map(|lang| {
@@ -120,7 +122,7 @@ async fn settings_callback_handler(
bot: CacheMe<Throttle<Bot>>, bot: CacheMe<Throttle<Bot>>,
callback_data: SettingsCallbackData, callback_data: SettingsCallbackData,
me: Me, me: Me,
user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
) -> BotHandlerInternal { ) -> BotHandlerInternal {
let message = match cq.message { let message = match cq.message {
Some(v) => v, 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 allowed_langs = get_user_or_default_lang_codes(user.id, user_langs_cache.clone()).await;
let mut allowed_langs_set: HashSet<String> = HashSet::new(); let mut allowed_langs_set: HashSet<SmartString> = HashSet::new();
allowed_langs.into_iter().for_each(|v| { allowed_langs.into_iter().for_each(|v| {
allowed_langs_set.insert(v); allowed_langs_set.insert(v);
}); });

View File

@@ -152,8 +152,8 @@ async fn update_log_pagination_handler(
let mut items_page = get_uploaded_books( let mut items_page = get_uploaded_books(
update_callback_data.page, update_callback_data.page,
update_callback_data.from.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(), update_callback_data.to.format("%Y-%m-%d").to_string().into(),
) )
.await?; .await?;
@@ -168,8 +168,8 @@ async fn update_log_pagination_handler(
if update_callback_data.page > items_page.pages { if update_callback_data.page > items_page.pages {
items_page = get_uploaded_books( items_page = get_uploaded_books(
items_page.pages, items_page.pages,
update_callback_data.from.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(), update_callback_data.to.format("%Y-%m-%d").to_string().into(),
).await?; ).await?;
} }

View File

@@ -1,3 +1,6 @@
use smallvec::SmallVec;
use smartstring::alias::String as SmartString;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::config; use crate::config;
@@ -23,7 +26,7 @@ pub struct CreateTaskData {
pub object_id: u32, pub object_id: u32,
pub object_type: TaskObjectType, pub object_type: TaskObjectType,
pub file_format: String, pub file_format: String,
pub allowed_langs: Vec<String>, pub allowed_langs: SmallVec<[SmartString; 3]>,
} }
#[derive(Deserialize)] #[derive(Deserialize)]

View File

@@ -1,6 +1,8 @@
pub mod formaters; pub mod formaters;
pub mod types; pub mod types;
use smartstring::alias::String as SmartString;
use serde::de::DeserializeOwned; use serde::de::DeserializeOwned;
use smallvec::SmallVec; use smallvec::SmallVec;
@@ -8,7 +10,7 @@ use crate::config;
use self::types::Empty; 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 allowed_langs
.into_iter() .into_iter()
.map(|lang| ("allowed_langs", lang)) .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<T>( async fn _make_request<T>(
url: &str, url: &str,
params: Vec<(&str, String)>, params: Vec<(&str, SmartString)>,
) -> Result<T, Box<dyn std::error::Error + Send + Sync>> ) -> Result<T, Box<dyn std::error::Error + Send + Sync>>
where where
T: DeserializeOwned, T: DeserializeOwned,
@@ -46,34 +48,34 @@ pub async fn get_book(
} }
pub async fn get_random_book_by_genre( pub async fn get_random_book_by_genre(
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
genre: Option<u32>, genre: Option<u32>,
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
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 { 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 _make_request("/api/v1/books/random", params).await
} }
pub async fn get_random_book( pub async fn get_random_book(
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Book, Box<dyn std::error::Error + Send + Sync>> {
get_random_book_by_genre(allowed_langs, None).await get_random_book_by_genre(allowed_langs, None).await
} }
pub async fn get_random_author( pub async fn get_random_author(
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Author, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Author, Box<dyn std::error::Error + Send + Sync>> {
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 _make_request("/api/v1/authors/random", params).await
} }
pub async fn get_random_sequence( pub async fn get_random_sequence(
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Sequence, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Sequence, Box<dyn std::error::Error + Send + Sync>> {
let params = get_allowed_langs_params(allowed_langs); let params = get_allowed_langs_params(allowed_langs);
@@ -85,7 +87,7 @@ pub async fn get_genre_metas() -> Result<Vec<String>, Box<dyn std::error::Error
} }
pub async fn get_genres( pub async fn get_genres(
meta: String, meta: SmartString,
) -> Result<types::Page<types::Genre, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::Genre, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let params = vec![("meta", meta)]; let params = vec![("meta", meta)];
@@ -97,12 +99,12 @@ const PAGE_SIZE: &str = "5";
pub async fn search_book( pub async fn search_book(
query: String, query: String,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/books/search/{query}").as_str(), params).await _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( pub async fn search_author(
query: String, query: String,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::Author, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::Author, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/authors/search/{query}").as_str(), params).await _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( pub async fn search_sequence(
query: String, query: String,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::Sequence, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::Sequence, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/sequences/search/{query}").as_str(), params).await _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( pub async fn search_translator(
query: String, query: String,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::Translator, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::Translator, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request( _make_request(
format!("/api/v1/translators/search/{query}").as_str(), format!("/api/v1/translators/search/{query}").as_str(),
@@ -165,12 +167,12 @@ pub async fn get_author_annotation(
pub async fn get_author_books( pub async fn get_author_books(
id: u32, id: u32,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::AuthorBook, types::BookAuthor>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::AuthorBook, types::BookAuthor>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/authors/{id}/books").as_str(), params).await _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( pub async fn get_translator_books(
id: u32, id: u32,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::TranslatorBook, types::BookTranslator>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::TranslatorBook, types::BookTranslator>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/translators/{id}/books").as_str(), params).await _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( pub async fn get_sequence_books(
id: u32, id: u32,
page: u32, page: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<types::Page<types::SequenceBook, types::Sequence>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::SequenceBook, types::Sequence>, Box<dyn std::error::Error + Send + Sync>> {
let mut params = get_allowed_langs_params(allowed_langs); let mut params = get_allowed_langs_params(allowed_langs);
params.push(("page", page.to_string())); params.push(("page", page.to_string().into()));
params.push(("size", PAGE_SIZE.to_string())); params.push(("size", PAGE_SIZE.to_string().into()));
_make_request(format!("/api/v1/sequences/{id}/books").as_str(), params).await _make_request(format!("/api/v1/sequences/{id}/books").as_str(), params).await
} }
pub async fn get_uploaded_books( pub async fn get_uploaded_books(
page: u32, page: u32,
uploaded_gte: String, uploaded_gte: SmartString,
uploaded_lte: String, uploaded_lte: SmartString,
) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<types::Page<types::SearchBook, Empty>, Box<dyn std::error::Error + Send + Sync>> {
let params = vec![ let params = vec![
("page", page.to_string()), ("page", page.to_string().into()),
("size", PAGE_SIZE.to_string()), ("size", PAGE_SIZE.to_string().into()),
("uploaded_gte", uploaded_gte), ("uploaded_gte", uploaded_gte),
("uploaded_lte", uploaded_lte), ("uploaded_lte", uploaded_lte),
("is_deleted", "false".to_string()), ("is_deleted", "false".into()),
]; ];
_make_request("/api/v1/books/", params).await _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( pub async fn get_author_books_available_types(
id: u32, id: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
let params = get_allowed_langs_params(allowed_langs); 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( pub async fn get_translator_books_available_types(
id: u32, id: u32,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
let params = get_allowed_langs_params(allowed_langs); 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( pub async fn get_sequence_books_available_types(
id: u32, id: u32,
allowed_langs: SmallVec<[String; 3]> allowed_langs: SmallVec<[SmartString; 3]>
) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<Vec<String>, Box<dyn std::error::Error + Send + Sync>> {
let params = get_allowed_langs_params(allowed_langs); let params = get_allowed_langs_params(allowed_langs);

View File

@@ -2,24 +2,25 @@ use moka::future::Cache;
use serde::Deserialize; use serde::Deserialize;
use serde_json::json; use serde_json::json;
use smallvec::{SmallVec, smallvec}; use smallvec::{SmallVec, smallvec};
use teloxide::{types::{UserId, ChatId}}; use teloxide::types::{UserId, ChatId};
use smartstring::alias::String as SmartString;
use crate::config; use crate::config;
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct Lang { pub struct Lang {
// pub id: u32, // pub id: u32,
pub label: String, pub label: SmartString,
pub code: String, pub code: SmartString,
} }
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
pub struct UserSettings { pub struct UserSettings {
pub user_id: u64, pub user_id: u64,
pub last_name: String, pub last_name: SmartString,
pub first_name: String, pub first_name: SmartString,
pub username: String, pub username: SmartString,
pub source: String, pub source: SmartString,
pub allowed_langs: SmallVec<[Lang; 3]>, 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( pub async fn get_user_or_default_lang_codes(
user_id: UserId, user_id: UserId,
cache: Cache<UserId, SmallVec<[String; 3]>> cache: Cache<UserId, SmallVec<[SmartString; 3]>>
) -> SmallVec<[String; 3]> { ) -> SmallVec<[SmartString; 3]> {
if let Some(cached_langs) = cache.get(&user_id) { if let Some(cached_langs) = cache.get(&user_id) {
return cached_langs; 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 { match get_user_settings(user_id).await {
Ok(v) => { 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; cache.insert(user_id, langs.clone()).await;
langs langs
}, },
@@ -66,8 +71,8 @@ pub async fn create_or_update_user_settings(
first_name: String, first_name: String,
username: String, username: String,
source: String, source: String,
allowed_langs: SmallVec<[String; 3]>, allowed_langs: SmallVec<[SmartString; 3]>,
cache: Cache<UserId, SmallVec<[String; 3]>> cache: Cache<UserId, SmallVec<[SmartString; 3]>>
) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> { ) -> Result<UserSettings, Box<dyn std::error::Error + Send + Sync>> {
cache.invalidate(&user_id).await; cache.invalidate(&user_id).await;

View File

@@ -1,5 +1,7 @@
pub mod bot_manager_client; pub mod bot_manager_client;
use smartstring::alias::String as SmartString;
use std::collections::HashMap; use std::collections::HashMap;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@@ -26,7 +28,7 @@ use crate::config;
#[derive(Clone)] #[derive(Clone)]
pub struct AppState { pub struct AppState {
pub user_activity_cache: Cache<UserId, ()>, pub user_activity_cache: Cache<UserId, ()>,
pub user_langs_cache: Cache<UserId, SmallVec<[String; 3]>>, pub user_langs_cache: Cache<UserId, SmallVec<[SmartString; 3]>>,
pub chat_donation_notifications_cache: Cache<ChatId, ()>, pub chat_donation_notifications_cache: Cache<ChatId, ()>,
} }