https://github.com/linka-cloud/protofilters
Protobuf message filtering in Go
https://github.com/linka-cloud/protofilters
filter filtering go golang protobuf reflection
Last synced: about 1 month ago
JSON representation
Protobuf message filtering in Go
- Host: GitHub
- URL: https://github.com/linka-cloud/protofilters
- Owner: linka-cloud
- License: apache-2.0
- Created: 2021-06-04T12:23:40.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2025-02-09T15:37:06.000Z (3 months ago)
- Last Synced: 2025-03-27T18:21:22.826Z (about 2 months ago)
- Topics: filter, filtering, go, golang, protobuf, reflection
- Language: Go
- Homepage:
- Size: 188 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Proto Filters
[](https://pkg.go.dev/go.linka.cloud/protofilters)
Proto filters provides a simple way to filter protobuf message based on field filter conditions.
**Project status: *alpha***
Not all planned features are completed.
The API, spec, status and other user facing objects are subject to change.
We do not support backward-compatibility for the alpha releases.## Overview
The main filter construct is the *Expression*:
```protobuf
// Expression represent a complete condition
// fields are evaluated as the following expression:
// condition && and_exprs || or_exprs
message Expression {
FieldFilter condition = 1;
repeated Expression and_exprs = 2;
repeated Expression or_exprs = 3;
}
```The two message filtering types available follow the same pattern as `google.protobuf.FieldMask`:
```proto
message FieldsFilter {
// filters is a map of
map filters = 1;
}
message FieldFilter {
string field = 1;
Filter filter = 2;
}
```The message's Field is selected by its path and compared against the provided typed filter:
```proto
message Filter {
oneof match {
StringFilter string = 1;
NumberFilter number = 2;
BoolFilter bool = 3;
NullFilter null = 4;
TimeFilter time = 5;
DurationFilter duration = 6;
}
// not negates the match result
bool not = 7;
}
```The typed filters are the following:
```proto
message StringFilter {
message In {
repeated string values = 1;
}
oneof condition {
string equals = 1;
string regex = 2;
In in = 3;
}
bool case_insensitive = 4;
}message NumberFilter {
message In {
repeated double values = 1;
}
oneof condition {
double equals = 1;
double sup = 2;
double inf = 3;
In in = 4;
}
}message NullFilter {}
message BoolFilter {
bool equals = 1;
}message TimeFilter {
oneof condition {
google.protobuf.Timestamp equals = 1;
google.protobuf.Timestamp before = 2;
google.protobuf.Timestamp after = 3;
}
}message DurationFilter {
oneof condition {
google.protobuf.Duration equals = 1;
google.protobuf.Duration sup = 2;
google.protobuf.Duration inf = 3;
}
}
```## Usage
Download:
```bash
go get go.linka.cloud/protofilters
```Basic example:
```go
package mainimport (
"log""google.golang.org/protobuf/types/known/wrapperspb"
"go.linka.cloud/protofilters"
"go.linka.cloud/protofilters/filters"
test "go.linka.cloud/protofilters/tests/pb"
)func main() {
m := &test.Test{
BoolField: true,
BoolValueField: wrapperspb.Bool(false),
}
ok, err := protofilters.Match(m, filters.Where("bool_field").True())
if err != nil {
log.Fatalln(err)
}
if !ok {
log.Fatalln("should be true")
}
ok, err = protofilters.Match(m, filters.Where("bool_value_field").False())
if err != nil {
log.Fatalln(err)
}
if !ok {
log.Fatalln("should be true")
}
}```
## TODOs
- [ ] support more languages