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

Support readOnly / writeOnly. #81

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
20 changes: 20 additions & 0 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,21 @@ func (g *Generator) processObject(name string, schema *Schema) (typ string, err
if err != nil {
return "", err
}

access := Access_RW
if prop.ReadOnly {
access = Access_RO
} else if prop.WriteOnly {
access = Access_WO
}

f := Field{
Name: fieldName,
JSONName: propKey,
Type: fieldType,
Required: contains(schema.Required, propKey),
Description: prop.Description,
Access: access,
}
if f.Required {
strct.GenerateCode = true
Expand Down Expand Up @@ -384,6 +393,14 @@ type Struct struct {
AdditionalType string
}

type Access int

const (
Access_RW Access = iota
Access_RO
Access_WO
)

// Field defines the data required to generate a field in Go.
type Field struct {
// The golang name, e.g. "Address1"
Expand All @@ -395,5 +412,8 @@ type Field struct {
Type string
// Required is set to true when the field is required.
Required bool
// Access type, either R/W (default), R/O, or W/O.
Access Access

Description string
}
5 changes: 5 additions & 0 deletions jsonschema.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ type Schema struct {
// "additionalProperties": false
AdditionalPropertiesBool *bool `json:"-"`

// ReadOnly and WriteOnly specify access to a field.
// https://json-schema.org/draft-07/json-schema-validation.html#rfc.section.10.3
ReadOnly bool
WriteOnly bool

AnyOf []*Schema
AllOf []*Schema
OneOf []*Schema
Expand Down
13 changes: 12 additions & 1 deletion output.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,23 @@ func Output(w io.Writer, g *Generator, pkg string) {
if f.Required {
omitempty = ""
}
schemaTags := []string{}
if f.Access == Access_RO {
schemaTags = append(schemaTags, "readonly")
} else if f.Access == Access_WO {
schemaTags = append(schemaTags, "writeonly")
}

schemaTag := ""
if len(schemaTags) > 0 {
schemaTag = fmt.Sprintf(" jsonSchema:\"%s\"", strings.Join(schemaTags, ","))
}

if f.Description != "" {
outputFieldDescriptionComment(f.Description, w)
}

fmt.Fprintf(w, " %s %s `json:\"%s%s\"`\n", f.Name, f.Type, f.JSONName, omitempty)
fmt.Fprintf(w, " %s %s `json:\"%s%s\"%s`\n", f.Name, f.Type, f.JSONName, omitempty, schemaTag)
}

fmt.Fprintln(w, "}")
Expand Down
8 changes: 8 additions & 0 deletions test/example1.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
},
"minItems": 1,
"uniqueItems": true
},
"inStock": {
"type": "boolean",
"readOnly": true
},
"couponCode": {
"type": "string",
"writeOnly": true
}
},
"required": [
Expand Down
25 changes: 24 additions & 1 deletion test/example1_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package test

import (
"strings"
"encoding/json"
"testing"
"github.com/a-h/generate/test/example1_gen"
"reflect"
"testing"
)

func TestExample1(t *testing.T) {
Expand Down Expand Up @@ -45,3 +47,24 @@ func TestExample1(t *testing.T) {
}
}
}

func TestExample1Access(t *testing.T) {
fs := reflect.VisibleFields(reflect.TypeOf(example1.Product{}))
for _, f := range fs {
if f.Name == "CouponCode" {
if v, ok := f.Tag.Lookup("jsonSchema"); !ok {
t.Fatal("Expected CouponCode field to have jsonSchema tag")
} else if !strings.Contains(v, "writeonly") {
t.Fatalf("CouponCode's json %q doesn't specify writeonly", v)
}
}

if f.Name == "InStock" {
if v, ok := f.Tag.Lookup("jsonSchema"); !ok {
t.Fatal("Expected InStock field to have jsonSchema tag")
} else if !strings.Contains(v, "readonly") {
t.Fatalf("InStock's json %q doesn't specify readonly", v)
}
}
}
}