Parse querystrings in non-strict mode.

This commit is contained in:
Sebastian Jeltsch
2025-05-17 09:55:43 +02:00
parent 149c989f74
commit f2bdc85dc4
3 changed files with 19 additions and 4 deletions

1
Cargo.lock generated
View File

@@ -6999,7 +6999,6 @@ name = "trailbase-qs"
version = "0.1.0"
dependencies = [
"base64 0.22.1",
"itertools 0.14.0",
"serde",
"serde-value",
"serde_qs",

View File

@@ -10,7 +10,6 @@ readme = "../README.md"
[dependencies]
base64 = { version = "0.22.1", default-features = false, features = ["alloc"] }
itertools = "0.14.0"
serde = "1.0.219"
serde-value = "0.7.0"
serde_qs = "0.15.0"

View File

@@ -4,6 +4,8 @@ use serde::Deserialize;
use crate::filter::ValueOrComposite;
use crate::util::deserialize_bool;
pub type Error = serde_qs::Error;
/// TrailBase supports cursors in a few formats:
/// * Integers
/// * Text-encoded UUIDs ([u8; 16])
@@ -182,8 +184,9 @@ pub struct Query {
}
impl Query {
pub fn parse(query: &str) -> Result<Query, serde_qs::Error> {
let qs = serde_qs::Config::new(5, true);
pub fn parse(query: &str) -> Result<Query, Error> {
// NOTE: We rely on non-strict mode to parse `filter[col0]=a&b%filter[col1]=c`.
let qs = serde_qs::Config::new(5, false);
return qs.deserialize_str::<Query>(query);
}
}
@@ -201,6 +204,20 @@ mod tests {
#[test]
fn test_query_basic_parsing() {
assert_eq!(Query::parse("").unwrap(), Query::default());
assert_eq!(Query::parse("unknown=foo").unwrap(), Query::default());
assert_eq!(
Query::parse("filter%5Btext_not_null%5D=rust+client+test+0%3A+%3D%3F%261747466199")
.unwrap()
.filter
.unwrap(),
ValueOrComposite::Value(ColumnOpValue {
column: "text_not_null".to_string(),
op: CompareOp::Equal,
value: Value::String("rust client test 0: =?&1747466199".to_string()),
})
);
assert_eq!(
Query::parse("limit=5&offset=5&count=true").unwrap(),
Query {