HTTPQL = { SOI ~ Query? ~ EOI }
// Tokens
// Delimiters
LeftParen = _{ "(" }
RightParen = _{ ")" }
Dot = _{ "." }
Colon = _{ ":" }
// Logical operators
And = { "AND" | "and" }
Or = { "OR" | "or" }
// Namespaces
RequestNamespace = _{ "req" }
ResponseNamespace = _{ "resp" }
PresetNamespace = _{ "preset" }
// Request field names
RequestStringFieldName = { "ext" | "host" | "method" | "path" | "query" | "raw" }
RequestIntFieldName = { "port" }
// Response field names
ResponseStringFieldName = { "raw" }
ResponseIntFieldName = { "code" }
// Operators for string and integer types
StringOperator = { "cont" | "ncont" | "eq" | "ne" | "like" | "nlike" | "regex" | "nregex" }
IntOperator = { "eq" | "gte" | "gt" | "lte" | "lt" | "ne" }
// Value types
SymbolValue = @{ ('a'..'z' | '0'..'9' | "-" | "_")+ }
IntValue = @{ ASCII_DIGIT+ }
StringValue = ${ "\"" ~ StringContent ~ "\"" }
StringContent = @{ StringChar* }
StringChar = {
"\\" ~ ANY
| !"\"" ~ ANY
}
// Define non-token rules for constructing expressions
WHITESPACE = _{ " " | "\t" | "\n" | "\r" }
// Expression
IntExpression = ${ IntOperator ~ Colon ~ IntValue }
StringExpression = ${ StringOperator ~ Colon ~ StringValue }
PresetNameExpression = { StringValue }
PresetAliasExpression = { SymbolValue }
// Clause
StringClause = { StringValue }
RequestClause = ${
RequestNamespace ~ Dot ~ RequestIntFieldName ~ Dot ~ IntExpression
| RequestNamespace ~ Dot ~ RequestStringFieldName ~ Dot ~ StringExpression
}
ResponseClause = ${
ResponseNamespace ~ Dot ~ ResponseIntFieldName ~ Dot ~ IntExpression
| ResponseNamespace ~ Dot ~ ResponseStringFieldName ~ Dot ~ StringExpression
}
PresetClause = ${
PresetNamespace ~ Colon ~ (PresetNameExpression | PresetAliasExpression)
}
// Query
Clause = _{ StringClause | RequestClause | ResponseClause | PresetClause | LeftParen ~ Query ~ RightParen }
LogicalOperator = _{ And | Or }
Query = { Clause ~ (LogicalOperator ~ Clause)* }