use crate::{ LodestoneScraper, error::*, models::ClassJobRole, util::{Either, AsLodestone}, }; use ffxiv_types::{World, Race, Clan, DataCenter}; use lodestone_parser::models::{ GrandCompany, character::Job, search::{ Paginated, character::CharacterSearchItem, }, }; use url::Url; #[derive(Debug)] pub struct CharacterSearchBuilder<'a> { scraper: &'a LodestoneScraper, // q name: Option<&'a str>, // worldname world: Option>, // classjob job: Option>, // race_tribe race: Option>, // gcid grand_company: Option>, } impl<'a> CharacterSearchBuilder<'a> { pub fn new(scraper: &'a LodestoneScraper) -> Self { CharacterSearchBuilder { scraper, name: None, world: None, job: None, race: None, grand_company: None, } } pub fn name(&mut self, n: &'a str) -> &mut Self { self.name = Some(n); self } pub fn world(&mut self, w: World) -> &mut Self { self.world = Some(Either::Left(w)); self } pub fn data_center(&mut self, dc: DataCenter) -> &mut Self { self.world = Some(Either::Right(dc)); self } pub fn job(&mut self, j: Job) -> &mut Self { self.job = Some(Either::Left(j)); self } pub fn role(&mut self, r: ClassJobRole) -> &mut Self { self.job = Some(Either::Right(r)); self } pub fn race(&mut self, r: Race) -> &mut Self { self.race = Some(Either::Left(r)); self } pub fn clan(&mut self, c: Clan) -> &mut Self { self.race = Some(Either::Right(c)); self } pub fn grand_company(&mut self, gc: GrandCompany) -> &mut Self { self.grand_company.get_or_insert_with(Default::default).push(gc); self } pub fn send(&self) -> Result> { let text = self.scraper.client .get(self.as_url()) .send() .map_err(Error::Net)? .text() .map_err(Error::Net)?; lodestone_parser::parse_character_search(&text).map_err(Error::Parse) } pub fn as_url(&self) -> Url { let mut url = crate::LODESTONE_URL.join("character/").unwrap(); { let mut pairs = url.query_pairs_mut(); if let Some(ref name) = self.name { pairs.append_pair("q", name); } match self.world { Some(Either::Left(w)) => { pairs.append_pair("worldname", w.as_str()); }, Some(Either::Right(dc)) => { pairs.append_pair("worldname", &dc.as_lodestone()); }, _ => {}, } match self.job { Some(Either::Left(j)) => { pairs.append_pair("classjob", &j.as_lodestone().to_string()); }, Some(Either::Right(cjr)) => { pairs.append_pair("classjob", cjr.as_lodestone()); }, _ => {}, } match self.race { Some(Either::Left(r)) => { pairs.append_pair("race_tribe", &format!("race_{}", r.as_lodestone())); }, Some(Either::Right(c)) => { pairs.append_pair("race_tribe", &format!("tribe_{}", c.as_lodestone())); }, _ => {}, } if let Some(ref gcs) = self.grand_company { for gc in gcs { pairs.append_pair("gcid", &gc.as_lodestone().to_string()); } } } url } }