An open API service indexing awesome lists of open source software.

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

Awesome Lists containing this project

README

        

# Proto Filters

[![Go Reference](https://pkg.go.dev/badge/go.linka.cloud/protofilters.svg)](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 main

import (
"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