From 08682c35c1f8a7e52744fcd603828880539975c3 Mon Sep 17 00:00:00 2001 From: Heavy Date: Thu, 12 Feb 2026 20:34:32 +0000 Subject: [PATCH] add Int64Component --- internal/block/block.go | 8 +- internal/block/component.go | 3 +- .../block/int64_component/int64_component.go | 89 +++++++++++++++++++ .../block/int64_component/validators/max.go | 21 +++++ internal/block/number_component.go | 54 ----------- .../block/text_component/text_component.go | 16 ++-- main.go | 25 +++--- 7 files changed, 141 insertions(+), 75 deletions(-) create mode 100644 internal/block/int64_component/int64_component.go create mode 100644 internal/block/int64_component/validators/max.go delete mode 100644 internal/block/number_component.go diff --git a/internal/block/block.go b/internal/block/block.go index 19022dc..2eb130b 100644 --- a/internal/block/block.go +++ b/internal/block/block.go @@ -2,7 +2,6 @@ package block import ( "encoding/json" - "fmt" ) type Block struct { @@ -23,17 +22,18 @@ func (b *BlockInstance) FromJSON(block *Block, data []byte) error { for _, c := range block.Components { jsonValue, ok := raw[c.Identifier()] + // jsonValue, ok := raw[c.Identifier()] if !ok { - continue + // continue + jsonValue = nil } instance := c.NewInstance() if err := instance.FromJSON(c, jsonValue); err != nil { return err } - components = append(components, instance) - fmt.Println(c.Identifier(), instance) + components = append(components, instance) } b.Components = components diff --git a/internal/block/component.go b/internal/block/component.go index ab534d0..653cfd1 100644 --- a/internal/block/component.go +++ b/internal/block/component.go @@ -10,7 +10,7 @@ type ComponentType int8 const ( _ ComponentType = iota TextComponentType - NumberComponentType + Int64ComponentType Date ) @@ -24,4 +24,5 @@ type Component interface { type ComponentInstance interface { FromJSON(component Component, data json.RawMessage) error + Value() interface{} } diff --git a/internal/block/int64_component/int64_component.go b/internal/block/int64_component/int64_component.go new file mode 100644 index 0000000..6fae531 --- /dev/null +++ b/internal/block/int64_component/int64_component.go @@ -0,0 +1,89 @@ +package int64_component + +import ( + "blocky/internal/block" + "blocky/internal/block/validation" + "encoding/json" + "fmt" +) + +type Int64Component struct { + identifier string + name string + validators []validation.Validator + Int64Validators []Int64Validator +} + +func (t Int64Component) Type() block.ComponentType { + return block.Int64ComponentType +} + +func (t Int64Component) Name() string { + return t.name +} + +func (t Int64Component) Identifier() string { + return t.identifier +} + +func (t Int64Component) Validators() []validation.Validator { + return t.validators +} + +func NewInt64Component(identifier, name string, validators []validation.ComponentOption, int64Validators []Int64ComponentOption) Int64Component { + cfg := &validation.ComponentConfig{} + for _, opt := range validators { + opt(cfg) + } + + int64Cfg := &Int64ComponentConfig{} + for _, opt := range int64Validators { + opt(int64Cfg) + } + + return Int64Component{identifier: identifier, name: name, validators: cfg.Validators, Int64Validators: int64Cfg.Validators} +} + +func (t Int64Component) NewInstance() block.ComponentInstance { + return &Int64ComponentInstance{} +} + +type Int64ComponentInstance struct { + value int64 +} + +func (t *Int64ComponentInstance) Value() interface{} { + return t.value +} + +func (t *Int64ComponentInstance) FromJSON(component block.Component, data json.RawMessage) error { + var s int64 + err := json.Unmarshal(data, &s) + if err != nil { + return fmt.Errorf("Error unmarshalling property %s: %w", component.Identifier(), err) + } + + t.value = s + + for _, v := range component.Validators() { + if err := v(s); err != nil { + return fmt.Errorf("%s: %w", component.Identifier(), err) + } + } + + if tc, ok := component.(Int64Component); ok { + for _, v := range tc.Int64Validators { + if err := v(s); err != nil { + return fmt.Errorf("%s: %w", component.Identifier(), err) + } + } + } + + return nil +} + +type Int64Validator func(value any) error +type Int64ComponentConfig struct { + Validators []Int64Validator +} +type Int64ComponentOption func(*Int64ComponentConfig) diff --git a/internal/block/int64_component/validators/max.go b/internal/block/int64_component/validators/max.go new file mode 100644 index 0000000..2ba7c61 --- /dev/null +++ b/internal/block/int64_component/validators/max.go @@ -0,0 +1,21 @@ +package int64_component_validators + +import ( + "blocky/internal/block/int64_component" + "fmt" +) + +func Max(max int64) int64_component.Int64ComponentOption { + return func(c *int64_component.Int64ComponentConfig) { + c.Validators = append(c.Validators, func(value any) error { + s, ok := value.(int64) + if !ok { + return fmt.Errorf("provided value bust be an int: %v", value) + } + if s > max { + return fmt.Errorf("int must be %d or less", max) + } + return nil + }) + } +} diff --git a/internal/block/number_component.go b/internal/block/number_component.go deleted file mode 100644 index 72f2de0..0000000 --- a/internal/block/number_component.go +++ /dev/null @@ -1,54 +0,0 @@ -package block - -import ( - "blocky/internal/block/validation" - "encoding/json" -) - -type NumberComponent struct { - identifier string - name string - validators []validation.Validator -} - -func (t NumberComponent) Type() ComponentType { - return NumberComponentType -} - -func (t NumberComponent) Name() string { - return t.name -} - -func (t NumberComponent) Identifier() string { - return t.identifier -} - -func (t NumberComponent) Validators() []validation.Validator { - return t.validators -} - -func NewNumberComponent(identifier, name string, opts ...validation.ComponentOption) NumberComponent { - cfg := &validation.ComponentConfig{} - for _, opt := range opts { - opt(cfg) - } - return NumberComponent{identifier: identifier, name: name, validators: cfg.Validators} -} - -func (t NumberComponent) NewInstance() ComponentInstance { - return &NumberComponentInstance{} -} - -type NumberComponentInstance struct { - value int64 -} - -func (t *NumberComponentInstance) FromJSON(component Component, data json.RawMessage) error { - var s int64 - err := json.Unmarshal(data, &s) - if err != nil { - return err - } - t.value = s - return nil -} diff --git a/internal/block/text_component/text_component.go b/internal/block/text_component/text_component.go index 7dbef60..6de02cf 100644 --- a/internal/block/text_component/text_component.go +++ b/internal/block/text_component/text_component.go @@ -52,13 +52,20 @@ type TextComponentInstance struct { value string } +func (t *TextComponentInstance) Value() interface{} { + return t.value +} + func (t *TextComponentInstance) FromJSON(component block.Component, data json.RawMessage) error { var s string - err := json.Unmarshal(data, &s) - if err != nil { - return err + + if data != nil { + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + t.value = s } - t.value = s for _, v := range component.Validators() { if err := v(s); err != nil { @@ -81,5 +88,4 @@ type TextValidator func(value any) error type TextComponentConfig struct { Validators []TextValidator } - type TextComponentOption func(*TextComponentConfig) diff --git a/main.go b/main.go index b6acfed..9f1ad5b 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,8 @@ package main import ( "blocky/internal/block" + "blocky/internal/block/int64_component" + int64_component_validators "blocky/internal/block/int64_component/validators" "blocky/internal/block/text_component" text_component_validators "blocky/internal/block/text_component/validators" "blocky/internal/block/validation" @@ -9,31 +11,32 @@ import ( ) func main() { + b := &block.Block{} textComponent := text_component.NewTextComponent( "title", "Title", - // validation.Required(), - // validation.MaxLength(4), - // nil, []validation.ComponentOption{ validation.Required(), - validation.MaxLength(4), }, []text_component.TextComponentOption{ text_component_validators.Regex("^\\d+$"), }, ) - - b := &block.Block{} b.Components = append(b.Components, textComponent) - fmt.Println(textComponent.Name(), textComponent.Type()) - numberComponent := block.NewNumberComponent("age", "Age") - b.Components = append(b.Components, numberComponent) + int64Component := int64_component.NewInt64Component( + "year", + "Year", + []validation.ComponentOption{}, + []int64_component.Int64ComponentOption{ + int64_component_validators.Max(4), + }, + ) + b.Components = append(b.Components, int64Component) - data := []byte(`{"title": "252", "age": 25 }`) - // data := []byte(`{"title": "this is the title", "age": 25 }`) + data := []byte(`{"title": "252", "year": 2 }`) + // data := []byte(`{"year": 2}`) instance := &block.BlockInstance{} err := instance.FromJSON(b, data) if err != nil {