From f5bf7c479fcbb80b0f9b742cf6af7306d6b63bd5 Mon Sep 17 00:00:00 2001 From: Mohammad Rajabloo Date: Sun, 25 Aug 2024 22:37:48 +0330 Subject: [PATCH] draft work of module system --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++ error.go | 2 +- module.go | 22 +++++++++++++++++++ reflect.go | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 module.go create mode 100644 reflect.go diff --git a/README.md b/README.md index b0e85da..0109ce9 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,53 @@ func main() { ``` +### Modules + +```go + + creators.RedisConnectionModule[app.Hub](), + creators.Redis2ConnectionModule[app.Hub]("WorkerManager"), +``` + +```go +func WorkerManagerModule[T any]() vabastegi.Provider[T] { + return vabastegi.NewModule(func(ctx context.Context, app *vabastegi.App[T]) vabastegi.Module { + //data := "host with data" + return vabastegi.Module{ + Name: "WorkerManager", + Data: routine.NewSequence(10, 100), + // Data: "some", + //Data: &data, + } + }) +} + +func RedisConnectionModule[T any]() vabastegi.Provider[T] { + return vabastegi.NewModule(func(ctx context.Context, app *vabastegi.App[T]) vabastegi.Module { + //data := "host with data" + return vabastegi.Module{ + Name: "Redis", + Data: redis.NewClient(&redis.Options{}), + // Data: "some", + //Data: &data, + } + }) +} + +func Redis2ConnectionModule[T any](name string) vabastegi.Provider[T] { + return vabastegi.NewModule(func(ctx context.Context, app *vabastegi.App[T]) vabastegi.Module { + //data := "host with data" + return vabastegi.Module{ + Name: name, + Data: redis.NewClient(&redis.Options{}), + // Data: "some", + //Data: &data, + } + }) +} + +``` + for mode details, check the [documentation](https://godoc.org/github.com/mrsoftware/vabastegi) diff --git a/error.go b/error.go index 68ec9f2..bd9e7fd 100644 --- a/error.go +++ b/error.go @@ -8,7 +8,7 @@ import ( func IgnoreError[T any](provider Provider[T]) Provider[T] { return func(ctx context.Context, app *App[T]) error { if err := provider(ctx, app); err != nil { - app.Logger().Errorf("privider error ignored: %s", err.Error()) + app.Log(ErrorLogLevel, "provider error ignored: %s", err) } return nil diff --git a/module.go b/module.go new file mode 100644 index 0000000..b261281 --- /dev/null +++ b/module.go @@ -0,0 +1,22 @@ +package vabastegi + +import "context" + +func NewModule[T any](provider ModuleProvider[T]) Provider[T] { + return func(ctx context.Context, a *App[T]) error { + module := provider(ctx, a) + if module.Err != nil { + return module.Err + } + + return SetHubField(a, module.Name, module.Data) + } +} + +type ModuleProvider[T any] func(ctx context.Context, app *App[T]) Module + +type Module struct { + Name string + Data interface{} + Err error +} diff --git a/reflect.go b/reflect.go new file mode 100644 index 0000000..937c025 --- /dev/null +++ b/reflect.go @@ -0,0 +1,63 @@ +package vabastegi + +import ( + "errors" + "fmt" + "reflect" +) + +// Hub is a contract that the T must satisfy. +type Hub interface { + Get(key string) (interface{}, error) + Set(key string, value interface{}) error +} + +var ( + ErrHubIsNotStruct = errors.New("passed hub is not struct") + ErrHubFieldNotFound = errors.New("hub field not found") + ErrTheFieldCanNotChange = errors.New("the field can not change") +) + +func GetHubField(hub interface{}, name string) (interface{}, error) { + hubValue := reflect.ValueOf(hub) + if hubValue.Kind() != reflect.Struct { + return nil, ErrHubIsNotStruct + } + + theValue := hubValue.FieldByName(name) + if !theValue.IsValid() { + return nil, fmt.Errorf("%s field on hub: %w", name, ErrHubFieldNotFound) + } + + return theValue.Interface(), nil +} + +func SetHubField[T any](app *App[T], name string, value interface{}) (err error) { + defer func() { + if e := recover(); e != nil { + err = fmt.Errorf("setting %s field: %v", name, e) + } + }() + + hubValue := reflect.ValueOf(&app.Hub).Elem() + if hubValue.Kind() != reflect.Struct { + return fmt.Errorf("hub is %s: %w", hubValue.Kind(), ErrHubIsNotStruct) + } + + theValue := hubValue.FieldByName(name) + if !theValue.IsValid() { + return fmt.Errorf("%s field on hub: %w", name, ErrHubFieldNotFound) + } + + if !theValue.CanAddr() { + return ErrTheFieldCanNotChange + } + + theValue.Set(reflect.ValueOf(value)) + + return nil +} + +func areTheSame(valueA, ValueB reflect.Value) bool { + return false +}