mirror of
https://github.com/IBM/fp-go.git
synced 2025-08-10 22:31:32 +02:00
fix: remove types from this branch
Signed-off-by: Dr. Carsten Leue <carsten.leue@de.ibm.com>
This commit is contained in:
@@ -98,7 +98,7 @@ func MapRefWithIndex[K comparable, V, R any](f func(K, *V) R) func(map[K]V) map[
|
||||
}
|
||||
|
||||
// Lookup returns the entry for a key in a map if it exists
|
||||
func Lookup[K comparable, V any](k K) func(map[K]V) O.Option[V] {
|
||||
func Lookup[V any, K comparable](k K) func(map[K]V) O.Option[V] {
|
||||
return G.Lookup[map[K]V](k)
|
||||
}
|
||||
|
||||
|
@@ -71,8 +71,8 @@ func TestLookup(t *testing.T) {
|
||||
"b": "b",
|
||||
"c": "c",
|
||||
}
|
||||
assert.Equal(t, O.Some("a"), Lookup[string, string]("a")(data))
|
||||
assert.Equal(t, O.None[string](), Lookup[string, string]("a1")(data))
|
||||
assert.Equal(t, O.Some("a"), Lookup[string]("a")(data))
|
||||
assert.Equal(t, O.None[string](), Lookup[string]("a1")(data))
|
||||
}
|
||||
|
||||
func TestFilterChain(t *testing.T) {
|
||||
|
@@ -1,91 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
AR "github.com/IBM/fp-go/array/generic"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
T "github.com/IBM/fp-go/tuple"
|
||||
)
|
||||
|
||||
func toUnknownArray[A any](item func(reflect.Value, Context) E.Either[Errors, A], c Context, val reflect.Value) []E.Either[Errors, A] {
|
||||
l := val.Len()
|
||||
res := make([]E.Either[Errors, A], l)
|
||||
for i := l - 1; i >= 0; i-- {
|
||||
v := val.Index(i)
|
||||
res[i] = item(v, AR.Push[Context](&ContextEntry{Key: fmt.Sprintf("[%d]", i), Value: v})(c))
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func flattenUnknownArray[GA ~[]A, A any](as []E.Either[Errors, A]) E.Either[Errors, GA] {
|
||||
return F.Pipe1(
|
||||
AR.Reduce(as, func(t T.Tuple2[GA, Errors], item E.Either[Errors, A]) T.Tuple2[GA, Errors] {
|
||||
return E.MonadFold(item, func(e Errors) T.Tuple2[GA, Errors] {
|
||||
return T.MakeTuple2(t.F1, append(t.F2, e...))
|
||||
}, func(a A) T.Tuple2[GA, Errors] {
|
||||
return T.MakeTuple2(append(t.F1, a), t.F2)
|
||||
})
|
||||
}, T.MakeTuple2(make(GA, len(as)), make(Errors, 0))),
|
||||
func(t T.Tuple2[GA, Errors]) E.Either[Errors, GA] {
|
||||
if AR.IsEmpty(t.F2) {
|
||||
return E.Of[Errors](t.F1)
|
||||
}
|
||||
return E.Left[GA](t.F2)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func toValidatedArray[GA ~[]A, A any](item func(reflect.Value, Context) E.Either[Errors, A], c Context, val reflect.Value) E.Either[Errors, GA] {
|
||||
return F.Pipe1(
|
||||
toUnknownArray(item, c, val),
|
||||
flattenUnknownArray[GA, A],
|
||||
)
|
||||
}
|
||||
|
||||
func validateArray[GA ~[]A, A any](item Validate[reflect.Value, A]) func(i reflect.Value, c Context) E.Either[Errors, GA] {
|
||||
var r func(i reflect.Value, c Context) E.Either[Errors, GA]
|
||||
|
||||
r = func(i reflect.Value, c Context) E.Either[Errors, GA] {
|
||||
// check for unknow array
|
||||
switch i.Kind() {
|
||||
case reflect.Slice:
|
||||
return toValidatedArray[GA](item, c, i)
|
||||
case reflect.Array:
|
||||
return toValidatedArray[GA](item, c, i)
|
||||
case reflect.Pointer:
|
||||
return r(i.Elem(), c)
|
||||
default:
|
||||
return Failure[GA](c, fmt.Sprintf("Type %T is neither an array nor a slice nor a pointer to these values", i))
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// ArrayG returns the type validator for an array
|
||||
func ArrayG[GA ~[]A, A any](item Validate[reflect.Value, A]) *Type[GA, GA, reflect.Value] {
|
||||
return FromValidate(validateArray[GA, A](item))
|
||||
}
|
||||
|
||||
// Array returns the type validator for an array
|
||||
func Array[A any](item Validate[reflect.Value, A]) *Type[[]A, []A, reflect.Value] {
|
||||
return ArrayG[[]A, A](item)
|
||||
}
|
@@ -1,41 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestArray(t *testing.T) {
|
||||
stringArray := Array(String.Validate)
|
||||
|
||||
validData := A.From(
|
||||
reflect.ValueOf(A.From("a", "b", "c")),
|
||||
reflect.ValueOf(A.Empty[string]()),
|
||||
reflect.ValueOf([]string{"a", "b"}),
|
||||
reflect.ValueOf(A.From(1, 2, 3)),
|
||||
)
|
||||
|
||||
for i := 0; i < len(validData); i++ {
|
||||
assert.True(t, E.IsRight(stringArray.Decode(validData[i])))
|
||||
}
|
||||
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
AR "github.com/IBM/fp-go/array/generic"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
)
|
||||
|
||||
func getMessage(val *ValidationError) string {
|
||||
return val.Message
|
||||
}
|
||||
|
||||
func pathNoErrors() []string {
|
||||
return AR.Of[[]string]("No Errors!")
|
||||
}
|
||||
|
||||
func PathReporter[A any](val E.Either[Errors, A]) []string {
|
||||
return E.MonadFold(
|
||||
val,
|
||||
AR.Map[Errors, []string](getMessage),
|
||||
func(_ A) []string {
|
||||
return pathNoErrors()
|
||||
},
|
||||
)
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
|
||||
E "github.com/IBM/fp-go/either"
|
||||
)
|
||||
|
||||
func validateStringFromReflect(i reflect.Value, c Context) E.Either[Errors, string] {
|
||||
switch i.Kind() {
|
||||
case reflect.String:
|
||||
return E.Of[Errors](i.String())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return E.Of[Errors](strconv.FormatInt(i.Int(), 10))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return E.Of[Errors](strconv.FormatUint(i.Uint(), 10))
|
||||
case reflect.Bool:
|
||||
return E.Of[Errors](strconv.FormatBool(i.Bool()))
|
||||
case reflect.Pointer:
|
||||
return validateStringFromReflect(i.Elem(), c)
|
||||
case reflect.Invalid:
|
||||
return Failure[string](c, "Invalid value")
|
||||
}
|
||||
|
||||
if i.CanInterface() {
|
||||
if strg, ok := i.Interface().(fmt.Stringer); ok {
|
||||
return E.Of[Errors](strg.String())
|
||||
}
|
||||
}
|
||||
|
||||
return E.Of[Errors](i.String())
|
||||
}
|
||||
|
||||
// String returns the type validator for a string
|
||||
func makeString() *Type[string, string, reflect.Value] {
|
||||
return FromValidate(validateStringFromReflect)
|
||||
}
|
||||
|
||||
// converts from any type to string
|
||||
var String = makeString()
|
@@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
A "github.com/IBM/fp-go/array"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
s := "Carsten"
|
||||
validData := A.From(
|
||||
reflect.ValueOf("Carsten"),
|
||||
reflect.ValueOf(s),
|
||||
reflect.ValueOf(&s),
|
||||
reflect.ValueOf(10),
|
||||
reflect.ValueOf(true),
|
||||
reflect.ValueOf(false),
|
||||
)
|
||||
for i := 0; i < len(validData); i++ {
|
||||
assert.True(t, E.IsRight(String.Decode(validData[i])))
|
||||
}
|
||||
|
||||
invalidDataData := A.From(
|
||||
reflect.ValueOf(nil),
|
||||
)
|
||||
for i := 0; i < len(invalidDataData); i++ {
|
||||
assert.True(t, E.IsLeft(String.Decode(invalidDataData[i])))
|
||||
}
|
||||
}
|
146
types/types.go
146
types/types.go
@@ -1,146 +0,0 @@
|
||||
// Copyright (c) 2023 IBM Corp.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
AR "github.com/IBM/fp-go/array/generic"
|
||||
E "github.com/IBM/fp-go/either"
|
||||
F "github.com/IBM/fp-go/function"
|
||||
"github.com/IBM/fp-go/option"
|
||||
)
|
||||
|
||||
type (
|
||||
ValidationError struct {
|
||||
Context Context
|
||||
Message string
|
||||
}
|
||||
|
||||
ContextEntry struct {
|
||||
Key string
|
||||
Value any
|
||||
}
|
||||
|
||||
Errors []*ValidationError
|
||||
|
||||
Context []*ContextEntry
|
||||
|
||||
Encoder[A, O any] interface {
|
||||
Encode(A) O
|
||||
}
|
||||
|
||||
Decoder[I, A any] interface {
|
||||
Validate(I, Context) E.Either[Errors, A]
|
||||
Decode(I) E.Either[Errors, A]
|
||||
}
|
||||
|
||||
Codec[I, O, A any] interface {
|
||||
Encoder[A, O]
|
||||
Decoder[I, A]
|
||||
}
|
||||
|
||||
Guard[I, A any] func(I) option.Option[A]
|
||||
|
||||
Validate[I, A any] func(I, Context) E.Either[Errors, A]
|
||||
|
||||
Type[A, O, I any] struct {
|
||||
validate func(I, Context) E.Either[Errors, A]
|
||||
encode func(A) O
|
||||
is Guard[I, A]
|
||||
}
|
||||
)
|
||||
|
||||
func (t *Type[A, O, I]) Validate(i I, c Context) E.Either[Errors, A] {
|
||||
return t.validate(i, c)
|
||||
}
|
||||
|
||||
func defaultContext(value any) Context {
|
||||
return AR.Of[Context](&ContextEntry{Value: value})
|
||||
}
|
||||
|
||||
func (t *Type[A, O, I]) Decode(i I) E.Either[Errors, A] {
|
||||
return t.validate(i, defaultContext(i))
|
||||
}
|
||||
|
||||
func (t *Type[A, O, I]) Encode(a A) O {
|
||||
return t.encode(a)
|
||||
}
|
||||
|
||||
func (t *Type[A, O, I]) Is(a I) option.Option[A] {
|
||||
return t.is(a)
|
||||
}
|
||||
|
||||
func (t *Type[A, O, I]) AsEncoder() Encoder[A, O] {
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *Type[A, O, I]) AsDecoder() Decoder[I, A] {
|
||||
return t
|
||||
}
|
||||
|
||||
func (val *ValidationError) Error() string {
|
||||
return val.Message
|
||||
}
|
||||
|
||||
func Pipe[O, I, A, B any](ab Type[B, A, A]) func(a Type[A, O, I]) Type[B, O, I] {
|
||||
return func(a Type[A, O, I]) Type[B, O, I] {
|
||||
return Type[B, O, I]{
|
||||
is: F.Flow2(
|
||||
a.is,
|
||||
option.Chain(ab.Is),
|
||||
),
|
||||
validate: func(i I, c Context) E.Either[Errors, B] {
|
||||
return F.Pipe1(
|
||||
a.Validate(i, c),
|
||||
E.Chain(F.Bind2nd(ab.Validate, c)),
|
||||
)
|
||||
},
|
||||
encode: F.Flow2(
|
||||
ab.Encode,
|
||||
a.Encode,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Success[A any](value A) E.Either[Errors, A] {
|
||||
return E.Of[Errors](value)
|
||||
}
|
||||
|
||||
func Failures[A any](err Errors) E.Either[Errors, A] {
|
||||
return E.Left[A](err)
|
||||
}
|
||||
|
||||
func Failure[A any](c Context, message string) E.Either[Errors, A] {
|
||||
return Failures[A](AR.Of[Errors](&ValidationError{Context: c, Message: message}))
|
||||
}
|
||||
|
||||
func guardFromValidate[A, I any](validate func(I, Context) E.Either[Errors, A]) Guard[I, A] {
|
||||
return func(i I) option.Option[A] {
|
||||
return F.Pipe1(
|
||||
validate(i, defaultContext(i)),
|
||||
E.ToOption[Errors, A],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// FromValidate constructs a Type instance from just the validation function
|
||||
func FromValidate[A, I any](validate Validate[I, A]) *Type[A, A, I] {
|
||||
return &Type[A, A, I]{
|
||||
validate,
|
||||
F.Identity[A],
|
||||
guardFromValidate[A, I](validate),
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user