Documentation
¶
Overview ¶
Example ¶
Example demonstrates basic usage of JsonNull
package main
import (
"encoding/json"
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
type User struct {
Name string `json:"name"`
Email jsonull.JsonNull[string] `json:"email,omitempty"`
}
// Field with value
json1 := `{"name":"John","email":"john@example.com"}`
var user1 User
json.Unmarshal([]byte(json1), &user1)
fmt.Println("IsSet:", user1.Email.IsSet())
fmt.Println("Value:", user1.Email.Value)
// Field explicitly null
json2 := `{"name":"Jane","email":null}`
var user2 User
json.Unmarshal([]byte(json2), &user2)
fmt.Println("IsNull:", user2.Email.IsNull())
// Field not present
json3 := `{"name":"Bob"}`
var user3 User
json.Unmarshal([]byte(json3), &user3)
fmt.Println("Present:", user3.Email.Present)
}
Output: IsSet: true Value: john@example.com IsNull: true Present: false
Example (ComplexTypes) ¶
Example_complexTypes demonstrates using JsonNull with complex types
package main
import (
"encoding/json"
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
type Config struct {
Settings jsonull.JsonNull[map[string]string] `json:"settings,omitempty"`
Tags jsonull.JsonNull[[]string] `json:"tags,omitempty"`
}
jsonData := `{
"settings": {"theme": "dark", "locale": "en"},
"tags": ["go", "programming"]
}`
var config Config
json.Unmarshal([]byte(jsonData), &config)
if config.Settings.IsSet() {
fmt.Println("Theme:", config.Settings.Value["theme"])
fmt.Println("Locale:", config.Settings.Value["locale"])
}
if config.Tags.IsSet() {
fmt.Println("Tags:", config.Tags.Value)
}
}
Output: Theme: dark Locale: en Tags: [go programming]
Example (PatchEndpoint) ¶
Example_patchEndpoint demonstrates using JsonNull for PATCH endpoints
package main
import (
"encoding/json"
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
type UpdateUserRequest struct {
Name jsonull.JsonNull[string] `json:"name,omitempty"`
Email jsonull.JsonNull[string] `json:"email,omitempty"`
Age jsonull.JsonNull[int] `json:"age,omitempty"`
}
// Scenario 1: Delete email (set to null)
req1 := `{"email":null}`
var update1 UpdateUserRequest
json.Unmarshal([]byte(req1), &update1)
if update1.Email.IsNull() {
fmt.Println("Scenario 1: Delete email")
}
// Scenario 2: Update name
req2 := `{"name":"New Name"}`
var update2 UpdateUserRequest
json.Unmarshal([]byte(req2), &update2)
if update2.Name.IsSet() {
fmt.Println("Scenario 2: Update name to:", update2.Name.Value)
}
if !update2.Email.Present {
fmt.Println("Scenario 2: Don't touch email")
}
// Scenario 3: Update multiple fields
req3 := `{"name":"John","age":30}`
var update3 UpdateUserRequest
json.Unmarshal([]byte(req3), &update3)
if update3.Name.IsSet() {
fmt.Println("Scenario 3: Update name to:", update3.Name.Value)
}
if update3.Age.IsSet() {
fmt.Println("Scenario 3: Update age to:", update3.Age.Value)
}
}
Output: Scenario 1: Delete email Scenario 2: Update name to: New Name Scenario 2: Don't touch email Scenario 3: Update name to: John Scenario 3: Update age to: 30
Index ¶
- type JsonNull
- func (j JsonNull[T]) IsNull() bool
- func (j JsonNull[T]) IsSet() bool
- func (j JsonNull[T]) MarshalJSON() ([]byte, error)
- func (j JsonNull[T]) MustGet() T
- func (j JsonNull[T]) OrDefault(defaultValue T) T
- func (j JsonNull[T]) Ptr() *T
- func (j JsonNull[T]) String() string
- func (j *JsonNull[T]) UnmarshalJSON(data []byte) error
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type JsonNull ¶
JsonNull represents a nullable value of type T that can distinguish between: - Not present in JSON (Present=false) - Present as null (Present=true, Valid=false) - Present with value (Present=true, Valid=true)
This is particularly useful for API endpoints that need to differentiate between: - A field not being sent in the request (no update) - A field explicitly set to null (delete/clear the value) - A field set to a specific value (update with new value)
Zero Value Behavior: The zero value of JsonNull[T] has Present=false, Valid=false, and Value=zero value of T. This represents a value that was not present in the JSON.
Thread Safety: JsonNull is not thread-safe. If used concurrently, external synchronization is required.
Example Usage:
type User struct {
Name string `json:"name"`
Email JsonNull[string] `json:"email,omitempty"`
Age JsonNull[int] `json:"age,omitempty"`
}
// PATCH /users/:id
// Request: {"email": null}
// Result: user.Email.IsNull() == true (explicitly clear email)
// Request: {"name": "John"}
// Result: user.Email.Present == false (don't touch email)
// Request: {"email": "john@example.com"}
// Result: user.Email.IsSet() == true (update email)
func JsonNullFromPtr ¶
JsonNullFromPtr creates JsonNull from pointer. If ptr is nil, returns a JsonNull representing null (Present=true, Valid=false). Otherwise, returns a JsonNull with the dereferenced value.
Example:
var ptr *string = nil email := JsonNullFromPtr(ptr) // email.IsNull() == true str := "test@example.com" email2 := JsonNullFromPtr(&str) // email2.IsSet() == true // email2.Value == "test@example.com"
Example ¶
ExampleJsonNullFromPtr demonstrates creating JsonNull from a pointer
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// From nil pointer
var ptr *string = nil
email1 := jsonull.JsonNullFromPtr(ptr)
fmt.Println("From nil pointer - IsNull:", email1.IsNull())
// From valid pointer
str := "test@example.com"
email2 := jsonull.JsonNullFromPtr(&str)
fmt.Println("From valid pointer - IsSet:", email2.IsSet())
fmt.Println("From valid pointer - Value:", email2.Value)
}
Output: From nil pointer - IsNull: true From valid pointer - IsSet: true From valid pointer - Value: test@example.com
func NewJsonNull ¶
NewJsonNull creates a new JsonNull[T] with the given value. The returned JsonNull will have Present=true and Valid=true.
Example:
email := NewJsonNull("user@example.com")
// email.Value = "user@example.com"
// email.Valid = true
// email.Present = true
Example ¶
ExampleNewJsonNull demonstrates creating a JsonNull with a value
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
email := jsonull.NewJsonNull("user@example.com")
fmt.Println("Present:", email.Present)
fmt.Println("Valid:", email.Valid)
fmt.Println("Value:", email.Value)
}
Output: Present: true Valid: true Value: user@example.com
func NewJsonNullNull ¶
NewJsonNullNull creates a new JsonNull[T] representing an explicit null value. The returned JsonNull will have Present=true and Valid=false.
Example:
email := NewJsonNullNull[string]() // email.IsNull() == true
Example ¶
ExampleNewJsonNullNull demonstrates creating a JsonNull representing null
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
email := jsonull.NewJsonNullNull[string]()
fmt.Println("Present:", email.Present)
fmt.Println("Valid:", email.Valid)
fmt.Println("IsNull:", email.IsNull())
}
Output: Present: true Valid: false IsNull: true
func (JsonNull[T]) IsNull ¶
IsNull returns true if the value is present but null. This means the field was explicitly set to null in the JSON.
Example ¶
ExampleJsonNull_IsNull demonstrates the IsNull method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Explicitly null value
nullValue := jsonull.NewJsonNullNull[string]()
fmt.Println("Null value:", nullValue.IsNull())
// Valid value
validValue := jsonull.NewJsonNull("test")
fmt.Println("Valid value:", validValue.IsNull())
// Not present
var notPresent jsonull.JsonNull[string]
fmt.Println("Not present:", notPresent.IsNull())
}
Output: Null value: true Valid value: false Not present: false
func (JsonNull[T]) IsSet ¶
IsSet returns true if the value is present and valid. This means the field was set to an actual value in the JSON.
Example ¶
ExampleJsonNull_IsSet demonstrates the IsSet method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Valid value
validValue := jsonull.NewJsonNull("test")
fmt.Println("Valid value:", validValue.IsSet())
// Null value
nullValue := jsonull.NewJsonNullNull[string]()
fmt.Println("Null value:", nullValue.IsSet())
// Not present
var notPresent jsonull.JsonNull[string]
fmt.Println("Not present:", notPresent.IsSet())
}
Output: Valid value: true Null value: false Not present: false
func (JsonNull[T]) MarshalJSON ¶
MarshalJSON marshals the value into JSON. If Valid is false, returns the JSON null value. Otherwise, marshals the contained value.
Example ¶
ExampleJsonNull_MarshalJSON demonstrates JSON marshaling
package main
import (
"encoding/json"
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
type Data struct {
Value jsonull.JsonNull[string] `json:"value"`
}
// Valid value
d1 := Data{Value: jsonull.NewJsonNull("test")}
json1, _ := json.Marshal(d1)
fmt.Println("Valid:", string(json1))
// Null value
d2 := Data{Value: jsonull.NewJsonNullNull[string]()}
json2, _ := json.Marshal(d2)
fmt.Println("Null:", string(json2))
// Not present (zero value will marshal to null)
d3 := Data{}
json3, _ := json.Marshal(d3)
fmt.Println("Not present (zero value):", string(json3))
}
Output: Valid: {"value":"test"} Null: {"value":null} Not present (zero value): {"value":null}
func (JsonNull[T]) MustGet ¶
func (j JsonNull[T]) MustGet() T
MustGet returns the value or panics if not valid. Use this only when you are certain the value is valid.
Example:
email := NewJsonNull("user@example.com")
value := email.MustGet() // "user@example.com"
nullEmail := NewJsonNullNull[string]()
value2 := nullEmail.MustGet() // panics!
Example ¶
ExampleJsonNull_MustGet demonstrates the MustGet method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Valid value - safe to use
validValue := jsonull.NewJsonNull("test")
value := validValue.MustGet()
fmt.Println("Value:", value)
}
Output: Value: test
func (JsonNull[T]) OrDefault ¶
func (j JsonNull[T]) OrDefault(defaultValue T) T
OrDefault returns the value if valid, otherwise returns the provided default value. This is a safe way to extract a value with a fallback.
Example:
email := NewJsonNull("user@example.com")
result := email.OrDefault("default@example.com") // "user@example.com"
nullEmail := NewJsonNullNull[string]()
result2 := nullEmail.OrDefault("default@example.com") // "default@example.com"
Example ¶
ExampleJsonNull_OrDefault demonstrates the OrDefault method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Valid value
validValue := jsonull.NewJsonNull("user@example.com")
email := validValue.OrDefault("default@example.com")
fmt.Println("Valid value:", email)
// Null value
nullValue := jsonull.NewJsonNullNull[string]()
email2 := nullValue.OrDefault("default@example.com")
fmt.Println("Null value:", email2)
// Not present
var notPresent jsonull.JsonNull[string]
email3 := notPresent.OrDefault("default@example.com")
fmt.Println("Not present:", email3)
}
Output: Valid value: user@example.com Null value: default@example.com Not present: default@example.com
func (JsonNull[T]) Ptr ¶
func (j JsonNull[T]) Ptr() *T
Ptr returns a pointer to the value if it is valid, otherwise returns nil. This is useful when you need to convert JsonNull to a standard pointer type.
Example:
email := NewJsonNull("user@example.com")
ptr := email.Ptr() // *string pointing to "user@example.com"
nullEmail := NewJsonNullNull[string]()
ptr2 := nullEmail.Ptr() // nil
Example ¶
ExampleJsonNull_Ptr demonstrates the Ptr method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Valid value
validValue := jsonull.NewJsonNull("test")
ptr := validValue.Ptr()
if ptr != nil {
fmt.Println("Valid value pointer:", *ptr)
}
// Null value
nullValue := jsonull.NewJsonNullNull[string]()
ptr2 := nullValue.Ptr()
fmt.Println("Null value pointer is nil:", ptr2 == nil)
}
Output: Valid value pointer: test Null value pointer is nil: true
func (JsonNull[T]) String ¶
String returns a string representation of the JsonNull value. Useful for debugging and logging.
Example:
email := NewJsonNull("user@example.com")
fmt.Println(email.String()) // "JsonNull{user@example.com}"
nullEmail := NewJsonNullNull[string]()
fmt.Println(nullEmail.String()) // "JsonNull{null}"
var notPresent JsonNull[string]
fmt.Println(notPresent.String()) // "JsonNull{not present}"
Example ¶
ExampleJsonNull_String demonstrates the String method
package main
import (
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
// Valid value
validValue := jsonull.NewJsonNull("test")
fmt.Println(validValue.String())
// Null value
nullValue := jsonull.NewJsonNullNull[string]()
fmt.Println(nullValue.String())
// Not present
var notPresent jsonull.JsonNull[string]
fmt.Println(notPresent.String())
}
Output: JsonNull{test} JsonNull{null} JsonNull{not present}
func (*JsonNull[T]) UnmarshalJSON ¶
UnmarshalJSON unmarshals the JSON data into the value. MUST use pointer receiver to modify the struct fields.
This method sets Present=true to indicate the field was in the JSON. If the JSON value is null, Valid is set to false. If the JSON value is a valid value, Valid is set to true and Value is populated. If unmarshaling fails, an error is returned and Valid remains false.
Example ¶
ExampleJsonNull_UnmarshalJSON demonstrates JSON unmarshaling
package main
import (
"encoding/json"
"fmt"
"github.com/atfromhome/goreus/pkg/jsonull"
)
func main() {
type Data struct {
Value jsonull.JsonNull[int] `json:"value,omitempty"`
}
// Valid value
var d1 Data
json.Unmarshal([]byte(`{"value":42}`), &d1)
fmt.Println("Valid - IsSet:", d1.Value.IsSet(), "Value:", d1.Value.Value)
// Null value
var d2 Data
json.Unmarshal([]byte(`{"value":null}`), &d2)
fmt.Println("Null - IsNull:", d2.Value.IsNull())
// Not present
var d3 Data
json.Unmarshal([]byte(`{}`), &d3)
fmt.Println("Not present - Present:", d3.Value.Present)
}
Output: Valid - IsSet: true Value: 42 Null - IsNull: true Not present - Present: false