diff --git a/Cargo.lock b/Cargo.lock index 24a252b..6ac6cd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,12 +57,12 @@ dependencies = [ [[package]] name = "actix-macros" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 1.0.109", + "syn 2.0.27", ] [[package]] @@ -359,9 +359,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "encoding_rs" @@ -741,9 +741,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -839,9 +839,9 @@ checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" @@ -851,29 +851,29 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.171" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e27d1e4fd7659406c492fd6cfaf2066ba8773de45ca75e855590f856dc34a9" +checksum = "63ba2516aa6bf82e0b19ca8b50019d52df58455d3cf9bdaf6315225fdd0c560a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.171" +version = "1.0.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389894603bd18c46fa56231694f8d827779c0951a667087194cf9de94ed24682" +checksum = "401797fe7833d72109fedec6bfcbe67c0eed9b99772f26eb8afd261f0abc6fd3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.26", + "syn 2.0.27", ] [[package]] name = "serde_json" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -950,9 +950,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.26" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index fd2e227..c9c9f47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } -nom = "7.1.3" -actix-web = { version = "4.3.0", default_features = false, features = ["macros"] } -itertools = "0.11.0" -time = { version = "0.3.17", features = ["serde", "serde-human-readable"] } -regex = { version = "1.7.1", default_features = false, features = ["std"] } +nom = "7.1" +actix-web = { version = "4.3", default_features = false, features = ["macros"] } +itertools = "0.11" +time = { version = "0.3", features = ["serde", "serde-human-readable"] } +regex = { version = "1.7", default_features = false, features = ["std"] } [dev-dependencies] test-case = "3.1" diff --git a/src/data.rs b/src/data.rs index b7571f8..b986853 100644 --- a/src/data.rs +++ b/src/data.rs @@ -66,7 +66,7 @@ pub struct Set { impl Card { pub fn extended_info(&self) -> Result { let mut s = String::with_capacity(1000); - write!(s, "

RulingsYugipedia

", &self.name, &self.name.replace(' ', "_"))?; + write!(s, "

RulingsYugipedia

", &self.name, &self.id)?; s.push_str("

Printings:

"); for printing in &self.card_sets { write!(s, "{}: {} ({})", printing.set_name, printing.set_code, printing.set_rarity)?; diff --git a/src/main.rs b/src/main.rs index edcfc0d..dec237a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -82,6 +82,12 @@ struct Query { q: String, } +#[derive(Debug)] +enum TargetPage { + Data(PageData), + Redirect(String), +} + #[derive(Debug)] struct PageData { description: String, @@ -118,7 +124,7 @@ async fn search(q: Option, web::Form>>) -> AnyRe let mut res = String::with_capacity(10_000); let data = match q { Some(q) => compute_results(q)?, - None => PageData { + None => TargetPage::Data(PageData { title: "YGO card search".to_owned(), description: "Enter a query above to search".to_owned(), query: None, @@ -126,10 +132,15 @@ async fn search(q: Option, web::Form>>) -> AnyRe

Enter a query above to search or read the query syntax for more information.

\

The source code is available on Gitea.

" .to_owned(), - }, + }), }; - add_data(&mut res, &data)?; - Ok(HttpResponse::Ok().insert_header(header::ContentType::html()).body(res)) + match data { + TargetPage::Data(data) => { + add_data(&mut res, &data)?; + Ok(HttpResponse::Ok().insert_header(header::ContentType::html()).body(res)) + } + TargetPage::Redirect(target) => Ok(HttpResponse::Found().insert_header((header::LOCATION, target)).finish()), + } } #[get("/card/{id}")] @@ -187,18 +198,18 @@ fn add_searchbox(res: &mut String, query: &Option) -> std::fmt::Result { ) } -fn compute_results(raw_query: String) -> AnyResult { +fn compute_results(raw_query: String) -> AnyResult { let mut body = String::with_capacity(10_000); let (raw_filters, query) = match parser::parse_filters(raw_query.trim()) { Ok(q) => q, Err(e) => { let s = format!("Could not parse query: {e:?}"); - return Ok(PageData { + return Ok(TargetPage::Data(PageData { description: s.clone(), query: Some(raw_query), body: s, title: "YGO Card Database".to_owned(), - }); + })); } }; let now = Instant::now(); @@ -210,32 +221,35 @@ fn compute_results(raw_query: String) -> AnyResult { .collect(); let readable_query = format!("Showing {} results where {}", matches.len(), raw_filters.iter().map(|f| f.to_string()).join(" and "),); write!(body, "{readable_query} (took {:?})", now.elapsed())?; - if matches.is_empty() { - return Ok(PageData { + match matches[..] { + [] => Ok(TargetPage::Data(PageData { description: readable_query, query: Some(raw_query), body, title: "No results - YGO Card Database".to_owned(), - }); + })), + [card] => Ok(TargetPage::Redirect(format!("/card/{}", card.id))), + ref cards => { + body.push_str("
"); + for card in cards { + write!( + body, + r#"Card Image: {}{card}"#, + card.id, + card.name, + IMG_HOST.as_str(), + card.id + )?; + } + body.push_str("
"); + Ok(TargetPage::Data(PageData { + description: readable_query, + query: Some(raw_query), + body, + title: format!("{} results - YGO Card Database", cards.len()), + })) + } } - body.push_str("
"); - for card in &matches { - write!( - body, - r#"Card Image: {}{card}"#, - card.id, - card.name, - IMG_HOST.as_str(), - card.id - )?; - } - body.push_str("
"); - Ok(PageData { - description: readable_query, - query: Some(raw_query), - body, - title: format!("{} results - YGO Card Database", matches.len()), - }) } fn add_data(res: &mut String, pd: &PageData) -> AnyResult<()> {