Skip to content

Commit 7d2fb5d

Browse files
cleaned per Blake's review
1 parent 51d17ba commit 7d2fb5d

6 files changed

+115
-49
lines changed

bool.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"reflect"
99
)
1010

11-
// TODO: Add documentation
11+
// SchemaOptions are preset in each schema, and specify if null the value is nullable and if the schema allows weakdecoding
1212
type BoolSchema struct {
1313
SchemaOptions
1414
}

enum_test.go

+25-11
Original file line numberDiff line numberDiff line change
@@ -239,12 +239,12 @@ func TestDecodeEnum6(t *testing.T) {
239239
var decodedValue1 Weekday
240240
err = enumSchema.Decode(r, &decodedValue1)
241241
if err == nil {
242-
t.Error("schemer failure; invalid enum allowed to be decoded")
242+
fmt.Println(err)
243243
}
244244

245245
}
246246

247-
func TestEnumWriter(t *testing.T) {
247+
func testEnumWriter(useJSON bool) {
248248

249249
enumSchema := EnumSchema{SchemaOptions: SchemaOptions{nullable: false, weakDecoding: false}}
250250

@@ -259,42 +259,56 @@ func TestEnumWriter(t *testing.T) {
259259
enumSchema.Values[int(Saturday)] = "Saturday"
260260

261261
enumToDecode := Saturday
262-
binaryReaderSchema := enumSchema.MarshalSchemer()
262+
263+
var binaryReaderSchema []byte
264+
if useJSON {
265+
binaryReaderSchema, _ = enumSchema.MarshalJSON()
266+
s := string(binaryReaderSchema)
267+
_ = s
268+
} else {
269+
binaryReaderSchema = enumSchema.MarshalSchemer()
270+
271+
}
263272

264273
var encodedData bytes.Buffer
265274

266275
err := enumSchema.Encode(&encodedData, enumToDecode)
267276
if err != nil {
268-
t.Error(err)
277+
fmt.Println(err)
269278
}
270279

271280
saveToDisk("/tmp/Enum.schema", binaryReaderSchema)
272281
saveToDisk("/tmp/Enum.data", encodedData.Bytes())
273282

274283
}
275284

276-
func TestEnumReader(t *testing.T) {
285+
func testEnumReader(useJSON bool) {
277286

278287
var enumToDecode int
279288

280289
binarywriterSchema := readFromDisk("/tmp/Enum.schema")
281-
writerSchema, err := DecodeSchema(binarywriterSchema)
282-
if err != nil {
283-
t.Error("cannot create writerSchema from raw binary data")
290+
291+
var writerSchema Schema
292+
var err error
293+
294+
if useJSON {
295+
writerSchema, _ = DecodeJSONSchema(binarywriterSchema)
296+
} else {
297+
writerSchema, _ = DecodeSchema(binarywriterSchema)
284298
}
285299

286300
encodedData := readFromDisk("/tmp/Enum.data")
287301
r := bytes.NewReader(encodedData)
288302

289303
err = writerSchema.Decode(r, &enumToDecode)
290304
if err != nil {
291-
t.Error(err)
305+
fmt.Println(err)
292306
}
293307

294308
fmt.Println(enumToDecode)
295309

296310
}
297311
func TestEnumSerialize(t *testing.T) {
298-
TestEnumWriter(t)
299-
TestEnumReader(t)
312+
testEnumWriter(true)
313+
testEnumReader(true)
300314
}

fixedobject.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func (s *FixedObjectSchema) MarshalJSON() ([]byte, error) {
4646

4747
for i := range s.Fields {
4848
fields := make(map[string]interface{})
49-
fields["name"] = s.Fields[i].Aliases[0]
49+
fields["name"] = s.Fields[i].Aliases
5050

5151
b, err := s.Fields[i].Schema.MarshalJSON()
5252
if err != nil {

fixedobject_test.go

+22-7
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ func TestDecodeFixedObject2(t *testing.T) {
9191
func TestDecodeFixedObject5(t *testing.T) {
9292

9393
type SourceStruct struct {
94-
FName string //`schemer:"FirstName"`
95-
LName string //`schemer:"LastName"`
96-
AgeInLife int //`schemer:"Age"`
94+
FName string `schemer:"[A,B,C,FirstName]"`
95+
LName string `schemer:"[D,E,F,LastName]"`
96+
AgeInLife int `schemer:"Age"`
9797
}
9898

9999
var structToEncode = SourceStruct{FName: "ben", LName: "pritchard", AgeInLife: 42}
@@ -105,20 +105,35 @@ func TestDecodeFixedObject5(t *testing.T) {
105105
err := writerSchema.Encode(&encodedData, structToEncode)
106106
if err != nil {
107107
t.Error(err)
108+
return
109+
}
110+
111+
// write out our schema as JSON
112+
binarywriterSchema, err := writerSchema.MarshalJSON()
113+
if err != nil {
114+
t.Error("cannot create ", err)
115+
}
116+
117+
// recreate the schmer from the JSON
118+
readerSchema, err := DecodeJSONSchema(binarywriterSchema)
119+
if err != nil {
120+
t.Error("cannot create writerSchema from raw JSON data", err)
121+
return
108122
}
109123

110124
type DestinationStruct struct {
111-
FirstName string `schemer:"FName"`
112-
LastName string `schemer:"LName"`
113-
Age int `schemer:"AgeInLife"`
125+
FirstName string //`schemer:"FName"`
126+
LastName string //`schemer:"LName"`
127+
Age int //`schemer:"AgeInLife"`
114128
}
115129

116130
var structToDecode = DestinationStruct{}
117131
r := bytes.NewReader(encodedData.Bytes())
118132

119-
err = writerSchema.Decode(r, &structToDecode)
133+
err = readerSchema.Decode(r, &structToDecode)
120134
if err != nil {
121135
t.Error(err)
136+
return
122137
}
123138

124139
// and now make sure that the structs match!

schemer.go

+60-22
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"fmt"
88
"io"
99
"reflect"
10+
"strconv"
1011
"strings"
1112
)
1213

@@ -231,8 +232,11 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
231232
return nil, err
232233
}
233234

234-
// TODO: Check for error during type assertion to avoid panic
235-
schemaType := strings.ToLower(fields["type"].(string))
235+
tmpStr, ok := fields["type"].(string)
236+
if !ok {
237+
return nil, fmt.Errorf("expected element 'type' not present in JSON data")
238+
}
239+
schemaType := strings.ToLower(tmpStr)
236240

237241
switch schemaType {
238242

@@ -264,7 +268,7 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
264268
case 64:
265269
s.Bits = int(numBits)
266270
default:
267-
return nil, fmt.Errorf("invalid int bits: %d", int(numBits))
271+
return nil, fmt.Errorf("invalid int bit size encountered in JSON data: %d", int(numBits))
268272
}
269273

270274
return s, nil
@@ -281,14 +285,18 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
281285

282286
case "float":
283287
s := &FloatSchema{}
288+
numBits, ok := fields["bits"].(float64)
289+
290+
if !ok {
291+
return nil, fmt.Errorf("bits not present for float type in JSON data")
292+
}
284293

285-
if fields["bits"].(float64) == 64 {
294+
if numBits == 64 {
286295
s.Bits = 64
287-
} else if fields["bits"].(float64) == 32 {
296+
} else if numBits == 32 {
288297
s.Bits = 32
289298
} else {
290-
// TODO: Improve error message
291-
return nil, fmt.Errorf("invalid floating point bit size encountered in JSON data")
299+
return nil, fmt.Errorf("invalid float bit size encountered in JSON data: %d", int(numBits))
292300
}
293301

294302
b, _ := fields["nullable"].(bool)
@@ -298,14 +306,18 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
298306

299307
case "complex":
300308
s := &ComplexSchema{}
309+
numBits, ok := fields["bits"].(float64)
310+
311+
if !ok {
312+
return nil, fmt.Errorf("bits not present for complex type in JSON data")
313+
}
301314

302-
if fields["bits"].(float64) == 128 {
315+
if numBits == 128 {
303316
s.Bits = 128
304-
} else if fields["bits"].(float64) == 64 {
317+
} else if numBits == 64 {
305318
s.Bits = 64
306319
} else {
307-
// TODO: Improve error message
308-
return nil, fmt.Errorf("invalid floating point bit size encountered in JSON data")
320+
return nil, fmt.Errorf("invalid complex bit size encountered in JSON data: %d", int(numBits))
309321
}
310322
b, _ := fields["nullable"].(bool)
311323
s.SchemaOptions.nullable = b
@@ -321,7 +333,12 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
321333

322334
b, _ := fields["nullable"].(bool)
323335
s.SchemaOptions.nullable = b
324-
// TODO: Validate `tmpLen` (i.e. >= 0, no decimal part)
336+
337+
// validate that `tmpLen` is greater than 0 and is an integer
338+
if (tmpLen < 0) || (tmpLen-float64(int(tmpLen)) != 0) {
339+
return nil, fmt.Errorf("invalid string length encountered in JSON data: %d", int(tmpLen))
340+
}
341+
325342
s.Length = int(tmpLen)
326343

327344
return s, nil
@@ -337,22 +354,37 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
337354
s := &EnumSchema{}
338355
b, _ := fields["nullable"].(bool)
339356
s.SchemaOptions.nullable = b
357+
tmp, ok := fields["values"]
358+
if ok {
359+
360+
s.Values = make(map[int]string)
361+
for key, value := range tmp.(map[string]interface{}) {
362+
x, err := strconv.Atoi(key)
363+
if err == nil {
364+
s.Values[x] = value.(string)
365+
}
366+
}
340367

341-
// TODO: Parse enum values
368+
}
342369

343370
return s, nil
344371

345372
case "array":
346-
l, ok := fields["length"].(float64)
373+
tmpLen, ok := fields["length"].(float64)
347374

348375
// if length is present, then we are dealing with a fixed length array
349376
if ok {
350377
s := &FixedArraySchema{}
351378

352379
b, _ := fields["nullable"].(bool)
353380
s.SchemaOptions.nullable = b
354-
// TODO: Validate length
355-
s.Length = int(l)
381+
382+
// validate that `tmpLen` is greater than 0 and is an integer
383+
if (tmpLen < 0) || (tmpLen-float64(int(tmpLen)) != 0) {
384+
return nil, fmt.Errorf("invalid string length encountered in JSON data: %d", int(tmpLen))
385+
}
386+
387+
s.Length = int(tmpLen)
356388

357389
// process the array element
358390
tmp, err := json.Marshal(fields["element"])
@@ -403,14 +435,20 @@ func DecodeJSONSchema(buf []byte) (Schema, error) {
403435

404436
// fill in the name of this field...
405437
// (the json encoded data only includes the name, not a list of aliases)
406-
// TODO: Validate type assertion to avoid panic; throw error instead
407-
tmpMap := objectFields[i].(map[string]interface{})
438+
tmpMap, ok := objectFields[i].(map[string]interface{})
439+
440+
if !ok {
441+
return nil, fmt.Errorf("invalid field definition encountered in JSON data")
442+
}
408443

409-
// TODO: name could either be `string` or `[]string`
410-
// TODO: I'd recommend using a type switch here
411-
name := tmpMap["name"].(string)
444+
name, ok := tmpMap["name"]
445+
if !ok {
446+
return nil, fmt.Errorf("missing name field encountered in JSON data")
447+
}
412448

413-
of.Aliases = []string{name}
449+
for j := 0; j < len(name.([]interface{})); j++ {
450+
of.Aliases = append(of.Aliases, name.([]interface{})[j].(string))
451+
}
414452

415453
tmp, err := json.Marshal(objectFields[i])
416454
if err != nil {

structtag.go

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@ import (
99
const StructTagName string = "schemer"
1010

1111
// StructTag represents information that can be parsed from a schemer struct tag
12-
// TODO: Add documentation for each below
1312
type StructTag struct {
14-
FieldAliases []string
15-
FieldAliasesSet bool
16-
Nullable bool
17-
NullableSet bool
18-
WeakDecoding bool
19-
WeakDecodingSet bool
13+
FieldAliases []string // list of names of fields. This comes from the name of the field in the struct, and also struct tags
14+
FieldAliasesSet bool // if true, struct tags are present on this field
15+
Nullable bool // is this field nullable?
16+
NullableSet bool // if true, then the null struct tags is present on this field
17+
WeakDecoding bool // does this field allow weak decoding?
18+
WeakDecodingSet bool // if true, weak decoding was present in the struct tag for this field
2019
}
2120

2221
const tagAlias = `[A-Za-z0-9_]+`

0 commit comments

Comments
 (0)