summaryrefslogtreecommitdiff
path: root/vendor/github.com/xlgmokha/x/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/xlgmokha/x/pkg')
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/context/key.go20
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/convert/ptr.go9
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/env/env.go22
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/env/vars.go3
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/env/with.go27
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/log/context.go17
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/log/fields.go7
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/log/http.go23
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/log/init.go18
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/log/log.go19
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/mapper/mapper.go46
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/mapper/test.go77
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/error.go16
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/iterate.go60
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/middleware.go8
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/option.go20
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/specification.go21
-rw-r--r--vendor/github.com/xlgmokha/x/pkg/x/types.go38
18 files changed, 451 insertions, 0 deletions
diff --git a/vendor/github.com/xlgmokha/x/pkg/context/key.go b/vendor/github.com/xlgmokha/x/pkg/context/key.go
new file mode 100644
index 00000000..80ca7bd2
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/context/key.go
@@ -0,0 +1,20 @@
+package context
+
+import (
+ "context"
+
+ "github.com/xlgmokha/x/pkg/x"
+)
+
+type Key[T any] string
+
+func (self Key[T]) With(ctx context.Context, value T) context.Context {
+ return context.WithValue(ctx, self, value)
+}
+
+func (self Key[T]) From(ctx context.Context) T {
+ if value := ctx.Value(self); value != nil {
+ return value.(T)
+ }
+ return x.Zero[T]()
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/convert/ptr.go b/vendor/github.com/xlgmokha/x/pkg/convert/ptr.go
new file mode 100644
index 00000000..34c3949f
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/convert/ptr.go
@@ -0,0 +1,9 @@
+package convert
+
+func ToPtr[T any](item T) *T {
+ return &item
+}
+
+func FromPtr[T any](p *T) T {
+ return *p
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/env/env.go b/vendor/github.com/xlgmokha/x/pkg/env/env.go
new file mode 100644
index 00000000..24fb519a
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/env/env.go
@@ -0,0 +1,22 @@
+package env
+
+import (
+ "os"
+ "strings"
+)
+
+func Fetch(key string, defaultValue string) string {
+ if x := os.Getenv(key); x != "" {
+ return x
+ }
+ return defaultValue
+}
+
+func Variables() Vars {
+ items := Vars{}
+ for _, line := range os.Environ() {
+ segments := strings.SplitN(line, "=", 2)
+ items[segments[0]] = segments[1]
+ }
+ return items
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/env/vars.go b/vendor/github.com/xlgmokha/x/pkg/env/vars.go
new file mode 100644
index 00000000..aad050ab
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/env/vars.go
@@ -0,0 +1,3 @@
+package env
+
+type Vars map[string]string
diff --git a/vendor/github.com/xlgmokha/x/pkg/env/with.go b/vendor/github.com/xlgmokha/x/pkg/env/with.go
new file mode 100644
index 00000000..6efeed46
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/env/with.go
@@ -0,0 +1,27 @@
+package env
+
+import (
+ "os"
+)
+
+func With(env Vars, callback func()) {
+ original := Vars{}
+
+ for key, value := range env {
+ if val, ok := os.LookupEnv(key); ok {
+ original[key] = val
+ }
+ os.Setenv(key, value)
+ }
+
+ defer func() {
+ for key, _ := range env {
+ os.Unsetenv(key)
+ }
+ for key, value := range original {
+ os.Setenv(key, value)
+ }
+ }()
+
+ callback()
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/log/context.go b/vendor/github.com/xlgmokha/x/pkg/log/context.go
new file mode 100644
index 00000000..ce99fe77
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/log/context.go
@@ -0,0 +1,17 @@
+package log
+
+import (
+ "context"
+
+ "github.com/rs/zerolog"
+)
+
+func WithFields(ctx context.Context, fields Fields) {
+ From(ctx).UpdateContext(func(c zerolog.Context) zerolog.Context {
+ return c.Fields(fields.ToMap())
+ })
+}
+
+func From(ctx context.Context) *zerolog.Logger {
+ return zerolog.Ctx(ctx)
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/log/fields.go b/vendor/github.com/xlgmokha/x/pkg/log/fields.go
new file mode 100644
index 00000000..8b0d48e2
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/log/fields.go
@@ -0,0 +1,7 @@
+package log
+
+type Fields map[string]interface{}
+
+func (f Fields) ToMap() map[string]interface{} {
+ return map[string]interface{}(f)
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/log/http.go b/vendor/github.com/xlgmokha/x/pkg/log/http.go
new file mode 100644
index 00000000..2257fa07
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/log/http.go
@@ -0,0 +1,23 @@
+package log
+
+import (
+ "net/http"
+
+ "github.com/rs/zerolog"
+ "github.com/xlgmokha/x/pkg/mapper"
+)
+
+func HTTP(logger *zerolog.Logger) func(http.Handler) http.Handler {
+ return func(next http.Handler) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ ctx := logger.WithContext(r.Context())
+
+ defer func() {
+ WithFields(ctx, mapper.MapFrom[*http.Request, Fields](r))
+ zerolog.Ctx(ctx).Print()
+ }()
+
+ next.ServeHTTP(w, r.WithContext(ctx))
+ })
+ }
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/log/init.go b/vendor/github.com/xlgmokha/x/pkg/log/init.go
new file mode 100644
index 00000000..202b1864
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/log/init.go
@@ -0,0 +1,18 @@
+package log
+
+import (
+ "net/http"
+
+ "github.com/xlgmokha/x/pkg/mapper"
+)
+
+func init() {
+ mapper.Register[*http.Request, Fields](func(r *http.Request) Fields {
+ return Fields{
+ "host": r.URL.Host,
+ "method": r.Method,
+ "path": r.URL.Path,
+ "remote_host": r.RemoteAddr,
+ }
+ })
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/log/log.go b/vendor/github.com/xlgmokha/x/pkg/log/log.go
new file mode 100644
index 00000000..de9098be
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/log/log.go
@@ -0,0 +1,19 @@
+package log
+
+import (
+ "io"
+
+ "github.com/rs/zerolog"
+ "github.com/xlgmokha/x/pkg/convert"
+)
+
+func New(writer io.Writer, fields Fields) *zerolog.Logger {
+ return convert.ToPtr(
+ zerolog.
+ New(writer).
+ With().
+ Timestamp().
+ Fields(fields.ToMap()).
+ Logger(),
+ )
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/mapper/mapper.go b/vendor/github.com/xlgmokha/x/pkg/mapper/mapper.go
new file mode 100644
index 00000000..2057f719
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/mapper/mapper.go
@@ -0,0 +1,46 @@
+package mapper
+
+import (
+ "fmt"
+ "reflect"
+)
+
+type Mapping[TInput any, TOutput any] func(TInput) TOutput
+
+var mappings map[string]interface{}
+
+func init() {
+ mappings = map[string]interface{}{}
+}
+
+func Register[Input any, Output any](mapping Mapping[Input, Output]) {
+ mappings[keyFor[Input, Output]()] = mapping
+}
+
+func MapFrom[Input any, Output any](input Input) Output {
+ if mapping, ok := mappings[keyFor[Input, Output]()]; ok {
+ return mapping.(Mapping[Input, Output])(input)
+ }
+ var output Output
+ return output
+}
+
+func MapEachFrom[Input any, Output any](input []Input) []Output {
+ var zero Output
+ zeroValue := reflect.Zero(reflect.TypeOf(zero))
+
+ results := []Output{}
+ for _, item := range input {
+ tmp := MapFrom[Input, Output](item)
+ if zeroValue != reflect.ValueOf(tmp) {
+ results = append(results, tmp)
+ }
+ }
+ return results
+}
+
+func keyFor[Input any, Output any]() string {
+ var input Input
+ var output Output
+ return fmt.Sprintf("%v-%v", reflect.TypeOf(input), reflect.TypeOf(output))
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/mapper/test.go b/vendor/github.com/xlgmokha/x/pkg/mapper/test.go
new file mode 100644
index 00000000..6e18807f
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/mapper/test.go
@@ -0,0 +1,77 @@
+package mapper
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+type unregisteredType struct{}
+
+type testObject struct {
+ GivenName string
+ FamilyName string
+}
+
+type testModel struct {
+ Name string
+}
+
+func TestMapper(t *testing.T) {
+ Register[*testObject, *testModel](func(item *testObject) *testModel {
+ return &testModel{
+ Name: fmt.Sprintf("%v %v", item.GivenName, item.FamilyName),
+ }
+ })
+
+ t.Run("MapFrom", func(t *testing.T) {
+ t.Run("when the mapping is registered", func(t *testing.T) {
+ item := &testObject{
+ GivenName: "Tsuyoshi",
+ FamilyName: "Garret",
+ }
+
+ model := MapFrom[*testObject, *testModel](item)
+
+ require.NotNil(t, model)
+ assert.Equal(t, "Tsuyoshi Garret", model.Name)
+ })
+
+ t.Run("When the mapping is not registered", func(t *testing.T) {
+ item := &unregisteredType{}
+ model := MapFrom[*unregisteredType, *testModel](item)
+
+ assert.Nil(t, model)
+ })
+ })
+
+ t.Run("MapEachFrom", func(t *testing.T) {
+ t.Run("when the mapping is registered", func(t *testing.T) {
+ datum := []*testObject{
+ {GivenName: "Tsuyoshi", FamilyName: "Garret"},
+ {GivenName: "Takashi", FamilyName: "Shirogane"},
+ }
+
+ results := MapEachFrom[*testObject, *testModel](datum)
+
+ require.NotNil(t, results)
+ require.Equal(t, 2, len(results))
+
+ assert.Equal(t, "Tsuyoshi Garret", results[0].Name)
+ assert.Equal(t, "Takashi Shirogane", results[1].Name)
+ })
+
+ t.Run("when the mapping is not registered", func(t *testing.T) {
+ datum := []*unregisteredType{
+ {},
+ }
+
+ results := MapEachFrom[*unregisteredType, *testModel](datum)
+
+ require.NotNil(t, results)
+ assert.Equal(t, 0, len(results))
+ })
+ })
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/error.go b/vendor/github.com/xlgmokha/x/pkg/x/error.go
new file mode 100644
index 00000000..be9db9ca
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/error.go
@@ -0,0 +1,16 @@
+package x
+
+var Panic = func(err error) {
+ panic(err)
+}
+
+func Check(err error) {
+ if err != nil {
+ Panic(err)
+ }
+}
+
+func Must[T any](item T, err error) T {
+ Check(err)
+ return item
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/iterate.go b/vendor/github.com/xlgmokha/x/pkg/x/iterate.go
new file mode 100644
index 00000000..a1d40a1d
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/iterate.go
@@ -0,0 +1,60 @@
+package x
+
+import "slices"
+
+type Mapper[T any, K any] func(T) K
+type Predicate[T any] func(T) bool
+type Visitor[T any] func(T)
+
+func Find[T any](items []T, predicate Predicate[T]) T {
+ for _, item := range items {
+ if predicate(item) {
+ return item
+ }
+ }
+ return Zero[T]()
+}
+
+func FindAll[T any](items []T, predicate Predicate[T]) []T {
+ results := []T{}
+ Each[T](items, func(item T) {
+ if predicate(item) {
+ results = append(results, item)
+ }
+ })
+ return results
+}
+
+func Contains[T comparable](items []T, predicate Predicate[T]) bool {
+ return Find[T](items, predicate) != Zero[T]()
+}
+
+func Map[TInput any, TOutput any](items []TInput, mapFrom Mapper[TInput, TOutput]) []TOutput {
+ results := []TOutput{}
+ Each[TInput](items, func(item TInput) {
+ results = append(results, mapFrom(item))
+ })
+ return results
+}
+
+func Each[T any](items []T, v Visitor[T]) {
+ for _, item := range items {
+ v(item)
+ }
+}
+
+func Inject[TInput any, TOutput any](items []TInput, memo TOutput, f func(TOutput, TInput)) TOutput {
+ for _, item := range items {
+ f(memo, item)
+ }
+ return memo
+}
+
+func Prepend[T any](rest []T, beginning ...T) []T {
+ return append(beginning, rest...)
+}
+
+func Reverse[T any](items []T) []T {
+ slices.Reverse(items)
+ return items
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/middleware.go b/vendor/github.com/xlgmokha/x/pkg/x/middleware.go
new file mode 100644
index 00000000..a24580a3
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/middleware.go
@@ -0,0 +1,8 @@
+package x
+
+func Middleware[T any](item T, items ...Option[T]) T {
+ for _, middleware := range Reverse(items) {
+ item = middleware(item)
+ }
+ return item
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/option.go b/vendor/github.com/xlgmokha/x/pkg/x/option.go
new file mode 100644
index 00000000..b0bf6381
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/option.go
@@ -0,0 +1,20 @@
+package x
+
+type Configure[T any] func(T)
+type Option[T any] func(T) T
+type Factory[T any] func() T
+
+func New[T any](options ...Option[T]) T {
+ item := Default[T]()
+ for _, option := range options {
+ item = option(item)
+ }
+ return item
+}
+
+func With[T any](with Configure[T]) Option[T] {
+ return func(item T) T {
+ with(item)
+ return item
+ }
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/specification.go b/vendor/github.com/xlgmokha/x/pkg/x/specification.go
new file mode 100644
index 00000000..c79dc4ad
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/specification.go
@@ -0,0 +1,21 @@
+package x
+
+type Specification[T any] interface {
+ IsSatisfiedBy(T) bool
+}
+
+func (f Predicate[T]) IsSatisfiedBy(item T) bool {
+ return f(item)
+}
+
+func (s Predicate[T]) Or(other Specification[T]) Predicate[T] {
+ return Predicate[T](func(item T) bool {
+ return s.IsSatisfiedBy(item) || other.IsSatisfiedBy(item)
+ })
+}
+
+func (s Predicate[T]) And(other Specification[T]) Predicate[T] {
+ return Predicate[T](func(item T) bool {
+ return s.IsSatisfiedBy(item) && other.IsSatisfiedBy(item)
+ })
+}
diff --git a/vendor/github.com/xlgmokha/x/pkg/x/types.go b/vendor/github.com/xlgmokha/x/pkg/x/types.go
new file mode 100644
index 00000000..7c38c834
--- /dev/null
+++ b/vendor/github.com/xlgmokha/x/pkg/x/types.go
@@ -0,0 +1,38 @@
+package x
+
+import "reflect"
+
+func Default[T any]() T {
+ item := Zero[T]()
+
+ if IsPtr[T](item) {
+ return reflect.New(reflect.TypeOf(item).Elem()).Interface().(T)
+ }
+
+ return item
+}
+
+func Zero[T any]() T {
+ var item T
+ return item
+}
+
+func IsZero[T comparable](item T) bool {
+ return item == Zero[T]()
+}
+
+func IsPresent[T comparable](item T) bool {
+ return !IsZero[T](item)
+}
+
+func IsPtr[T any](item T) bool {
+ return Is[T](item, reflect.Pointer)
+}
+
+func IsSlice[T any](item T) bool {
+ return Is[T](item, reflect.Slice)
+}
+
+func Is[T any](item T, kind reflect.Kind) bool {
+ return reflect.TypeOf(item).Kind() == kind
+}