From 4b54b5d74b8796c7c8f8b2c5e9c4ab3e80b273a4 Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Fri, 6 Dec 2024 17:10:35 +0300 Subject: [PATCH] validate: imp append --- netutil/httputil/logmw.go | 6 +++--- validate/validate.go | 20 ++++++++++++++++---- validate/validate_example_test.go | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/netutil/httputil/logmw.go b/netutil/httputil/logmw.go index 2d610ac..c966941 100644 --- a/netutil/httputil/logmw.go +++ b/netutil/httputil/logmw.go @@ -66,7 +66,7 @@ func (mw *LogMiddleware) Wrap(h http.Handler) (wrapped http.Handler) { rw.Reset(w) l.Log(ctx, mw.lvl, "started") - defer mw.printFinished(ctx, l, rw, startTime) + defer mw.logFinished(ctx, l, rw, startTime) h.ServeHTTP(rw, nextReq) rw.SetImplicitSuccess() @@ -75,8 +75,8 @@ func (mw *LogMiddleware) Wrap(h http.Handler) (wrapped http.Handler) { return http.HandlerFunc(f) } -// printFinished is called at the end of handling of a query. -func (mw *LogMiddleware) printFinished( +// logFinished is called at the end of handling of a query. +func (mw *LogMiddleware) logFinished( ctx context.Context, l *slog.Logger, rw *CodeRecorderResponseWriter, diff --git a/validate/validate.go b/validate/validate.go index 5117fe8..17fbe50 100644 --- a/validate/validate.go +++ b/validate/validate.go @@ -28,9 +28,21 @@ type Interface interface { Validate() (err error) } -// Append validates values, wraps errors with the name and the index, appends -// them to errs, and returns the result. -func Append[T Interface](errs []error, name string, values []T) (res []error) { +// Append validates v and, if it returns an error, appends it to errs and +// returns the result. +func Append(errs []error, name string, v Interface) (res []error) { + res = errs + err := v.Validate() + if err != nil { + res = append(res, fmt.Errorf("%s: %w", name, err)) + } + + return res +} + +// AppendSlice validates values, wraps errors with the name and the index, +// appends them to errs, and returns the result. +func AppendSlice[T Interface](errs []error, name string, values []T) (res []error) { res = errs for i, v := range values { // TODO(a.garipov): Consider flattening error slices. @@ -46,7 +58,7 @@ func Append[T Interface](errs []error, name string, values []T) (res []error) { // Slice validates values, wraps errors with the name and the index, and returns // the result as a single joined error. func Slice[T Interface](name string, values []T) (err error) { - return errors.Join(Append(nil, name, values)...) + return errors.Join(AppendSlice(nil, name, values)...) } // InRange returns an error of v is less than min or greater than max. The diff --git a/validate/validate_example_test.go b/validate/validate_example_test.go index 1694107..d572541 100644 --- a/validate/validate_example_test.go +++ b/validate/validate_example_test.go @@ -21,6 +21,25 @@ func (v *value) Validate() (err error) { return v.err } +func ExampleAppend() { + var errs []error + + var ( + badValue = &value{ + err: errors.Error("test error"), + } + goodValue = &value{} + ) + + errs = validate.Append(errs, "first_value", goodValue) + errs = validate.Append(errs, "second_value", badValue) + + fmt.Println(errors.Join(errs...)) + + // Output: + // second_value: test error +} + func ExampleSlice() { values := []*value{ 0: {