Skip to content

MicahParks/jsontype

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go Report Card Go Reference

jsontype

This package provides a generic json.Marshaler and json.Unmarshaler wrapper for common Go types. This helps minimize custom JSON string parsing and formatting code.

import "github.com/MicahParks/jsontype"

Supported Types

  1. *mail.Address
  2. *regexp.Regexp
  3. time.Time
  4. time.Duration
  5. *url.URL

Planned support

  1. *big.Float
  2. *big.Int
  3. *big.Rat
  4. netip.Addr
  5. netip.AddrPort
  6. netip.Prefix

Usage

  • All methods are safe for concurrent use by multiple goroutines.

Define a data structure using one or more *jsontype.JSONType generic field.

type myConfig struct {
	Ends            *jsontype.JSONType[time.Time]      `json:"ends"`
	GetInterval     *jsontype.JSONType[time.Duration]  `json:"getInterval"`
	NotificationMsg string                             `json:"notificationMsg"`
	Notify          *jsontype.JSONType[*mail.Address]  `json:"notify"`
	TargetPage      *jsontype.JSONType[*url.URL]       `json:"targetPage"`
	TargetRegExp    *jsontype.JSONType[*regexp.Regexp] `json:"targetRegExp"`
}

Optionally set non-default behavior through options before unmarshalling

// Set non-default unmarshal behavior.
endOpts := jsontype.Options{
	TimeFormatUnmarshal: time.RFC1123,
}
config.Ends = jsontype.NewWithOptions(time.Time{}, endOpts)

Unmarshal JSON into the data structure

// Unmarshal the configuration.
err := json.Unmarshal(json.RawMessage(exampleConfig), &config)
if err != nil {
	logger.Fatalf("failed to unmarshal JSON: %s", err)
}

Use the fields on the data structure by accessing the .Get() method

// Access fields on the unmarshalled configuration.
logger.Printf("Ends: %s", config.Ends.Get().String())
logger.Printf("Get interval: %s", config.GetInterval.Get().String())

Optionally set non-default behavior through options before marshalling

// Set non-default marshal behavior.
emailOpts := jsontype.Options{
	MailAddressAddressOnlyMarshal: true,
	MailAddressLowerMarshal:       true,
}
config.Notify = jsontype.NewWithOptions(config.Notify.Get(), emailOpts)

Marshal the data structure into JSON

// Marshal the configuration back to JSON.
remarshaled, err := json.MarshalIndent(config, "", "  ")
if err != nil {
	logger.Fatalf("failed to re-marshal configuration: %s", err)
}

Examples

Please see the examples directory.

package main

import (
	"encoding/json"
	"log"
	"net/mail"
	"net/url"
	"os"
	"regexp"
	"time"

	"github.com/MicahParks/jsontype"
)

const exampleConfig = `{
  "ends": "Wed, 04 Oct 2022 00:00:00 MST",
  "getInterval": "1h30m",
  "notificationMsg": "Your item is on sale!",
  "notify": "[email protected]",
  "targetPage": "https://www.example.com",
  "targetRegExp": "example"
}`

type myConfig struct {
	Ends            *jsontype.JSONType[time.Time]      `json:"ends"`
	GetInterval     *jsontype.JSONType[time.Duration]  `json:"getInterval"`
	NotificationMsg string                             `json:"notificationMsg"`
	Notify          *jsontype.JSONType[*mail.Address]  `json:"notify"`
	TargetPage      *jsontype.JSONType[*url.URL]       `json:"targetPage"`
	TargetRegExp    *jsontype.JSONType[*regexp.Regexp] `json:"targetRegExp"`
}

func main() {
	logger := log.New(os.Stdout, "", 0)
	var config myConfig

	// Set non-default unmarshal behavior.
	endOpts := jsontype.Options{
		TimeFormatUnmarshal: time.RFC1123,
	}
	config.Ends = jsontype.NewWithOptions(time.Time{}, endOpts)

	// Unmarshal the configuration.
	err := json.Unmarshal(json.RawMessage(exampleConfig), &config)
	if err != nil {
		logger.Fatalf("failed to unmarshal JSON: %s", err)
	}

	// Access fields on the unmarshalled configuration.
	logger.Printf("Ends: %s", config.Ends.Get().String())
	logger.Printf("Get interval: %s", config.GetInterval.Get().String())

	// Set non-default marshal behavior.
	emailOpts := jsontype.Options{
		MailAddressAddressOnlyMarshal: true,
		MailAddressLowerMarshal:       true,
	}
	config.Notify = jsontype.NewWithOptions(config.Notify.Get(), emailOpts)

	// Marshal the configuration back to JSON.
	remarshaled, err := json.MarshalIndent(config, "", "  ")
	if err != nil {
		logger.Fatalf("failed to re-marshal configuration: %s", err)
	}
	logger.Println(string(remarshaled))
}

Output:

Ends: 2022-10-04 00:00:00 -0500 -0500
Get interval: 1h30m0s
{
  "ends": "2022-10-04T00:00:00-05:00",
  "getInterval": "1h30m0s",
  "notificationMsg": "Your item is on sale!",
  "notify": "[email protected]",
  "targetPage": "https://www.example.com",
  "targetRegExp": "example"
}

Testing

$ go test -cover -race
PASS
coverage: 90.1% of statements
ok      github.com/MicahParks/jsontype  0.021s

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages