From 7fe2af29e04a81f7c0348928a50425d4daa2095b Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 5 Sep 2018 09:39:21 -0400 Subject: [PATCH] fix: show an error for invalid pages --- src/error.rs | 2 ++ src/logic/search.rs | 33 ++++++++++++++++++++------------ src/logic/search/character.rs | 12 +++++------- src/logic/search/free_company.rs | 12 +++++------- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/error.rs b/src/error.rs index c87e29f..c3fdbb2 100644 --- a/src/error.rs +++ b/src/error.rs @@ -8,6 +8,8 @@ pub enum Error { MissingElement(String), #[fail(display = "the content scraped from the Lodestone was invalid: {}", _0)] InvalidContent(String), + #[fail(display = "invalid page (1 through {} available)", _0)] + InvalidPage(u64), #[fail(display = "invalid number: {}", _0)] InvalidNumber(std::num::ParseIntError), diff --git a/src/logic/search.rs b/src/logic/search.rs index 88799a4..066ac1a 100644 --- a/src/logic/search.rs +++ b/src/logic/search.rs @@ -21,6 +21,8 @@ selectors!( ); crate fn parse_pagination(html: &Html) -> Result { + const LODESTONE_PER_PAGE: f32 = 50.0; + let total_str = crate::logic::plain_parse(&html, &*PAGINATION_TOTAL)?; let total_results: u64 = total_str .split(' ') @@ -29,20 +31,27 @@ crate fn parse_pagination(html: &Html) -> Result { .parse() .map_err(Error::InvalidNumber)?; - let pages_str = crate::logic::plain_parse(&html, &*PAGINATION_PAGES)?; - let mut pages_split = pages_str.split(' '); + let (total_pages, current_page) = if parse_no_results(html) { + let total_pages = (total_results as f32 / LODESTONE_PER_PAGE).ceil() as u64; + let current_page = 0; + (total_pages, current_page) + } else { + let pages_str = crate::logic::plain_parse(&html, &*PAGINATION_PAGES)?; + let mut pages_split = pages_str.split(' '); - let current_page: u64 = pages_split - .nth(1) - .ok_or_else(|| Error::invalid_content("4 items in pages string", None))? - .parse() - .map_err(Error::InvalidNumber)?; + let current_page: u64 = pages_split + .nth(1) + .ok_or_else(|| Error::invalid_content("4 items in pages string", None))? + .parse() + .map_err(Error::InvalidNumber)?; - let total_pages: u64 = pages_split - .nth(1) - .ok_or_else(|| Error::invalid_content("4 items in pages string", None))? - .parse() - .map_err(Error::InvalidNumber)?; + let total_pages: u64 = pages_split + .nth(1) + .ok_or_else(|| Error::invalid_content("4 items in pages string", None))? + .parse() + .map_err(Error::InvalidNumber)?; + (total_pages, current_page) + }; Ok(Pagination { current_page, diff --git a/src/logic/search/character.rs b/src/logic/search/character.rs index 222ee6d..7c99763 100644 --- a/src/logic/search/character.rs +++ b/src/logic/search/character.rs @@ -32,15 +32,13 @@ selectors!( pub fn parse(html: &str) -> Result> { let html = Html::parse_document(html); - if crate::logic::search::parse_no_results(&html) { - return Ok(Paginated { - pagination: Default::default(), - results: Default::default(), - }); - } - let pagination = crate::logic::search::parse_pagination(&html)?; + // has results but requested an invalid page + if pagination.total_results != 0 && pagination.current_page == 0 { + return Err(Error::InvalidPage(pagination.total_pages)); + } + let results: Vec = html .select(&*ITEM_ENTRY) .map(|x| parse_single(x)) diff --git a/src/logic/search/free_company.rs b/src/logic/search/free_company.rs index 3c49049..3dc5dc7 100644 --- a/src/logic/search/free_company.rs +++ b/src/logic/search/free_company.rs @@ -38,15 +38,13 @@ selectors!( pub fn parse(s: &str) -> Result> { let html = Html::parse_document(s); - if crate::logic::search::parse_no_results(&html) { - return Ok(Paginated { - pagination: Default::default(), - results: Default::default(), - }); - } - let pagination = crate::logic::search::parse_pagination(&html)?; + // has results but requested an invalid page + if pagination.total_results != 0 && pagination.current_page == 0 { + return Err(Error::InvalidPage(pagination.total_pages)); + } + let results: Vec = html .select(&*ITEM_ENTRY) .map(|x| parse_single(x))