Skip to content
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
15 changes: 15 additions & 0 deletions optional/string.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package optional

import "encoding/json"

// String represents an optional string value.
type String struct {
value string
Expand All @@ -19,6 +21,19 @@ func (s String) Present() bool {
return s.present
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (s *String) UnmarshalJSON(data []byte) error {
var v *string
if err := json.Unmarshal(data, &v); err != nil {
return err
}
if v != nil && *v != "" {
s.value = *v
s.present = true
}
return nil
}

// Value returns the value of the optional string.
func (s String) Value() string {
return s.value
Expand Down
13 changes: 9 additions & 4 deletions schema/characteristics.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,20 @@ import (
)

func checkAttributeName(name string) {
// starts w/ a A-Za-z followed by a A-Za-z0-9, a dollar sign, a hyphen or an underscore
match, err := regexp.MatchString(`^[A-Za-z][\w$-]*$`, name)
if err != nil {
if err := validateAttributeName(name); err != nil {
panic(err)
}
}

func validateAttributeName(name string) error {
match, err := regexp.MatchString(`^[A-Za-z][\w$-]*$`, name)
if err != nil {
return err
}
if !match {
panic(fmt.Sprintf("invalid attribute name %q", name))
return fmt.Errorf("invalid attribute name %q", name)
}
return nil
}

// AttributeDataType is a single keyword indicating the derived data type from JSON.
Expand Down
57 changes: 33 additions & 24 deletions schema/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,9 @@ type CoreAttribute struct {
func ComplexCoreAttribute(params ComplexParams) CoreAttribute {
checkAttributeName(params.Name)

names := map[string]int{}
var sa []CoreAttribute

for i, a := range params.SubAttributes {
name := strings.ToLower(a.name)
if j, ok := names[name]; ok {
panic(fmt.Errorf("duplicate name %q for sub-attributes %d and %d", name, i, j))
}

names[name] = i

sa = append(sa, CoreAttribute{
canonicalValues: a.canonicalValues,
caseExact: a.caseExact,
description: a.description,
multiValued: a.multiValued,
mutability: a.mutability,
name: a.name,
referenceTypes: a.referenceTypes,
required: a.required,
returned: a.returned,
typ: a.typ,
uniqueness: a.uniqueness,
})
sa, err := buildSubAttributes(params.SubAttributes)
if err != nil {
panic(err)
}

return CoreAttribute{
Expand Down Expand Up @@ -103,6 +82,36 @@ func SimpleCoreAttribute(params SimpleParams) CoreAttribute {
}
}

func buildSubAttributes(subAttributes []SimpleParams) ([]CoreAttribute, error) {
names := map[string]int{}
var sa []CoreAttribute

for i, a := range subAttributes {
name := strings.ToLower(a.name)
if j, ok := names[name]; ok {
return nil, fmt.Errorf("duplicate name %q for sub-attributes %d and %d", name, i, j)
}

names[name] = i

sa = append(sa, CoreAttribute{
canonicalValues: a.canonicalValues,
caseExact: a.caseExact,
description: a.description,
multiValued: a.multiValued,
mutability: a.mutability,
name: a.name,
referenceTypes: a.referenceTypes,
required: a.required,
returned: a.returned,
typ: a.typ,
uniqueness: a.uniqueness,
})
}

return sa, nil
}

// AttributeType returns the attribute type.
func (a CoreAttribute) AttributeType() string {
return a.typ.String()
Expand Down
Loading
Loading