diff --git a/Cargo.lock b/Cargo.lock index 432adc8..529d587 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -453,6 +453,7 @@ dependencies = [ "grammers-mtproto", "grammers-mtsender", "grammers-session", + "higher-order-closure", "lazy_static", "log", "macros", @@ -1372,6 +1373,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "higher-order-closure" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c450d87a307c754cbd7718dfca84b8904e313157191fae5b249d37aab216c89" + [[package]] name = "hmac" version = "0.11.0" diff --git a/bobot_impl/Cargo.toml b/bobot_impl/Cargo.toml index a998dce..b60c024 100644 --- a/bobot_impl/Cargo.toml +++ b/bobot_impl/Cargo.toml @@ -37,3 +37,4 @@ pomelo = "0.1.5" regex = "1" flexi_logger = { version = "0.22", features = [ "async", "colors" ] } teloxide = { version = "0.7", features = ["macros", "auto-send", "redis-storage", "erased"] } +higher-order-closure = "0.0.5" diff --git a/bobot_impl/src/modules/sticker.rs b/bobot_impl/src/modules/sticker.rs index efaa691..7a24785 100644 --- a/bobot_impl/src/modules/sticker.rs +++ b/bobot_impl/src/modules/sticker.rs @@ -1,7 +1,9 @@ use std::str::FromStr; use self::entities::tags::ModelRedis; -use crate::persist::redis::{scope_key_by_chatuser, CachedQuery, CachedQueryTrait, RedisStr}; +use crate::persist::redis::{ + scope_key_by_chatuser, CachedQuery, CachedQueryTrait, RedisPool, RedisStr, +}; use crate::persist::Result; use crate::statics::{DB, REDIS, TG}; use crate::tg::command::{parse_cmd, Arg}; @@ -22,6 +24,8 @@ use teloxide::types::{ MessageCommon, MessageKind, Update, UpdateKind, }; +use higher_order_closure; + // redis keys const KEY_TYPE_TAG: &str = "wc:tag"; const KEY_TYPE_STICKER_ID: &str = "wc:stickerid"; @@ -244,7 +248,10 @@ async fn handle_inline(query: &InlineQuery) -> Result<()> { Ok(Some(stickers)) } }) - .redis_query(|key, redis| async move { Ok(None) }) + .redis_query(|key: &_, redis: &_| async move { + println!("key{}", key); + Ok(None) + }) .build()? .query( Arc::clone(DB.deref()), diff --git a/bobot_impl/src/persist/redis.rs b/bobot_impl/src/persist/redis.rs index bebd4ee..dc13817 100644 --- a/bobot_impl/src/persist/redis.rs +++ b/bobot_impl/src/persist/redis.rs @@ -1,6 +1,9 @@ use super::Result; use crate::util::{ - callback::{CacheCallback, CacheCb, CacheMissCallback, CacheMissCb, OutputBoxer}, + callback::{ + BotDbFuture, BoxedCacheCallback, CacheCallback, CacheCb, CacheMissCallback, CacheMissCb, + OutputBoxer, + }, error::BotError, }; use anyhow::anyhow; @@ -12,6 +15,7 @@ use bb8_redis::RedisConnectionManager; use async_trait::async_trait; use futures::Future; +use higher_order_closure::higher_order_closure; use redis::{AsyncCommands, ErrorKind, FromRedisValue, Pipeline, RedisError, ToRedisArgs}; use serde::{de::DeserializeOwned, Serialize}; use std::sync::Arc; @@ -39,24 +43,21 @@ pub(crate) struct CachedQueryBuilder { } impl CachedQueryBuilder { - pub(crate) fn redis_query(mut self, func: F) -> Self + pub(crate) fn redis_query<'a, F>(mut self, func: F) -> Self where - F: for<'b> FnOnce(&'b String, &'b RedisPool) -> Fut + Sync + Send + 'static, - R: DeserializeOwned + 'static, - Fut: Future>> + Send + 'static, + F: for<'b> CacheCallback<'b, RedisPool, R> + 'static, { - let b = Box::new(OutputBoxer(func)); - self.redis_query = Some(CacheCb(b)); + // self.redis_query = Some(CacheCb::new(func)); self } - pub(crate) fn sql_query(mut self, func: F) -> Self + pub(crate) fn sql_query<'a, F, Fut>(mut self, func: F) -> Self where - F: for<'b> FnOnce(&'b String, &'b Arc) -> Fut + Sync + Send + 'static, - R: DeserializeOwned + 'static, - Fut: Future>> + Send + 'static, + F: for<'b> FnOnce(&'b String, &'b Arc) -> Fut + Sync + Send + 'a, + R: DeserializeOwned + 'a, + Fut: Future>> + Send + 'a, { - self.sql_query = Some(CacheCb(Box::new(OutputBoxer(func)))); + //self.sql_query = Some(CacheCb(Box::new(OutputBoxer(func)))); self } diff --git a/bobot_impl/src/util/callback.rs b/bobot_impl/src/util/callback.rs index 44b1a36..5f8f3cd 100644 --- a/bobot_impl/src/util/callback.rs +++ b/bobot_impl/src/util/callback.rs @@ -23,34 +23,47 @@ pub(crate) struct CacheCb( pub(crate) Box BoxedCacheCallback<'a, T, R, Fut = BotDbFuture<'a, Result>>>>, ); +impl <'a, T, R: 'a> CacheCb { + + pub(crate) fn new(func: F) -> Self + where + F: for<'b> CacheCallback<'b, T, R> + 'static, + R: DeserializeOwned + 'static + { + Self(Box::new(OutputBoxer(func))) + + } +} + impl<'a, T, R> CacheCallback<'a, T, R> for CacheCb where - R: DeserializeOwned + 'static, + R: DeserializeOwned + 'a, { type Fut = BotDbFuture<'a, Result>>; - fn cb(self, key: &String, db: &T) -> Self::Fut { + fn cb(self, key: &'a String, db: &'a T) -> Self::Fut { self.0.cb_boxed(key, db) } } pub trait CacheCallback<'a, T, R>: Send + Sync { type Fut: Future>> + Send + 'a; - fn cb(self, key: &String, db: &T) -> Self::Fut; + fn cb(self, key: &'a String, db: &'a T) -> Self::Fut; } pub trait BoxedCacheCallback<'a, T, R>: Send + Sync { type Fut: Future>> + Send + 'a; - fn cb_boxed(self: Box, key: &String, db: &T) -> Self::Fut; + fn cb_boxed(self: Box, key: &'a String, db: &'a T) -> Self::Fut; } impl<'a, F, T, R, Fut> CacheCallback<'a, T, R> for F where - F: for<'b> FnOnce(&'b String, &'b T) -> Fut + Sync + Send + 'static, - R: DeserializeOwned + 'static, - Fut: Future>> + Send + 'static, + F: FnOnce(&'a String, &'a T) -> Fut + Sync + Send + 'a, + R: DeserializeOwned + 'a, + T: 'a, + Fut: Future>> + Send + 'a, { type Fut = Fut; - fn cb(self, key: &String, db: &T) -> Self::Fut { + fn cb(self, key: &'a String, db: &'a T) -> Self::Fut { self(key, db) } } @@ -58,22 +71,23 @@ where impl<'a, F, T, R> BoxedCacheCallback<'a, T, R> for OutputBoxer where F: CacheCallback<'a, T, R>, - R: 'a, + R: DeserializeOwned + 'a { type Fut = BotDbFuture<'a, Result>>; - fn cb_boxed(self: Box, key: &String, db: &T) -> Self::Fut { + fn cb_boxed(self: Box, key: &'a String, db: &'a T) -> Self::Fut { (*self).0.cb(key, db).boxed() } } impl<'a, F, T, R, Fut> BoxedCacheCallback<'a, T, R> for F where - F: for<'b> FnOnce(&'b String, &'b T) -> Fut + Sync + Send + 'static, - R: DeserializeOwned + 'static, - Fut: Future>> + Send + 'static, + F: FnOnce(&'a String, &'a T) -> Fut + Sync + Send + 'a, + R: 'a, + T: 'a, + Fut: Future>> + Send + 'a, { type Fut = Fut; - fn cb_boxed(self: Box, key: &String, db: &T) -> Self::Fut { + fn cb_boxed(self: Box, key: &'a String, db: &'a T) -> Self::Fut { (*self)(key, db) } }