diff --git a/Cargo.lock b/Cargo.lock index 1cd060b..4d3ec26 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -724,7 +724,6 @@ dependencies = [ "quick-xml", "reqwest", "serde_json", - "thiserror", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index a13c63c..a48b0c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,3 @@ reqwest = { version = "0.12", features = ["stream", "json", "rustls-tls"], defau serde_json = "1" chrono = "0.4" quick-xml = "0.38" -thiserror = "2" diff --git a/src/lib.rs b/src/lib.rs index bd894e1..118741b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,6 @@ mod web; use chrono::DateTime; use serde_json::Value; use std::sync::Arc; -use thiserror::Error; use tokio::{net::TcpListener, sync::RwLock}; pub async fn start( @@ -15,9 +14,7 @@ pub async fn start( listener: TcpListener, ) -> Result<(), Box> { let state = Arc::new(RwLock::new( - LiveFeed::new(title, link, desc, filter_titles) - .await - .unwrap(), + Feed::new(title, link, desc, filter_titles).await.unwrap(), )); web::serve(state, listener).await?; @@ -25,57 +22,7 @@ pub async fn start( Ok(()) } -#[derive(Error, Debug)] -enum FetchError {} - -trait Feed { - async fn fetch(&mut self) -> Result<(), Box>; -} - -#[cfg(test)] -struct TestFeed { - episodes: Vec, - pub(crate) amount_fetch_calls: usize, -} - -#[cfg(test)] -impl Default for TestFeed { - fn default() -> Self { - Self { - episodes: vec![Broadcast::test()], - amount_fetch_calls: 0, - } - } -} - -#[cfg(test)] -impl rss::ToRss for TestFeed { - fn title(&self) -> &str { - "Test RSS Title" - } - - fn link(&self) -> &str { - "https://test.rss" - } - - fn desc(&self) -> &str { - "Test RSS Desc" - } - - fn episodes(&self) -> &Vec { - &self.episodes - } -} - -#[cfg(test)] -impl Feed for TestFeed { - async fn fetch(&mut self) -> Result<(), Box> { - self.amount_fetch_calls += 1; - Ok(()) - } -} - -struct LiveFeed { +struct Feed { episodes: Vec, title: String, link: String, @@ -83,27 +30,7 @@ struct LiveFeed { filter_titles: Vec, } -impl Feed for LiveFeed { - async fn fetch(&mut self) -> Result<(), Box> { - let broadcasts = self.get_all_broadcasts().await?; - - for broadcast in broadcasts { - if !self.has_broadcast_url(&broadcast) { - if let Some(broadcast) = Broadcast::from_url(broadcast).await.unwrap() { - self.episodes.push(broadcast); - } else { - return Ok(()); - } - } - } - - self.only_keep_last_episodes(); - - Ok(()) - } -} - -impl LiveFeed { +impl Feed { async fn new( title: String, link: String, @@ -123,6 +50,24 @@ impl LiveFeed { Ok(ret) } + async fn fetch(&mut self) -> Result<(), Box> { + let broadcasts = self.get_all_broadcasts().await?; + + for broadcast in broadcasts { + if !self.has_broadcast_url(&broadcast) { + if let Some(broadcast) = Broadcast::from_url(broadcast).await.unwrap() { + self.episodes.push(broadcast); + } else { + return Ok(()); + } + } + } + + self.only_keep_last_episodes(); + + Ok(()) + } + fn only_keep_last_episodes(&mut self) { self.episodes = self.episodes.clone().into_iter().rev().take(10).collect(); // only keep last 10 @@ -172,18 +117,6 @@ struct Broadcast { } impl Broadcast { - #[cfg(test)] - fn test() -> Self { - use chrono::Local; - - Self { - url: "test.url".into(), - media_url: "test.media.url".into(), - title: "Test title".into(), - timestamp: Local::now().into(), - } - } - async fn from_url(url: String) -> Result, Box> { let data: Value = reqwest::get(&url).await?.json().await?; let Some(streams) = data["streams"].as_array() else { diff --git a/src/rss.rs b/src/rss.rs index a5148f2..fc507e2 100644 --- a/src/rss.rs +++ b/src/rss.rs @@ -1,4 +1,4 @@ -use crate::{Broadcast, LiveFeed}; +use crate::{Broadcast, Feed}; pub(super) trait ToRss { fn title(&self) -> &str; @@ -39,7 +39,7 @@ pub(super) trait ToRss { } } -impl ToRss for LiveFeed { +impl ToRss for Feed { fn title(&self) -> &str { &self.title } diff --git a/src/web.rs b/src/web.rs index 076b611..940a1a2 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,10 +1,10 @@ -use crate::{rss::ToRss, Feed, LiveFeed}; +use crate::{rss::ToRss, Feed}; use axum::{extract::State, http::HeaderMap, response::IntoResponse, routing::get, Router}; use reqwest::header; use std::sync::Arc; use tokio::{net::TcpListener, sync::RwLock}; -async fn stream_handler(State(state): State>>) -> impl IntoResponse { +async fn stream_handler(State(state): State>>) -> impl IntoResponse { state.write().await.fetch().await.unwrap(); let content = state.read().await.to_rss(); @@ -15,7 +15,7 @@ async fn stream_handler(State(state): State>>) -> } pub(super) async fn serve( - state: Arc>, + state: Arc>, listener: TcpListener, ) -> Result<(), Box> { let app = Router::new() @@ -26,39 +26,3 @@ pub(super) async fn serve( Ok(()) } - -//#[cfg(test)] -//mod tests { -// use crate::{rss::ToRss, TestFeed}; -// use axum::http::StatusCode; -// use std::sync::Arc; -// use tokio::sync::RwLock; -// -// #[tokio::test] -// async fn serve_serves_rss() { -// let feed = Arc::new(RwLock::new(TestFeed::default())); -// -// let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap(); -// let addr = listener.local_addr().unwrap(); -// -// tokio::spawn(super::serve(feed.clone(), listener)); -// -// let client = reqwest::Client::new(); -// let resp = client.get(format!("http://{}", addr)).send().await.unwrap(); -// -// assert_eq!(resp.status(), StatusCode::OK); -// assert_eq!( -// resp.headers() -// .get("content-type") -// .unwrap() -// .to_str() -// .unwrap(), -// "application/rss+xml" -// ); -// -// let body = resp.text().await.unwrap(); -// assert_eq!(body, feed.read().await.to_rss()); -// -// assert_eq!(feed.read().await.amount_fetch_calls, 1); -// } -//}