jsoninline

package module
v0.0.6 Latest Latest
Warning

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

Go to latest
Published: Dec 24, 2025 License: MIT Imports: 6 Imported by: 0

README

jsoninline

jsoninline is a small Go utility that helps inline nested struct fields into the parent object when marshaling to JSON. It provides InlineMarshaler and a helper V() to wrap values that should be inlined.

Features

  • Inline fields tagged with ,inline into their parent JSON object.
  • Support for pointers, structs, slices/arrays, and basic types.

Installation

go get github.com/hydrz/jsoninline@latest

Quick start

  1. Use jsoninline.InlineMarshaler as the field type and add ,inline to the JSON tag.
  2. Wrap a value with jsoninline.V(value) to mark it for inlining.
  3. Marshal using the standard encoding/json package.

Example

package main

import (
    "encoding/json"
    "fmt"

    "github.com/hydrz/jsoninline"
)

type DNSServerOption struct {
    Type  string               `json:"type"`
    Tag   string               `json:"tag"`
    Local LocalDNSServerOption `json:",inline"`
    UDP   UDPDNSServerOption   `json:",inline"`
    TLS   TLSDNSServerOption   `json:",inline"`
}

type LocalDNSServerOption struct {
    PreferGO bool `json:"prefer_go,omitempty"`
}

type ServerOptions struct {
    Server     string `json:"server,omitempty"`
    ServerPort int    `json:"server_port,omitempty"`
}

type UDPDNSServerOption struct {
    ServerOptions
}

type TLSDNSServerOption struct {
    ServerOptions
    TLS any `json:"tls,omitempty"`
}

func main() {
    options := []DNSServerOption{
        {
            Type: "local",
            Tag:  "local-dns",
            Local: LocalDNSServerOption{
                PreferGO: true,
            },
        },
        {
            Type: "udp",
            Tag:  "udp-dns",
            UDP: UDPDNSServerOption{
                ServerOptions: ServerOptions{
                    Server:     "1.1.1.1",
                    ServerPort: 53,
                },
            },
        },
        {
            Type: "tls",
            Tag:  "tls-dns",
            TLS: TLSDNSServerOption{
                ServerOptions: ServerOptions{
                    Server:     "dns.google",
                    ServerPort: 853,
                },
                TLS: map[string]interface{}{
                    "sni": "dns.google",
                },
            },
        },
    }
    bytes, err := json.MarshalIndent(jsoninline.V(options), "", "  ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(bytes))

    // Output:
    // [ ... ]
}

Unmarshal example

You can also use jsoninline.V when unmarshaling to populate structs that expect inlined fields. Example:

//go:build example

package main

import (
    "encoding/json"
    "fmt"

    "github.com/hydrz/jsoninline"
)

// Demonstrates unmarshaling JSON with inlined fields into Go structs
// using jsoninline.V to wrap the destination.
type User struct {
    ID    int    `json:"id"`
    Name  string `json:"name"`
    Email string `json:"email"`
    China *China `json:",inline"`
    USA   *USA   `json:",inline"`
}

func (u *User) String() string {
    data, _ := json.Marshal(jsoninline.V(u))
    return string(data)
}

type China struct {
    City     string `json:"city,omitempty"`
    Province string `json:"province,omitempty"`
}

type USA struct {
    City  string `json:"city,omitempty"`
    State string `json:"state,omitempty"`
}

var jsonData = `[
  {
    "id": 1,
    "name": "Alice",
    "email": "alice@example.com",
    "province": "Guangdong",
    "city": "Shenzhen"
  },
  {
    "id": 2,
    "name": "Bob",
    "email": "bob@example.com",
    "state": "California",
    "city": "Los Angeles"
  }
]`

func main() {

    var users []*User
    if err := json.Unmarshal([]byte(jsonData), jsoninline.V(&users)); err != nil {
        panic(err)
    }

    for i, u := range users {
        fmt.Printf("user %d: %+v\n", i, u)
    }
    // Output:
    // user 0: { ... }
}

JSON Schema Usage

package main

import (
	"encoding/json"
	"fmt"

	"github.com/google/jsonschema-go/jsonschema"
	"github.com/hydrz/jsoninline"
)

// Example types mirroring test fixtures; used to demonstrate schema generation.
type User struct {
	ID    int    `json:"id"`
	Name  string `json:"name"`
	Email string `json:"email"`
	China *China `json:",inline"`
	USA   *USA   `json:",inline"`
}

type China struct {
	City      string     `json:"city,omitempty"`
	Province  string     `json:"province,omitempty"`
	NestedFoo *NestedFoo `json:",inline"`
}

type USA struct {
	City      string     `json:"city,omitempty"`
	State     string     `json:"state,omitempty"`
	NestedBar *NestedBar `json:",inline"`
}

type NestedFoo struct {
	FooField string `json:"foo_field,omitempty"`
}

type NestedBar struct {
	BarField string `json:"bar_field,omitempty"`
}

func main() {
	schema, err := jsoninline.For[User](&jsonschema.ForOptions{})
	if err != nil {
		panic(err)
	}

	// Marshal the schema to pretty JSON and print it.
	b, err := json.MarshalIndent(schema, "", "  ")
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func For added in v0.0.3

func For[T any](opts *jsonschema.ForOptions) (*jsonschema.Schema, error)

func ForType added in v0.0.3

func ForType(t reflect.Type, opts *jsonschema.ForOptions) (*jsonschema.Schema, error)

Types

type InlineMarshaler

type InlineMarshaler struct {
	V any
}

func V

func V(v any) *InlineMarshaler

func (InlineMarshaler) MarshalJSON

func (im InlineMarshaler) MarshalJSON() ([]byte, error)

func (*InlineMarshaler) UnmarshalJSON added in v0.0.2

func (im *InlineMarshaler) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler for InlineMarshaler. im.V must be a non-nil pointer to the destination value (struct, slice, etc.).

Jump to

Keyboard shortcuts

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