Last active
March 24, 2025 12:12
-
-
Save sheepla/7fdf89b0811372531723e6c698ac2f70 to your computer and use it in GitHub Desktop.
Fetch and parse RSS/Atom feed in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "rustyfeed" | |
version = "0.1.0" | |
edition = "2024" | |
[dependencies] | |
clap = { version = "4.5.32", features = ["derive"] } | |
reqwest = "0.12.15" | |
serde = { version = "1.0.219", features = ["derive"] } | |
syndication = "0.5.0" | |
thiserror = "2.0.12" | |
tokio = { version = "1.44.1", features = ["full"] } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use syndication::Feed; | |
#[derive(Debug, thiserror::Error)] | |
pub enum ClientError { | |
#[error("HTTP Error: {0}")] | |
Http(reqwest::Error), | |
#[error("HTTP Status Error: {0}")] | |
HttpStatus(reqwest::Error), | |
#[error("Failed to read the content: {0}")] | |
ReadText(reqwest::Error), | |
#[error("Parse Error: {0}")] | |
Parse(String), | |
} | |
pub struct Client(reqwest::Client); | |
impl Client { | |
pub fn new(client: reqwest::Client) -> Self { | |
Self(client) | |
} | |
pub async fn fetch_feed<U: reqwest::IntoUrl>( | |
&self, | |
url: U, | |
) -> Result<syndication::Feed, ClientError> { | |
let req = self.0.get(url); | |
let resp = req | |
.send() | |
.await | |
.map_err(ClientError::Http)? | |
.error_for_status() | |
.map_err(ClientError::HttpStatus)?; | |
let content = resp.text().await.map_err(ClientError::ReadText)?; | |
let feed = content | |
.parse::<syndication::Feed>() | |
.map_err(|err| ClientError::Parse(err.to_owned()))?; | |
Ok(feed) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
mod feed; | |
use syndication::Feed::{Atom, RSS}; | |
#[derive(Debug, thiserror::Error)] | |
enum AppError { | |
#[error("Client Error: {0}")] | |
Client(#[from] feed::ClientError), | |
} | |
#[tokio::main] | |
async fn main() -> Result<(), AppError> { | |
let feed = feed::Client::new(reqwest::Client::new()) | |
.fetch_feed("https://zenn.dev/topics/typescript/feed") | |
.await?; | |
match feed { | |
RSS(rss) => { | |
dbg!(rss); | |
} | |
Atom(atom) => { | |
dbg!(atom); | |
} | |
} | |
Ok(()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output
Output