Skip to content

feat: configurable operators/directions, dotted fields, and docs restructure#11

Merged
christiangda merged 2 commits into
mainfrom
feat/configurable-allowed-operators
Jul 11, 2026
Merged

feat: configurable operators/directions, dotted fields, and docs restructure#11
christiangda merged 2 commits into
mainfrom
feat/configurable-allowed-operators

Conversation

@christiangda

Copy link
Copy Markdown
Contributor

Summary

Three related additions, all backward compatible, plus a documentation restructure.

1. Configurable filter operators (opt-in)

Callers can restrict which operators a FilterParser accepts; the default (no option) still allows everything.

p := qfv.NewFilterParser(fields,
    qfv.WithAllowedOperatorGroups(qfv.GroupComparison, qfv.GroupLogical),
    qfv.WithAllowedOperators(qfv.OpIn),
)
p.Parse("age >= 18 AND status IN ('active')") // ok
p.Parse("name LIKE '%x%'")                     // error: operator "LIKE" is not allowed
  • New Operator enum (per-verb) + OperatorGroup presets (GroupComparison, GroupPattern, GroupLogical, …), both additive.
  • Helpers AllOperators() and OperatorGroup.Operators().
  • Disallowed verbs are reported through the existing single-pass error aggregation.
  • Negation semantics: negated predicates (NOT IN, NOT LIKE, IS NOT DISTINCT FROM, …) are governed by their base operator; OpNot governs only the standalone leading NOT (…).

2. Configurable sort directions (opt-in)

p := qfv.NewSortParser(fields, qfv.WithAllowedDirections(qfv.SortAsc))
p.Parse("name DESC") // error: sort direction "DESC" is not allowed

3. Nested dot-notation field names

FilterParser now accepts dotted identifiers via scanner.IsIdentRune:

p := qfv.NewFilterParser([]string{"user.profile.age", "user.name"})
p.Parse("user.profile.age >= 18 AND user.name = 'John'")

A dot is valid only inside an identifier, so numeric literals (3.14) are unaffected. FieldsParser/SortParser already matched dotted names (plain string comparison); this brings FilterParser in line. Unknown dotted fields are rejected by the allow-list as usual.

Constructors stay source-compatibleNewFilterParser(fields) / NewSortParser(fields) gained variadic options, so existing calls compile unchanged.

Documentation restructure

  • Detailed guides moved into docs/: getting-started, filtering, configuration, error-handling, migration.
  • Top-level README.md slimmed to essentials — install/update, a quick-start, a short feature list, and links into docs/.
  • New godoc Example* functions for the new options and dotted fields.

Tests

  • Operator gating (groups + individual, additive, negation), group-coverage invariant, sort-direction gating, dotted-identifier parsing, numeric-literal regression.
  • go vet, gofmt, go test -race ./... all pass; coverage 96.6%.

All of this targets the same unreleased v0.1.0 line; the migration guide (docs/migration.md) documents it as additive items 7–8.

…ructure

Add caller-side control over which filter operators and sort directions are
accepted, support nested dot-notation field names, and reorganize the
documentation into a docs/ folder.

Configurable operators (opt-in; default allows everything):
- New Operator enum (per-verb) and OperatorGroup presets, with AllOperators()
  and OperatorGroup.Operators() helpers.
- NewFilterParser now takes variadic FilterOption; WithAllowedOperators and
  WithAllowedOperatorGroups (additive) restrict the grammar. Disallowed verbs
  produce `operator "X" is not allowed`, collected in the same single-pass
  aggregation. Negated predicates (NOT IN, NOT LIKE, ...) are governed by their
  base operator; OpNot governs only the standalone leading NOT.

Configurable sort directions:
- NewSortParser takes variadic SortOption; WithAllowedDirections(SortAsc/SortDesc)
  restricts directions (default allows both).

Nested dot-notation fields:
- Lexer sets scanner.IsIdentRune so "q.v.last_name" scans as a single
  identifier; a dot is valid only in interior positions, so numeric literals
  like 3.14 are unaffected. FieldsParser/SortParser already matched dotted names
  via string comparison; this brings FilterParser in line. Unknown dotted fields
  are rejected by the allow-list as usual.

Constructor signatures are source-compatible (existing calls compile unchanged).

Docs:
- Move the detailed guides into docs/ (getting-started, filtering, configuration,
  error-handling, migration) with an index at docs/README.md.
- Slim the top-level README to essentials: install/update, a quick-start example,
  a short feature list, and links into docs/.
- Add godoc examples for WithAllowedOperatorGroups, WithAllowedDirections, and
  dotted fields.

Tests:
- Add operator-gating, group-coverage, sort-direction, and dotted-identifier
  tests. go vet, gofmt, and go test -race all pass; coverage 96.6%.
@christiangda christiangda self-assigned this Jul 11, 2026
@christiangda christiangda merged commit 5824211 into main Jul 11, 2026
1 check passed
@christiangda christiangda deleted the feat/configurable-allowed-operators branch July 11, 2026 12:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant