magnetar/ext_calckey_model/src/emoji.rs

104 lines
3.0 KiB
Rust

use crate::{CalckeyDbError, CalckeyModel};
use ck::emoji;
use sea_orm::prelude::Expr;
use sea_orm::{ColumnTrait, EntityTrait, IntoSimpleExpr, QueryFilter, QueryOrder};
#[derive(Debug, Copy, Clone)]
pub struct EmojiTag<'a> {
pub name: &'a str,
pub host: Option<&'a str>,
}
pub struct EmojiResolver(CalckeyModel);
impl EmojiResolver {
pub fn new(db: CalckeyModel) -> Self {
EmojiResolver(db)
}
pub async fn get_local_emoji(&self) -> Result<Vec<emoji::Model>, CalckeyDbError> {
Ok(emoji::Entity::find()
.filter(emoji::Column::Host.is_null())
.order_by_asc(emoji::Column::Category)
.order_by_asc(emoji::Column::Name)
.all(self.0.inner())
.await?)
}
pub async fn fetch_emoji(
&self,
shortcode: &str,
host: Option<&str>,
) -> Result<Option<emoji::Model>, CalckeyDbError> {
let host_filter = if let Some(host) = host {
emoji::Column::Host.eq(host)
} else {
emoji::Column::Host.is_null()
};
let name_filter = emoji::Column::Name.eq(shortcode);
let filter = host_filter.and(name_filter);
Ok(emoji::Entity::find()
.filter(filter)
.one(self.0.inner())
.await?)
}
pub async fn fetch_many_emojis(
&self,
shortcodes: &[String],
host: Option<&str>,
) -> Result<Vec<emoji::Model>, CalckeyDbError> {
let host_filter = if let Some(host) = host {
emoji::Column::Host.eq(host)
} else {
emoji::Column::Host.is_null()
};
let name_filter = emoji::Column::Name.is_in(shortcodes);
let filter = host_filter.and(name_filter);
Ok(emoji::Entity::find()
.filter(filter)
.all(self.0.inner())
.await?)
}
pub async fn fetch_many_tagged_emojis(
&self,
shortcodes: &[EmojiTag<'_>],
) -> Result<Vec<emoji::Model>, CalckeyDbError> {
let remote_shortcode_host_pairs = shortcodes
.iter()
.filter_map(|s| {
s.host.map(|host| {
Expr::tuple([
Expr::value(s.name.to_string()),
Expr::value(host.to_string()),
])
})
})
.collect::<Vec<_>>();
let local_shortcodes = shortcodes
.iter()
.filter_map(|s| s.host.is_none().then_some(s.name.to_string()))
.collect::<Vec<_>>();
let remote_filter = Expr::tuple([
emoji::Column::Name.into_simple_expr(),
emoji::Column::Host.into_simple_expr(),
])
.is_in(remote_shortcode_host_pairs);
let local_filter = emoji::Column::Name
.is_in(local_shortcodes)
.and(emoji::Column::Host.is_null());
let filter = remote_filter.or(local_filter);
Ok(emoji::Entity::find()
.filter(filter)
.all(self.0.inner())
.await?)
}
}