use crate::wiki::article::{compiled_article::Article, parser::Parser};
use anyhow::Result;
use reqwest::blocking::{get, Response};
pub struct ArticleBuilder {
page_id: i32,
target: Option<String>,
base_url: String,
}
impl ArticleBuilder {
pub fn new(page_id: i32, target: Option<String>, base_url: &str) -> ArticleBuilder {
debug!("creating a new instance of ArticleBuilder");
ArticleBuilder {
page_id,
target,
base_url: base_url.to_string(),
}
}
pub fn build(&self, parser: &mut impl Parser) -> Result<Article> {
info!("beginning the build process");
let url = self.build_url();
info!("making the request to '{}'", url);
let response = self.make_request(&url)?;
info!("parsing the article");
self.parse_response(parser, response)
}
fn build_url(&self) -> String {
match self.target {
Some(ref target) => format!("{}{}", self.base_url, target),
None => format!("{}?curid={}", self.base_url, self.page_id),
}
}
fn make_request(&self, url: &str) -> Result<Response> {
Ok(get(url)?.error_for_status()?)
}
fn parse_response(&self, parser: &mut impl Parser, response: Response) -> Result<Article> {
parser.parse(response)
}
}
#[cfg(test)]
mod tests {
const BASE_URL: &str = "https://en.wikipedia.org/";
#[test]
fn correct_url() {
use super::ArticleBuilder;
assert_eq!(
ArticleBuilder::new(1234, None, BASE_URL).build_url(),
format!("{}?curid=1234", BASE_URL)
);
assert_eq!(
ArticleBuilder::new(1234, Some("/wiki/Software".to_string()), BASE_URL).build_url(),
format!("{}/wiki/Software", BASE_URL)
);
}
}