move feed::get from FetchEnv into a pure function

This commit is contained in:
Paul Campbell 2023-07-29 19:55:37 +01:00
parent 73b9ad960b
commit f211823884
9 changed files with 26 additions and 16 deletions

1
Cargo.lock generated
View file

@ -1014,6 +1014,7 @@ name = "podal"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"atom_syndication", "atom_syndication",
"bytes",
"clap", "clap",
"reqwest", "reqwest",
"scraper", "scraper",

View file

@ -10,6 +10,7 @@ atom_syndication = "0.12.1"
reqwest = { version = "0.11.18", features = ["json", "blocking"] } reqwest = { version = "0.11.18", features = ["json", "blocking"] }
scraper = "0.17.1" scraper = "0.17.1"
clap = "4.3.19" clap = "4.3.19"
bytes = "1.4.0"
[dev-dependencies] [dev-dependencies]
tempfile = "*" tempfile = "*"

View file

@ -4,6 +4,13 @@ use std::{fmt::Display, str::Utf8Error, string::FromUtf8Error};
pub struct Error { pub struct Error {
details: String, details: String,
} }
impl Error {
pub fn message(details: &str) -> Self {
Self {
details: details.to_string(),
}
}
}
impl Display for Error { impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.details.to_string().as_str()) f.write_str(self.details.to_string().as_str())

View file

@ -23,12 +23,15 @@ pub fn find(site: &str, channel_name: &str, e: &NetworkEnv) -> Result<String> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::errors::Error;
use super::*; use super::*;
#[test] #[test]
fn finds_rss_url() -> Result<()> { fn finds_rss_url() -> Result<()> {
//given //given
let network_env = NetworkEnv { let network_env = NetworkEnv {
fetch_as_text: dummy_fetch_as_text, fetch_as_text: dummy_fetch_as_text,
fetch_as_bytes: dummy_fetch_as_bytes,
}; };
//when //when
let result = find("site", "@channel", &network_env)?; let result = find("site", "@channel", &network_env)?;
@ -42,6 +45,7 @@ mod tests {
//given //given
let network_env = NetworkEnv { let network_env = NetworkEnv {
fetch_as_text: dummy_fetch_as_text, fetch_as_text: dummy_fetch_as_text,
fetch_as_bytes: dummy_fetch_as_bytes,
}; };
//when //when
let result = find("site", "invalid-channel-name", &network_env); let result = find("site", "invalid-channel-name", &network_env);
@ -58,4 +62,7 @@ mod tests {
"# "#
.to_string()) .to_string())
} }
fn dummy_fetch_as_bytes(_url: &str) -> Result<bytes::Bytes> {
Err(Error::message("Not implemented"))
}
} }

View file

@ -1,9 +0,0 @@
use crate::prelude::*;
use atom_syndication::Feed;
pub fn reqwest_blocking_get(url: &str) -> Result<Feed> {
let content = reqwest::blocking::get(url)?.bytes()?;
let channel = Feed::read_from(&content[..])?;
Ok(channel)
}

View file

@ -1,18 +1,20 @@
use crate::prelude::*; use crate::prelude::*;
use crate::network::NetworkEnv; use crate::network::NetworkEnv;
use atom_syndication::Feed;
mod find; mod find;
mod get;
use atom_syndication::Feed;
pub use find::find; pub use find::find;
pub use get::reqwest_blocking_get;
pub struct FeedEnv { pub struct FeedEnv {
pub find: FeedFind, pub find: FeedFind,
pub get: FeedGet,
} }
pub type FeedFind = fn(&str, &str, &NetworkEnv) -> Result<String>; pub type FeedFind = fn(&str, &str, &NetworkEnv) -> Result<String>;
pub type FeedGet = fn(&str) -> Result<Feed>;
pub fn get(url: &str, e: &NetworkEnv) -> Result<Feed> {
let content = (e.fetch_as_bytes)(url)?;
let channel = Feed::read_from(&content[..])?;
Ok(channel)
}

View file

@ -28,7 +28,7 @@ pub fn run(subscriptions: &str, history: &str, site: &str, e: Env) -> Result<()>
for channel_name in file::read::lines_from(subscriptions, &e.file)? { for channel_name in file::read::lines_from(subscriptions, &e.file)? {
println!("Channel: {}", channel_name); println!("Channel: {}", channel_name);
let feed_url = (e.feed.find)(site, &channel_name, &e.network)?; let feed_url = (e.feed.find)(site, &channel_name, &e.network)?;
for entry in (e.feed.get)(&feed_url)?.entries() { for entry in feed::get(&feed_url, &e.network)?.entries() {
if let Some(link) = entry.links().get(0).cloned() { if let Some(link) = entry.links().get(0).cloned() {
if !(e.history.find)(&link, history, &e.file)? { if !(e.history.find)(&link, history, &e.file)? {
println!("Downloading {}: {}", &channel_name, entry.title().as_str()); println!("Downloading {}: {}", &channel_name, entry.title().as_str());

View file

@ -17,7 +17,6 @@ fn main() -> Result<()> {
podal::Env { podal::Env {
feed: FeedEnv { feed: FeedEnv {
find: podal::feed::find, find: podal::feed::find,
get: podal::feed::reqwest_blocking_get,
}, },
history: HistoryEnv { history: HistoryEnv {

View file

@ -2,11 +2,13 @@ use crate::prelude::*;
pub struct NetworkEnv { pub struct NetworkEnv {
pub fetch_as_text: fn(url: &str) -> Result<String>, pub fetch_as_text: fn(url: &str) -> Result<String>,
pub fetch_as_bytes: fn(url: &str) -> Result<bytes::Bytes>,
} }
impl Default for NetworkEnv { impl Default for NetworkEnv {
fn default() -> Self { fn default() -> Self {
Self { Self {
fetch_as_text: |url| Ok(reqwest::blocking::get(url)?.text()?), fetch_as_text: |url| Ok(reqwest::blocking::get(url)?.text()?),
fetch_as_bytes: |url| Ok(reqwest::blocking::get(url)?.bytes()?),
} }
} }
} }