Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored namespaces to use maps of objects #89

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions schema/any.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func NewAnySchema() *AnySchema {

// AnySchema is a wildcard allowing maps, lists, integers, strings, bools. and floats.
type AnySchema struct {
ScalarType
}

func (a *AnySchema) ReflectedType() reflect.Type {
Expand Down Expand Up @@ -87,13 +88,6 @@ func (a *AnySchema) Serialize(data any) (any, error) {
return a.checkAndConvert(data)
}

func (a *AnySchema) ApplyScope(_ Scope, _ string) {}

func (a *AnySchema) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (a *AnySchema) TypeID() TypeID {
return TypeIDAny
}
Expand Down
8 changes: 1 addition & 7 deletions schema/bool.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func NewBoolSchema() *BoolSchema {

// BoolSchema holds the schema information for boolean types.
type BoolSchema struct {
ScalarType
}

func (b BoolSchema) Unserialize(data any) (any, error) {
Expand Down Expand Up @@ -121,13 +122,6 @@ func (b BoolSchema) SerializeType(data bool) (any, error) {
return b.Serialize(data)
}

func (b BoolSchema) ApplyScope(_ Scope, _ string) {}

func (b BoolSchema) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (b BoolSchema) TypeID() TypeID {
return TypeIDBool
}
Expand Down
14 changes: 6 additions & 8 deletions schema/bool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,17 +186,15 @@ func TestBoolSerializationCycle(t *testing.T) {
}

func TestBoolJSONMarshal(t *testing.T) {
j, err := json.Marshal(schema.NewBoolSchema())
if err != nil {
t.Fatal(err)
}
boolType := schema.NewBoolSchema()
//nolint:staticcheck
j, err := json.Marshal(boolType)
assert.NoError(t, err)
if string(j) != "{}" {
t.Fatalf("Unexpected JSON output: %s", j)
}
boolType := schema.NewBoolSchema()
if err := json.Unmarshal(j, &boolType); err != nil {
t.Fatal(err)
}
//nolint:staticcheck
assert.NoError(t, json.Unmarshal(j, boolType))
}

func TestBoolSchema(t *testing.T) {
Expand Down
8 changes: 1 addition & 7 deletions schema/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,14 @@ type Enum[T enumValue] interface {
}

type EnumSchema[T enumValue] struct {
ScalarType
ValidValuesMap map[T]*DisplayValue `json:"values"`
}

func (e EnumSchema[T]) ValidValues() map[T]*DisplayValue {
return e.ValidValuesMap
}

func (e EnumSchema[T]) ApplyScope(_ Scope, _ string) {}

func (e EnumSchema[T]) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (e EnumSchema[T]) ReflectedType() reflect.Type {
var defaultValue T
return reflect.TypeOf(defaultValue)
Expand Down
2 changes: 1 addition & 1 deletion schema/enum_int.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "fmt"
func NewIntEnumSchema(validValues map[int64]*DisplayValue, units *UnitsDefinition) *IntEnumSchema {
return &IntEnumSchema{
EnumSchema[int64]{
validValues,
ValidValuesMap: validValues,
},
units,
}
Expand Down
2 changes: 1 addition & 1 deletion schema/enum_string.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "fmt"
func NewStringEnumSchema(validValues map[string]*DisplayValue) *StringEnumSchema {
return &StringEnumSchema{
EnumSchema[string]{
validValues,
ValidValuesMap: validValues,
},
}
}
Expand Down
13 changes: 4 additions & 9 deletions schema/float.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@ type Float interface {
// NewFloatSchema creates a new float schema from the specified values.
func NewFloatSchema(min *float64, max *float64, units *UnitsDefinition) *FloatSchema {
return &FloatSchema{
min,
max,
units,
MinValue: min,
MaxValue: max,
UnitsValue: units,
}
}

type FloatSchema struct {
ScalarType
MinValue *float64 `json:"min"`
MaxValue *float64 `json:"max"`
UnitsValue *UnitsDefinition `json:"units"`
Expand All @@ -51,12 +52,6 @@ func (f FloatSchema) Max() *float64 {
func (f FloatSchema) Units() *UnitsDefinition {
return f.UnitsValue
}
func (f FloatSchema) ApplyScope(_ Scope, _ string) {}

func (f FloatSchema) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (f FloatSchema) Unserialize(data any) (any, error) {
unserialized, err := floatInputMapper(data, f.UnitsValue)
Expand Down
15 changes: 5 additions & 10 deletions schema/int.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
// configuration but cannot serialize, unserialize or validate. For that functionality please use IntType.
type Int interface {
TypedType[int64]
ScalarType
Min() *int64
Max() *int64
Units() *UnitsDefinition
Expand All @@ -19,13 +20,14 @@ type Int interface {
// NewIntSchema creates a new integer schema with the specified values.
func NewIntSchema(min *int64, max *int64, units *UnitsDefinition) *IntSchema {
return &IntSchema{
min,
max,
units,
MinValue: min,
MaxValue: max,
UnitsValue: units,
}
}

type IntSchema struct {
ScalarType
MinValue *int64 `json:"min"`
MaxValue *int64 `json:"max"`
UnitsValue *UnitsDefinition `json:"units"`
Expand All @@ -35,13 +37,6 @@ func (i IntSchema) ReflectedType() reflect.Type {
return reflect.TypeOf(int64(0))
}

func (i IntSchema) ApplyScope(_ Scope, _ string) {}

func (i IntSchema) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (i IntSchema) TypeID() TypeID {
return TypeIDInt
}
Expand Down
4 changes: 2 additions & 2 deletions schema/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func (l AbstractListSchema[ItemType]) Max() *int64 {
return l.MaxValue
}

func (l AbstractListSchema[ItemType]) ApplyScope(scope Scope, namespace string) {
l.ItemsValue.ApplyScope(scope, namespace)
func (l AbstractListSchema[ItemType]) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
l.ItemsValue.ApplyNamespace(objects, namespace)
}

func (l AbstractListSchema[ItemType]) ValidateReferences() error {
Expand Down
6 changes: 3 additions & 3 deletions schema/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ func (m MapSchema[K, V]) Max() *int64 {
return m.MaxValue
}

func (m MapSchema[K, V]) ApplyScope(scope Scope, namespace string) {
m.KeysValue.ApplyScope(scope, namespace)
m.ValuesValue.ApplyScope(scope, namespace)
func (m MapSchema[K, V]) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
m.KeysValue.ApplyNamespace(objects, namespace)
m.ValuesValue.ApplyNamespace(objects, namespace)
}

func (m MapSchema[K, V]) ValidateReferences() error {
Expand Down
4 changes: 2 additions & 2 deletions schema/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ func (o *ObjectSchema) GetDefaults() map[string]any {
return o.defaultValues
}

func (o *ObjectSchema) ApplyScope(scope Scope, namespace string) {
func (o *ObjectSchema) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
for _, property := range o.PropertiesValue {
property.ApplyScope(scope, namespace)
property.ApplyNamespace(objects, namespace)
}
}

Expand Down
2 changes: 1 addition & 1 deletion schema/object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ func TestObjectSchema_ValidateCompatibility(t *testing.T) {
assert.Error(t, testStructSchema.ValidateCompatibility(testOptionalFieldSchema)) // Not the same
// Schema validation with ref
objectTestRef := schema.NewRefSchema("testStruct", nil)
objectTestRef.ApplyScope(testStructScope, schema.DEFAULT_NAMESPACE)
objectTestRef.ApplyNamespace(testStructScope.Objects(), schema.SelfNamespace)
webbnh marked this conversation as resolved.
Show resolved Hide resolved
assert.NoError(t, objectTestRef.ValidateCompatibility(testStructSchema))
assert.NoError(t, testStructSchema.ValidateCompatibility(objectTestRef))
// Schema validation with scope
Expand Down
4 changes: 2 additions & 2 deletions schema/oneof.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func (o OneOfSchema[KeyType]) DiscriminatorFieldName() string {
return o.DiscriminatorFieldNameValue
}

func (o OneOfSchema[KeyType]) ApplyScope(scope Scope, namespace string) {
func (o OneOfSchema[KeyType]) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
for _, t := range o.TypesValue {
t.ApplyScope(scope, namespace)
t.ApplyNamespace(objects, namespace)
}
// scope must be applied before we can access the subtypes' properties
err := o.validateSubtypeDiscriminatorInlineFields()
Expand Down
2 changes: 1 addition & 1 deletion schema/oneof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func Test_OneOf_ConstructorBypass(t *testing.T) { //nolint:funlen

scopeAny := assert.NoErrorR[any](t)(schema.DescribeScope().Unserialize(input_schema))
scopeSchemaTyped := scopeAny.(*schema.ScopeSchema)
scopeSchemaTyped.ApplyScope(scopeSchemaTyped, schema.DEFAULT_NAMESPACE)
scopeSchemaTyped.ApplySelf()
assert.NoError(t, scopeSchemaTyped.Validate(input_data_fullname))
unserialized := assert.NoErrorR[any](t)(scopeSchemaTyped.Unserialize(input_data_fullname))
serialized := assert.NoErrorR[any](t)(scopeSchemaTyped.Serialize(unserialized))
Expand Down
8 changes: 1 addition & 7 deletions schema/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,13 @@ func NewPatternSchema() *PatternSchema {
}

type PatternSchema struct {
ScalarType
}

func (p PatternSchema) TypeID() TypeID {
return TypeIDPattern
}

func (p PatternSchema) ApplyScope(_ Scope, _ string) {}

func (p PatternSchema) ValidateReferences() error {
// No references in this type. No work to do.
return nil
}

func (p PatternSchema) ReflectedType() reflect.Type {
return reflect.TypeOf(&regexp.Regexp{})
}
Expand Down
4 changes: 2 additions & 2 deletions schema/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ func (p *PropertySchema) Examples() []string {
return p.ExamplesValue
}

func (p *PropertySchema) ApplyScope(scope Scope, namespace string) {
p.TypeValue.ApplyScope(scope, namespace)
func (p *PropertySchema) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
p.TypeValue.ApplyNamespace(objects, namespace)
}

func (p *PropertySchema) ValidateReferences() error {
Expand Down
15 changes: 7 additions & 8 deletions schema/ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

// Ref holds the definition of a reference to a scope-wide object. The ref must always be inside a scope,
// either directly or indirectly. If several scopes are embedded within each other, the Ref references the object
// in the scope specified. DEFAULT_NAMESPACE for current scope.
// in the scope specified. SelfNamespace refers to the current scope.
type Ref interface {
Object

Expand All @@ -20,7 +20,7 @@ type Ref interface {

// NewRefSchema creates a new reference to an object in a wrapping Scope by ID.
func NewRefSchema(id string, display Display) *RefSchema {
return NewNamespacedRefSchema(id, DEFAULT_NAMESPACE, display)
return NewNamespacedRefSchema(id, SelfNamespace, display)
}

// NewNamespacedRefSchema creates a new reference to an object in a wrapping Scope by ID and namespace.
Expand Down Expand Up @@ -105,13 +105,12 @@ func (r *RefSchema) Display() Display {
return r.DisplayValue
}

// ApplyScope links the reference to the object if the given namespace
// ApplyNamespace links the reference to the object if the given namespace
// matches the ref's namespace. Other namespaces are skipped.
func (r *RefSchema) ApplyScope(scope Scope, namespace string) {
func (r *RefSchema) ApplyNamespace(objects map[string]*ObjectSchema, namespace string) {
if namespace != r.ObjectNamespace {
return // The scope does not apply to this reference.
return // This reference does not refer to an object in the supplied namespace.
}
objects := scope.Objects()
referencedObject, ok := objects[r.IDValue]
if !ok {
availableObjects := ""
Expand All @@ -129,8 +128,8 @@ func (r *RefSchema) ValidateReferences() error {
if r.referencedObjectCache != nil {
return nil // Success
}
// The only way, unless there is a bug, for it to get here is if ApplyScope was not called with the
// correct namespace, or if the code disregards the error returned by ApplyScope. ApplyScope should
// The only way, unless there is a bug, for it to get here is if ApplyNamespace was not called with the
// correct namespace, or if the code disregards the error returned by ApplyNamespace. ApplyNamespace should
// always set referencedObjectCache or return an error if the correct namespace is applied.
return BadArgumentError{
Message: fmt.Sprintf(
Expand Down
6 changes: 3 additions & 3 deletions schema/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ func (s SchemaSchema) Steps() map[string]Step {
return result
}

func (s SchemaSchema) applyScope() {
func (s SchemaSchema) applyNamespace() {
for _, step := range s.StepsValue {
// We can apply an empty scope because the scope does not need another scope.
step.InputValue.ApplyScope(nil, DEFAULT_NAMESPACE)
step.InputValue.ApplySelf()
for _, output := range step.OutputsValue {
output.ApplyScope(nil, DEFAULT_NAMESPACE)
output.Schema().ApplySelf()
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions schema/schema_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ var basicObjects = []*ObjectSchema{
nil,
nil,
nil,
PointerTo(DEFAULT_NAMESPACE),
PointerTo(SelfNamespace),
nil,
),
"display": displayProperty,
Expand Down Expand Up @@ -1313,6 +1313,6 @@ func UnserializeSchema(data any) (*SchemaSchema, error) {
return nil, err
}
result := s.(*SchemaSchema)
result.applyScope()
result.applyNamespace()
return result, nil
}
Loading