use crate::models::{FeedID, Url};
use crate::schema::feeds;
use feed_rs::model::Feed as FeedRS;
use std::hash::{Hash, Hasher};
#[derive(Identifiable, Clone, Insertable, Queryable, Eq, Debug)]
#[diesel(primary_key(feed_id))]
#[diesel(table_name = feeds)]
#[diesel(check_for_backend(SQLite))]
pub struct Feed {
pub feed_id: FeedID,
pub label: String,
pub website: Option<Url>,
pub feed_url: Option<Url>,
pub icon_url: Option<Url>,
pub error_count: i32,
pub error_message: Option<String>,
}
impl Hash for Feed {
fn hash<H: Hasher>(&self, state: &mut H) {
self.feed_id.hash(state);
}
}
impl PartialEq for Feed {
fn eq(&self, other: &Feed) -> bool {
self.feed_id == other.feed_id
}
}
impl Feed {
pub fn from_feed_rs(feed: &FeedRS, title: Option<String>, url: &Url) -> Self {
let title = match title {
Some(title) => title,
None => match &feed.title {
Some(title) => title.content.clone(),
None => "Unknown Feed".into(),
},
};
let website = feed
.links
.iter()
.find(|link| link.rel == Some("alternate".to_owned()))
.and_then(|link| Url::parse(&link.href).ok());
let website = match website {
Some(website) => Some(website),
None => feed
.links
.iter()
.find(|link| link.rel.is_none())
.and_then(|link| Url::parse(&link.href).ok()),
};
let website = match website {
Some(website) => Some(website),
None => feed.links.first().and_then(|link| Url::parse(&link.href).ok()),
};
let icon_url = match feed.icon.as_ref().and_then(|icon| Url::parse(&icon.uri).ok()) {
Some(url) => Some(url),
None => feed.logo.as_ref().and_then(|logo| Url::parse(&logo.uri).ok()),
};
Feed {
feed_id: FeedID::new(url.as_str()),
label: title,
website,
feed_url: Some(url.clone()),
icon_url,
error_count: 0,
error_message: None,
}
}
}
#[derive(Queryable, Debug)]
#[diesel(check_for_backend(SQLite))]
pub struct FeedCount {
pub feed_id: FeedID,
pub count: i64,
}