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")
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
.
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 {
...
}
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.
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
.