1package respjson
2
3// A Field provides metadata to indicate the presence of a value.
4//
5// Use [Field.Valid] to check if an optional value was null or omitted.
6//
7// A Field will always occur in the following structure, where it
8// mirrors the original field in it's parent struct:
9//
10// type ExampleObject struct {
11// Foo bool `json:"foo"`
12// Bar int `json:"bar"`
13// // ...
14//
15// // JSON provides metadata about the object.
16// JSON struct {
17// Foo Field
18// Bar Field
19// // ...
20// } `json:"-"`
21// }
22//
23// To differentiate a "nullish" value from the zero value,
24// use the [Field.Valid] method.
25//
26// if !example.JSON.Foo.Valid() {
27// println("Foo is null or omitted")
28// }
29//
30// if example.Foo {
31// println("Foo is true")
32// } else {
33// println("Foo is false")
34// }
35//
36// To differentiate if a field was omitted or the JSON value "null",
37// use the [Field.Raw] method.
38//
39// if example.JSON.Foo.Raw() == "null" {
40// println("Foo is null")
41// }
42//
43// if example.JSON.Foo.Raw() == "" {
44// println("Foo was omitted")
45// }
46//
47// Otherwise, if the field was invalid and couldn't be marshalled successfully,
48// [Field.Valid] will be false and [Field.Raw] will not be empty.
49type Field struct {
50 status
51 raw string
52}
53
54const (
55 omitted status = iota
56 null
57 invalid
58 valid
59)
60
61type status int8
62
63// Valid returns true if the parent field was set.
64// Valid returns false if the value doesn't exist, is JSON null, or
65// is an unexpected type.
66func (j Field) Valid() bool { return j.status > invalid }
67
68const Null string = "null"
69const Omitted string = ""
70
71// Returns the raw JSON value of the field.
72func (j Field) Raw() string {
73 if j.status == omitted {
74 return ""
75 }
76 return j.raw
77}
78
79func NewField(raw string) Field {
80 if raw == "null" {
81 return Field{status: null, raw: Null}
82 }
83 return Field{status: valid, raw: raw}
84}
85
86func NewInvalidField(raw string) Field {
87 return Field{status: invalid, raw: raw}
88}