properly display quoted queries

This commit is contained in:
kageru 2023-01-31 11:47:59 +01:00
parent 3385401e73
commit 944b9412f4
2 changed files with 16 additions and 10 deletions

View File

@ -18,7 +18,7 @@ static CARDS: LazyLock<Vec<Card>> = LazyLock::new(|| {
.data
});
static CARDS_BY_ID: LazyLock<HashMap<usize, Card>> =
LazyLock::new(|| CARDS.iter().map(|c| (c.id, Card { text: c.text.replace("\r", "").replace('\n', "<br/>"), ..c.clone() })).collect());
LazyLock::new(|| CARDS.iter().map(|c| (c.id, Card { text: c.text.replace('\r', "").replace('\n', "<br/>"), ..c.clone() })).collect());
static SEARCH_CARDS: LazyLock<Vec<SearchCard>> = LazyLock::new(|| CARDS.iter().map(SearchCard::from).collect());
#[actix_web::main]
@ -109,14 +109,14 @@ fn render_searchbox(res: &mut String, query: &Option<String>) -> std::fmt::Resul
<input type="text" name="q" id="searchbox" placeholder="Enter query (e.g. l:5 c:synchro atk>2000)" value="{}"><input type="submit" id="submit" value="🔍">
</form>"#,
match &query {
Some(q) => q,
None => "",
Some(q) => q.replace('"', "&quot;"),
None => String::new(),
}
)
}
fn render_results(res: &mut String, query: &str) -> Result<(), Box<dyn std::error::Error>> {
let query = match parser::parse_filters(query) {
let (raw_filters, query) = match parser::parse_filters(query) {
Ok(q) => q,
Err(e) => {
write!(res, "Could not parse query: {e:?}")?;
@ -126,7 +126,7 @@ fn render_results(res: &mut String, query: &str) -> Result<(), Box<dyn std::erro
let now = Instant::now();
let matches: Vec<&Card> = SEARCH_CARDS
.iter()
.filter(|card| query.iter().all(|(_, q)| q(card)))
.filter(|card| query.iter().all(|q| q(card)))
.map(|c| CARDS_BY_ID.get(&c.id).unwrap())
.take(RESULT_LIMIT)
.collect();
@ -134,7 +134,7 @@ fn render_results(res: &mut String, query: &str) -> Result<(), Box<dyn std::erro
res,
"<span class=\"meta\">Showing {} results where {} (took {:?})</span>",
matches.len(),
query.iter().map(|(f, _)| f.to_string()).join(" and "),
raw_filters.iter().map(|f| f.to_string()).join(" and "),
now.elapsed()
)?;
if matches.is_empty() {

View File

@ -14,11 +14,11 @@ use nom::{
IResult,
};
pub fn parse_filters(input: &str) -> Result<Vec<(RawCardFilter, CardFilter)>, String> {
pub fn parse_filters(input: &str) -> Result<(Vec<RawCardFilter>, Vec<CardFilter>), String> {
parse_raw_filters(input).map_err(|e| format!("Error while parsing filters “{input}”: {e:?}")).and_then(|(rest, mut v)| {
if rest.is_empty() {
v.sort_unstable_by_key(|RawCardFilter(f, _, _)| *f as u8);
v.into_iter().map(|r| build_filter(r.clone()).map(|f| (r, f))).collect()
Ok((v.clone(), v.into_iter().map(|r| build_filter(r)).collect::<Result<Vec<_>, _>>()?))
} else {
Err(format!("Input was not fully parsed. Left over: “{rest}"))
}
@ -180,8 +180,14 @@ pub enum Value {
impl Display for Value {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self {
Self::String(s) => f.write_str(s),
Self::Numerical(n) => write!(f, "{}", n),
Self::String(s) => {
if s.contains(' ') {
write!(f, "\"{s}\"")
} else {
f.write_str(s)
}
}
Self::Numerical(n) => write!(f, "{n}"),
}
}
}