Koucha/koucha/src/feed.rs

98 lines
2 KiB
Rust
Raw Normal View History

2026-01-20 16:08:36 -08:00
use crate::{
Result,
Item,
Channel,
2026-01-20 16:36:14 -08:00
channel::{
UnparsedChannel,
ChannelId,
},
user::UserId,
2026-01-20 16:08:36 -08:00
};
use sqlx::SqlitePool;
2026-01-21 12:47:47 -08:00
#[derive(Copy, Clone)]
pub struct FeedId(i64);
2026-01-20 16:08:36 -08:00
impl From<FeedId> for i64 { fn from(id: FeedId) -> Self { id.0 } }
2026-01-20 16:36:14 -08:00
pub struct UnparsedFeed {
pub id: i64,
pub title: String,
}
impl UnparsedFeed {
pub fn parse(self) -> Result<Feed> {
Ok(Feed {
id: FeedId(self.id),
title: self.title,
})
}
}
2026-01-20 16:08:36 -08:00
pub struct Feed {
2026-01-21 12:47:47 -08:00
id: FeedId,
title: String,
2026-01-20 16:08:36 -08:00
}
impl Feed {
2026-01-21 12:47:47 -08:00
pub fn id(&self) -> FeedId { self.id }
pub fn title(&self) -> &str { &self.title }
2026-01-20 16:36:14 -08:00
pub async fn create(
pool: &SqlitePool, id: UserId, name: &str
) -> Result<Self> {
2026-01-21 12:47:47 -08:00
let int_id = i64::from(id);
2026-01-20 16:36:14 -08:00
let new_feed = sqlx::query_as!(
UnparsedFeed,
"INSERT INTO feeds (user_id, title)
VALUES (?, ?)
2026-01-21 12:47:47 -08:00
RETURNING id as `id!`, title",
int_id, name
2026-01-20 16:36:14 -08:00
).fetch_one(pool).await?.parse();
new_feed
}
pub async fn add_channel(
pool: &SqlitePool, id: FeedId, channel_id: ChannelId
) -> Result<()> {
sqlx::query!(
"INSERT INTO feed_channels (feed_id, channel_id)
VALUES (?, ?)",
id.0, channel_id.0
).execute(pool).await?;
Ok(())
}
2026-01-20 16:08:36 -08:00
pub async fn get_items(
pool: &SqlitePool, id: FeedId, limit: u8, offset: u32
) -> Result<Vec<Item>> {
let items = sqlx::query_as!(
Item,
2026-01-20 16:36:14 -08:00
"SELECT item_id as id FROM feed_items
2026-01-20 16:08:36 -08:00
WHERE feed_id = ? AND archived = FALSE
ORDER BY score DESC
LIMIT ? OFFSET ?",
id.0, limit, offset
).fetch_all(pool).await?;
Ok(items)
}
pub async fn get_channels(
pool: &SqlitePool, id: FeedId
) -> Result<Vec<Channel>> {
let channels: Result<Vec<Channel>> = sqlx::query_as!(
UnparsedChannel,
"SELECT c.id as `id!`, c.title, c.link, c.description, c.last_fetched
FROM channels c
JOIN feed_channels fc on c.id = fc.channel_id
WHERE fc.feed_id = ?",
id.0
).fetch_all(pool).await?.into_iter()
.map(UnparsedChannel::parse).collect();
channels
}
}