Skip to content

Latest commit

 

History

History
84 lines (68 loc) · 1.9 KB

README.md

File metadata and controls

84 lines (68 loc) · 1.9 KB

Partial

Using Go 1.18's generics, this models a partial struct:

type MyStruct struct {
  Thing1 string
  Thing2 string
}

whole := MyStruct{
  Thing1: "hello",
}
partStruct := partial.New(whole).Without("Thing2")

Why is this useful?

Sometimes you want to do partial updates, or partial matches on a struct. In the above example whole.Thing2 is initialised to "", but really we just don't know what it is. By using a Partial that explicitly says "I only know about Thing1", we can safely apply partStruct as a database update for example.

This is also useful for matching things in tests: you might not care about the value in Thing2, and just want to match on Thing1.

Generators

Two generators are included. To use them, install them with

go install github.com/incident-io/partial/cmd/partial

Then add a go:generate comment to each package that contains relevant structs:

//go:generate partial

Within that package, annotate each struct that you want a matcher or builder for with:

// codegen-partial:builder,matcher
type MyStruct struct {
  ...
}

Builder

The builder generated lets you build up a partial of the given struct. For example:

//go:generate partial
package things

// codegen-partial:builder
type MyStruct struct {
  Thing1 string
  Thing2 string
}

will generate a builder that you can use like so:

partStruct := things.MyStructBuilder(
  things.MyStructBuilder.Thing1("hello"),
)

Because the builder is generated, you get type checking and autocompletion.

Matcher

The matcher produces Gomega matchers, that let you match on part of the struct. If we update the comment in the above example to

// codegen-partial:builder,matcher

we can then match as follows:

Expect(myStruct).To(things.MyStructMatcher(
  things.MyStructMatcher.Thing1("hello"),
))

This will ignore any value in myStruct.Thing2.