gonull

package module
v2.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2025 License: MIT Imports: 9 Imported by: 0

README

Go Nullable with Generics

PkgGoDev go-mod-verify go-vuln golangci-lint codecov

Go package simplifies nullable fields handling with Go Generics.

gonull is a Go package that provides type-safe handling of nullable values using generics. It's designed to work seamlessly with JSON and SQL operations, making it perfect for web services and database interactions.

Features

  • 🎯 Type-safe nullable values using Go generics
  • 💡 Omitzero support
  • 🔄 Built-in JSON marshaling/unmarshaling
  • 📊 SQL database compatibility
  • ✨ Zero dependencies

Usage

go get github.com/LukaGiorgadze/gonull/v2
Example
package main

import (
    "encoding/json"
    "fmt"

    "github.com/LukaGiorgadze/gonull"
)

type MyCustomInt int
type MyCustomFloat32 float32

type Person struct {
    Name     string                           `json:"name"`
    Age      gonull.Nullable[MyCustomInt]     `json:"age"`
    Address  gonull.Nullable[string]          `json:"address"`
    Height   gonull.Nullable[MyCustomFloat32] `json:"height"`
    IsZero   gonull.Nullable[bool]            `json:"is_zero,omitzero"` // This property will be omitted from the output since it's not present in jsonData.
}

func main() {
    jsonData := []byte(`
    {
        "name": "Alice",
        "age": 15,
        "address": null,
        "height": null
    }`)

    var person Person
    json.Unmarshal(jsonData, &person)
    fmt.Printf("Unmarshalled Person: %+v\n", person)

    marshalledData, _ := json.Marshal(person)
    fmt.Printf("Marshalled JSON: %s\n", string(marshalledData))

    // Output:
    // Unmarshalled Person: {Name:Alice Age:15 Address: Height:0 IsZero:false}
    // Marshalled JSON: {"name":"Alice","age":15,"address":null,"height":null}
    // As you see, IsZero is not present in the output, because we used the omitzero tag introduced in go v1.24.
}
Database example
type User struct {
    Name     gonull.Nullable[string]
    Age      gonull.Nullable[int]
}

func main() {
    // ...
    rows, err := db.Query("SELECT id, name, age FROM users")
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        var user User
        err := rows.Scan(&user.Name, &user.Age)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("ID: %d, Name: %v, Age: %v\n", user.Name.Val, user.Age.Val)
    }
    // ...
}

Documentation

Overview

Package gonull provides a generic Nullable type for handling nullable values in a convenient way. This is useful when working with databases and JSON, where nullable values are common.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnsupportedConversion is an error that occurs when attempting to convert a value to an unsupported type.
	// This typically happens when Scan is called with a value that cannot be converted to the target type T.
	ErrUnsupportedConversion = errors.New("unsupported type conversion")
)

Functions

This section is empty.

Types

type Nullable

type Nullable[T any] struct {
	Val     T
	Valid   bool
	Present bool
}

Nullable is a generic struct that holds a nullable value of any type T. It keeps track of the value (Val), a flag (Valid) indicating whether the value has been set and a flag (Present) indicating if the value is in the struct. This allows for better handling of nullable and undefined values, ensuring proper value management and serialization.

func NewNullable

func NewNullable[T any](value T) Nullable[T]

NewNullable creates a new Nullable with the given value and sets Valid to true. This is useful when you want to create a Nullable with an initial value, explicitly marking it as set.

func (Nullable[T]) IsZero

func (n Nullable[T]) IsZero() bool

IsZero implements the json.Zeroed interface for Nullable, enabling it to be used as a nullable field in JSON operations. This method ensures proper marshalling of Nullable values into JSON data, representing unset values as null in the serialized output.

func (Nullable[T]) MarshalJSON

func (n Nullable[T]) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface for Nullable, enabling it to be used as a nullable field in JSON operations. This method ensures proper marshalling of Nullable values into JSON data, representing unset values as null in the serialized output.

func (Nullable[T]) OrElse

func (n Nullable[T]) OrElse(defaultVal T) T

OrElse returns the underlying Val if valid otherwise returns the provided defaultVal

func (*Nullable[T]) Scan

func (n *Nullable[T]) Scan(value any) error

Scan implements the sql.Scanner interface for Nullable, allowing it to be used as a nullable field in database operations. It is responsible for properly setting the Valid flag and converting the scanned value to the target type T. This enables seamless integration with database/sql when working with nullable values.

func (*Nullable[T]) UnmarshalJSON

func (n *Nullable[T]) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface for Nullable, allowing it to be used as a nullable field in JSON operations. This method ensures proper unmarshalling of JSON data into the Nullable value, correctly setting the Valid flag based on the JSON data.

func (Nullable[T]) Value

func (n Nullable[T]) Value() (driver.Value, error)

Value implements the driver.Valuer interface for Nullable, enabling it to be used as a nullable field in database operations. This method ensures that the correct value is returned for serialization, handling unset Nullable values by returning nil.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL