@@ 37,6 37,7 @@ import (
type Provide[Out any] struct {
fOrV any
+ set bool
}
// Optional is the canonical way of specifying a field is optional. The library
@@ 60,12 61,14 @@ func Some[T any](val T) Optional[T] {
}
type provideI interface {
- diOutType() reflect.Type
- diPayload() any
+ outT() reflect.Type
+ payload() any
+ isSet() bool
}
-func (p Provide[Out]) diOutType() reflect.Type { return typeOf[Out]() }
-func (p Provide[Out]) diPayload() any { return p.fOrV }
+func (p Provide[Out]) outT() reflect.Type { return typeOf[Out]() }
+func (p Provide[Out]) payload() any { return p.fOrV }
+func (p Provide[Out]) isSet() bool { return p.set }
// SideEffect is a canonical value representing a constructor used only for side
// effects such as introducing two components together without a circular
@@ 292,8 295,11 @@ func (c *collector) collect(v reflect.Value, path string) error {
// Provide[T] (singular) must be recognized BEFORE treating structs as namespaces.
if pi, ok := asProvide(fv); ok {
- outT := pi.diOutType()
- payload := pi.diPayload()
+ outT := pi.outT()
+ payload := pi.payload()
+ if !pi.isSet() {
+ return fmt.Errorf("Missing Provide[%s]", outT)
+ }
if payload == nil {
c.values[outT] = reflect.Zero(outT)
continue
@@ 326,15 332,15 @@ func (c *collector) collect(v reflect.Value, path string) error {
if provideElem, ok := reflect.New(fv.Type().Elem()).Elem().Interface().(provideI); ok {
if fv.Len() == 0 && !fv.IsNil() {
// Set presence of empty list
- outT := provideElem.diOutType()
+ outT := provideElem.outT()
c.listPresence[outT] = true
}
for j := 0; j < fv.Len(); j++ {
pi := fv.Index(j).Interface().(provideI)
- outT := pi.diOutType()
+ outT := pi.outT()
c.listPresence[outT] = true
- payload := pi.diPayload()
+ payload := pi.payload()
if payload == nil {
c.listValues[outT] = append(c.listValues[outT], reflect.Zero(outT))
continue