Trim comments across Rust and webapp source to direct one-liners (ticket 030)

Pass over src/*.rs, webapp/src/**, and the in-app "?" docs prose:
condensed multi-paragraph doc comments to single lines that state the
non-obvious why, deleted comments that only restated adjacent code, and
tightened the Docs.tsx help-panel wording. No logic, structure, or code
formatting changed — verified via cargo test (143 passed) and
tsc -b && vite build.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-05 17:02:33 +01:00
co-authored by Claude Sonnet 5
parent 3cef6dc8ae
commit 00c21c8032
32 changed files with 347 additions and 1550 deletions
+10 -41
View File
@@ -1,26 +1,5 @@
//! FilterBar query language: grammar, AST and parser.
//!
//! This module is intentionally standalone and has no dependency on the
//! engine/index types (`data_value`, `index_key`, `engine`, ...). It only
//! knows how to turn a filter string into an [`FilterExpr`] AST. Evaluating
//! that AST against real log data, and resolving [`FilterValue::Raw`] tokens
//! into concrete datetimes, is left to later integration tickets.
//!
//! Grammar (see `src/filter_parser.pest`):
//!
//! - `regex("...")` — raw-text regex search over log lines.
//! - `metric_name[param] <op> value` — metric comparisons, with `<op>` one
//! of `<`, `>`, `<=`, `>=`, `==`, `!=`.
//! - `sequence <op> value` and `timestamp <op> value` — reserved metric
//! names usable the same way, without a `[param]`.
//! - `and` / `or` boolean combinators, with `and` binding tighter than `or`.
//! - Parenthesized sub-expressions.
//!
//! `engine.rs` (ticket 007) is what actually calls into this module: it
//! compiles the returned [`FilterExpr`] against the index (resolving
//! [`FilterValue::Raw`] tokens via `filter_datetime` and metric comparisons
//! via bucket data) and evaluates it per log line while answering
//! `EngineQuery::Logs`/`Timeline`.
//! FilterBar query language: grammar (see `src/filter_parser.pest`), AST and parser.
//! Evaluating the AST against real log data is left to `engine.rs`.
#![allow(dead_code)]
use pest::Parser;
@@ -48,9 +27,8 @@ pub enum FilterExpr {
Or(Box<FilterExpr>, Box<FilterExpr>),
}
/// Comparison operators supported by metric comparisons. Also reused by
/// `crate::alerts::AlertCondition::Threshold`/`Ratio` for their own
/// threshold/ratio comparisons (hence `Serialize`/`Deserialize`).
/// Comparison operators for metric comparisons; also reused by `crate::alerts::AlertCondition`
/// for threshold/ratio comparisons (hence `Serialize`/`Deserialize`).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum CompareOp {
@@ -62,10 +40,8 @@ pub enum CompareOp {
Ne,
}
/// The right-hand side of a comparison. Values that parse as a number
/// become [`FilterValue::Number`]; everything else (e.g. datetime-like
/// tokens such as `12:00`) is kept as an opaque [`FilterValue::Raw`] string
/// to be resolved by a later ticket.
/// The right-hand side of a comparison: values that parse as a number become
/// [`FilterValue::Number`], everything else is kept as an opaque [`FilterValue::Raw`] string.
#[derive(Debug, Clone, PartialEq)]
pub enum FilterValue {
Number(f64),
@@ -96,9 +72,7 @@ impl std::error::Error for FilterParseError {}
impl From<pest::error::Error<Rule>> for FilterParseError {
fn from(err: pest::error::Error<Rule>) -> Self {
// pest's own Display already renders a located, human-readable
// message (line/column + a pointer into the offending input), so we
// use it as the basis and add a short prefix for context.
// pest's Display already renders a located message, so use it and add a short prefix.
FilterParseError::new(format!("failed to parse filter expression: {err}"))
}
}
@@ -121,9 +95,7 @@ pub fn parse(input: &str) -> Result<FilterExpr, FilterParseError> {
fn build_or_expr(pair: Pair<Rule>) -> Result<FilterExpr, FilterParseError> {
debug_assert_eq!(pair.as_rule(), Rule::or_expr);
// `or_kw` is atomic (see the grammar file) so it is *not* silent: it
// shows up as a sibling pair between the `and_expr` operands. Skip it
// rather than assuming a fixed alternating structure.
// `or_kw` is atomic so it's not silent, showing up as a sibling pair between `and_expr` operands — skip it rather than assuming a fixed alternating structure.
let mut and_exprs = pair
.into_inner()
.filter(|p| p.as_rule() != Rule::or_kw);
@@ -140,7 +112,7 @@ fn build_or_expr(pair: Pair<Rule>) -> Result<FilterExpr, FilterParseError> {
fn build_and_expr(pair: Pair<Rule>) -> Result<FilterExpr, FilterParseError> {
debug_assert_eq!(pair.as_rule(), Rule::and_expr);
// Same reasoning as above for `and_kw`.
// Same reasoning as `build_or_expr` for `and_kw`.
let mut terms = pair
.into_inner()
.filter(|p| p.as_rule() != Rule::and_kw);
@@ -236,8 +208,7 @@ fn parse_value(s: &str) -> FilterValue {
}
}
/// Unescape a regex string literal's inner contents (`\"` -> `"`, `\\` -> `\`,
/// any other `\x` -> `x`).
/// Unescape a regex string literal's inner contents (`\"` -> `"`, `\\` -> `\`, `\x` -> `x`).
fn unescape(s: &str) -> String {
let mut out = String::with_capacity(s.len());
let mut chars = s.chars();
@@ -368,8 +339,6 @@ mod tests {
let result = parse("regex(\"unterminated and sequence<");
assert!(result.is_err());
let err = result.unwrap_err();
// Ensure the error message is human-readable and carries location
// info (pest errors always mention line/column context).
let msg = err.to_string();
assert!(!msg.is_empty());
}