fieldmask_utils

package module
v0.0.0-...-030f71b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 31, 2019 License: GPL-3.0 Imports: 5 Imported by: 0

README

Protobuf Field Mask utils for Go

Build Status Coverage Status

Features:

  • Copy from any Go struct to any compatible Go struct with a field mask applied
  • Copy from any Go struct to a map[string]interface{} with a field mask applied
  • Extensible masks (e.g. inverse mask: copy all except those mentioned, etc.)

Examples

Copy from a protobuf message to a protobuf message:

// test.proto

message UpdateUserRequest {
    User user = 1;
    google.protobuf.FieldMask field_mask = 2;
}
var request UpdateUserRequest
userDst := &testproto.User{} // a struct to copy to
mask, err := fieldmask_utils.MaskFromProtoFieldMask(request.FieldMask)
// handle err...
fieldmask_utils.StructToStruct(mask, request.User, userDst)
// Only the fields mentioned in the field mask will be copied to userDst, other fields are left intact

Copy from a protobuf message to a map[string]interface{}:

var request UpdateUserRequest
userDst := make(map[string]interface{}) // a map to copy to
mask, err := fieldmask_utils.MaskFromProtoFieldMask(request.FieldMask)
// handle err...
err := fieldmask_utils.StructToMap(mask, request.User, userDst)
// handle err..
// Only the fields mentioned in the field mask will be copied to userDst, other fields are left intact

Copy with an inverse mask:

var request UpdateUserRequest
userDst := &testproto.User{} // a struct to copy to
mask := fieldmask_utils.MaskInverse{"Id": nil, "Friends": fieldmask_utils.MaskInverse{"Username": nil}}
fieldmask_utils.StructToStruct(mask, request.User, userDst)
// Only the fields that are not mentioned in the field mask will be copied to userDst, other fields are left intact.

Limitations

  1. Larger scope field masks have no effect and are not considered invalid:

    field mask strings "a", "a.b", "a.b.c" will result in a mask a{b{c}}, which is the same as "a.b.c".

  2. Masks inside a protobuf Any and Map are not supported.

  3. When copying from a struct to struct the destination struct must have the same fields (or a subset) as the source struct. Pointers must also be coherent: if a field is a pointer in the source struct, then it also must be a pointer (not a value field) in the destination struct.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ProtoToStruct

func ProtoToStruct(
	fm *types.FieldMask,
	src, dst interface{},
	opts ...interface{},
) error

func StructToMap

func StructToMap(
	filter FieldFilter,
	src interface{},
	dst map[string]interface{},
) error

StructToMap copies `src` struct to the `dst` map. Behavior is similar to `StructToStruct`.

func StructToStruct

func StructToStruct(filter FieldFilter, src, dst interface{}) error

StructToStruct copies `src` struct to `dst` struct using the given FieldFilter. Only the fields where FieldFilter returns true will be copied to `dst`. `src` and `dst` must be coherent in terms of the field names, but it is not required for them to be of the same type.

Types

type FieldFilter

type FieldFilter interface {
	// Filter should return a corresponding FieldFilter for the given fieldName and
	Filter(fieldName string) (FieldFilter, bool)
	StructToMap(in interface{}) (map[string]interface{}, error)
}

FieldFilter is an interface used by the copying function to filter fields that are needed to be copied.

type Mask

type Mask map[string]FieldFilter

Mask is a tree-based implementation of a FieldFilter.

func MaskFromProtoFieldMask

func MaskFromProtoFieldMask(
	fm *types.FieldMask,
	opts ...interface{},
) (Mask, error)

MaskFromProtoFieldMask creates a Mask from the given FieldMask.

func MaskFromString

func MaskFromString(s string) Mask

MaskFromString creates a `Mask` from a string `s`. `s` is supposed to be a valid string representation of a FieldFilter like "a,b,c{d,e{f,g}},d". This is the same string format as in FieldFilter.String(). This function should only be used in tests as it does not validate the given string and is only convenient to easily create DefaultMasks.

func (Mask) Filter

func (m Mask) Filter(fieldName string) (FieldFilter, bool)

Filter returns true for those fieldNames that exist in the underlying map. Field names that start with "XXX_" are ignored as unexported.

func (Mask) String

func (m Mask) String() string

func (Mask) StructToMap

func (m Mask) StructToMap(in interface{}) (map[string]interface{}, error)

type MaskInverse

type MaskInverse Mask

MaskInverse is an inversed version of a Mask (will copy all the fields except those mentioned in the mask).

func (MaskInverse) Filter

func (m MaskInverse) Filter(fieldName string) (FieldFilter, bool)

Filter returns true for those fieldNames that do NOT exist in the underlying map. Field names that start with "XXX_" are ignored as unexported.

func (MaskInverse) String

func (m MaskInverse) String() string

func (MaskInverse) StructToMap

func (m MaskInverse) StructToMap(in interface{}) (map[string]interface{}, error)

type Naming

type Naming func(string) string

type Whitelist

type Whitelist []string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL