jsonutil

package module
v0.0.0-...-75122b6 Latest Latest
Warning

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

Go to latest
Published: May 4, 2026 License: MIT Imports: 13 Imported by: 7

README

JSON v2 Utilities

Go Reference Go Report Card Code Coverage

jsonutil is a Go package that provides custom JSON v2 marshaling and unmarshaling functions for specific data types.

This package is particularly useful when you need to handle JSON encoding and decoding for types like time.Duration and url.URL in a customized manner.

Features

  • Custom marshaler and unmarshaler for url.URL:
    • URLMarshal marshals url.URL as a string.
    • URLUnmarshal unmarshals url.URL from a string.
  • Custom marshaler and unmarshaler for time.Duration:
    • DurationMarshalIntSeconds marshals time.Duration as an integer representing seconds.
    • DurationUnmarshalIntSeconds unmarshals time.Duration from an integer assuming it represents seconds.
  • Custom marshaler for maps with ordered keys:
    • OrderedMapMarshal[M ~map[K]V, K cmp.Ordered, V any] marshals M so that the keys are sorted.
  • Custom marshaler for http.Header:
    • HTTPHeaderMarshal marshals the values of http.Header as single strings.
    • HTTPHeaderUnmarshal unmarshals the values of http.Header from single strings.

Installation

To install the library, use the following command:

go get github.com/MarkRosemaker/jsonutil

Usage

Custom Marshaling and Unmarshaling for url.URL

To use the custom marshaler and unmarshaler for url.URL, you can import the package and use the provided functions:

package main

import (
	"encoding/json/v2"
	"fmt"
	"net/url"

	"github.com/MarkRosemaker/jsonutil"
)

var jsonOpts = json.JoinOptions(
	json.WithMarshalers(json.NewMarshalers(json.MarshalToFunc(jsonutil.URLMarshal))),
	json.WithUnmarshalers(json.NewUnmarshalers(json.UnmarshalFromFunc(jsonutil.URLUnmarshal))),
)

type MyStruct struct {
	Foo  string  `json:"foo"`
	Link url.URL `json:"link"`
}

func main() {
	out := &MyStruct{}
	if err := json.Unmarshal([]byte(`{"foo":"bar","link":"https://example.com/"}`), out, jsonOpts); err != nil {
		panic(err)
	}

	if out.Link.String() != "https://example.com/" {
		panic("something went wrong")
	}

	res, err := json.Marshal(MyStruct{
		Foo:  "baz",
		Link: url.URL{Scheme: "http", Host: "example.com", Path: "/some-path"},
	}, jsonOpts)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(res))
	// Output: {"foo":"baz","link":"http://example.com/some-path"}
}
Custom Marshaling and Unmarshaling for time.Duration

To use the custom marshaler and unmarshaler for time.Duration, you can import the package and use the provided functions:

package main

import (
	"encoding/json/v2"
	"fmt"
	"time"

	"github.com/MarkRosemaker/jsonutil"
)

var jsonOpts = json.JoinOptions(
	json.WithMarshalers(json.MarshalToFunc(jsonutil.DurationMarshalIntSeconds)),
	json.WithUnmarshalers(json.UnmarshalFromFunc(jsonutil.DurationUnmarshalIntSeconds)),
)

type MyStruct struct {
	Foo      string        `json:"foo"`
	Duration time.Duration `json:"duration"`
}

func main() {
	out := &MyStruct{}
	if err := json.Unmarshal([]byte(`{"foo":"bar","duration":3}`), out, jsonOpts); err != nil {
		panic(err)
	}

	if out.Duration != 3*time.Second {
		panic("something went wrong")
	}

	res, err := json.Marshal(MyStruct{
		Foo:      "baz",
		Duration: time.Minute,
	}, jsonOpts)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(res))
	// Output: {"foo":"baz","duration":60}
}
Custom Marshaling for Maps with Ordered Keys

To use the custom marshaler for M where [M ~map[K]V, K cmp.Ordered, V any], you can import the package and use the provided functions:

package main

import (
	"encoding/json/v2"
	"fmt"

	"github.com/MarkRosemaker/jsonutil"
)

type myMap map[string]int

var jsonOpts = json.JoinOptions(
	json.WithMarshalers(json.MarshalToFunc(jsonutil.OrderedMapMarshal[myMap])),
)

func main() {
	res, err := json.Marshal(myMap{
		"foo": 1,
		"bar": 2,
	}, jsonOpts)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(res))
	// Output: {"bar":2,"bar":1}
}
Custom Marshaling and Unmarshaling for http.Header

To use the custom marshaler and unmarshaler for http.Header, you can import the package and use the provided functions:

package main

import (
	"encoding/json/v2"
	"fmt"
	"net/http"

	"github.com/MarkRosemaker/jsonutil"
)

var jsonOpts = json.JoinOptions(
	json.WithMarshalers(json.MarshalToFunc(jsonutil.HTTPHeaderMarshal)),
	json.WithUnmarshalers(json.UnmarshalFromFunc(jsonutil.HTTPHeaderUnmarshal)),
)

func main() {
	out := &http.Header{}
	if err := json.Unmarshal([]byte(`{"foo":"bar","baz":"quux"}`), out, jsonOpts); err != nil {
		panic(err)
	}

	res, err := json.Marshal(http.Header{
		"foo": []string{"bar"},
		"baz": []string{"quux"},
	}, jsonOpts)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(res))
	// Output: {"Foo":"bar","Baz":"quux"}
}

Contributing

If you have any contributions to make, please submit a pull request or open an issue on the GitHub repository.

License

This project is licensed under the MIT License. See the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DateMarshalIntUnix

func DateMarshalIntUnix(enc *jsontext.Encoder, d civil.Date) error

DateMarshalIntUnix is a custom marshaler for civil.Date, marshaling them as integers representing unix time.

func DateUnmarshalIntUnix

func DateUnmarshalIntUnix(dec *jsontext.Decoder, d *civil.Date) error

DateUnmarshalIntUnix is a custom unmarshaler for civil.Date, unmarshaling them from integers and assuming they represent unix time.

func DurationMarshalIntSeconds

func DurationMarshalIntSeconds(enc *jsontext.Encoder, d time.Duration) error

DurationMarshalIntSeconds is a custom marshaler for time.Duration, marshaling them as integers representing seconds.

func DurationUnmarshalIntSeconds

func DurationUnmarshalIntSeconds(dec *jsontext.Decoder, d *time.Duration) error

DurationUnmarshalIntSeconds is a custom unmarshaler for time.Duration, unmarshaling them from integers and assuming they represent seconds.

func HTTPHeaderMarshal

func HTTPHeaderMarshal(enc *jsontext.Encoder, m http.Header) error

HTTPHeaderMarshal is a custom marshaler for http.Header, marshaling values as a single strings. It also marshals the keys in their canonical form. Note that we omit keys that don't have a value.

func HTTPHeaderUnmarshal

func HTTPHeaderUnmarshal(dec *jsontext.Decoder, h *http.Header) error

HTTPHeaderUnmarshal is a custom unmarshaler for http.Header, unmarshaling values as single strings.

func OrderedMapMarshal

func OrderedMapMarshal[M ~map[K]V, K cmp.Ordered, V any](enc *jsontext.Encoder, m M) error

OrderedMapMarshal is a custom marshaler for maps with ordered keys, marshaling them in an ordered fashion.

func ReadFile

func ReadFile[T any](name string, opts ...json.Options) (T, error)

ReadFile reads a json file and unmarshals it.

func TimeMarshalIntUnix

func TimeMarshalIntUnix(enc *jsontext.Encoder, t time.Time) error

TimeMarshalIntUnix is a custom marshaler for time.Time, marshaling them as integers representing unix time.

func TimeUnmarshalIntUnix

func TimeUnmarshalIntUnix(dec *jsontext.Decoder, d *time.Time) error

TimeUnmarshalIntUnix is a custom unmarshaler for time.Time, unmarshaling them from integers and assuming they represent unix time.

func URLMarshal

func URLMarshal(enc *jsontext.Encoder, u url.URL) error

URLMarshal is a custom marshaler for URL values, marshaling them as strings.

func URLUnmarshal

func URLUnmarshal(dec *jsontext.Decoder, u *url.URL) error

URLUnmarshal is a custom unmarshaler for URL values, unmarshaling them from strings.

func WriteFile

func WriteFile[T any](name string, data T, opts ...json.Options) error

WriteFile writes a json file by marshalling it.

Types

This section is empty.