marshaler

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Mar 30, 2024 License: MIT Imports: 8 Imported by: 0

README

go-marshaler

go-marshaler is a Go library designed to simplify the unmarshalling and decoding of arbitrary key-value data into Go structs, with support for nested structures. This makes it particularly useful for complex configurations. Leveraging struct tags for custom field mappings, it provides a flexible way to work with configuration data stored in various formats.

Getting Started

Installation

Install go-marshaler by running:

go get github.com/g4s8/go-marshaler
Usage

A simple example to decode a map of key-value pairs into a Go struct, demonstrating nested structure support:

package main

import (
    "log"
    "github.com/g4s8/go-marshaler"
)

// Define your configuration struct
type Config struct {
    Host    *string       `kv:"host"`
    Port    int           `kv:"port"`
    Timeout time.Duration `kv:"timeout"`
    Logger  *LoggerConfig `kv:"logger"`
    // Add other fields...
}

type LoggerConfig struct {
    Level  string `kv:"level"`
    Output string `kv:"output"`
}

func main() {
    kv := marshaler.MapKV{
        "host":          "localhost",
        "port":          "8080",
        "timeout":       "5s",
        "logger/level":  "info",
        "logger/output": "stdout",
        // Populate with your key-value pairs
    }
    decoder := marshaler.NewDecoder(kv, marshaler.WithSeparator("/"), marshaler.WithTag("kv"))
    var cfg Config
    if err := decoder.Decode(&cfg); err != nil {
        log.Fatalf("error decoding: %v", err)
    }
    log.Printf("decoded config: %+v", &cfg)
}

Configuration Options

go-marshaler allows customizing the decoding process through various options:

  • WithSeparator(string): Specifies the separator for nested keys.
  • WithSliceSeparator(string): Specifies the separator for slice values.
  • WithTag(string): Sets the struct tag to use for key mapping.
  • WithPrefix(string): Adds a prefix to all keys during decoding.

Refer to the API documentation for more details on how to use these options.

Documentation

Overview

Package marshaler provides a simple interface for marshaling and unmarshaling values from a key-value storage.

The package provides a Decoder that reads and decodes values from a key-value storage. The Decoder uses a set of options to configure the behavior of the decoder.

The package also provides a set of interfaces and types to work with values from a key-value storage. The Value interface represents a value from a key-value storage that can be unmarshaled to a target type. The ValueUnmarshalOpts type is a set of options for value unmarshaling.

Example:

package main

import (
	"log"
	"time"

	"github.com/g4s8/go-marshaler"
)

type LoggerConfig struct {
	Level  string `kv:"level"`
	Output string `kv:"output"`
}

type Config struct {
	Host    *string       `kv:"host"`
	Port    int           `kv:"port"`
	Debug   *bool         `kv:"debug"`
	Opt     *bool         `kv:"opt,omitempty"`
	Timeout time.Duration `kv:"timeout"`
	Logger  *LoggerConfig `kv:"logger"`
	Params  []string      `kv:"params"`
}

func main() {
	kv := marshaler.MapKV{
		"host":          "localhost",
		"port":          "8080",
		"logger/level":  "info",
		"logger/output": "stdout",
		"timeout":       "5s",
		"params":        "a,b,c",
	}
	decoder, err := marshaler.NewDecoder(kv, marshaler.WithSeparator("/"), marshaler.WithTag("kv"))
	if err != nil {
		log.Fatalf("error creating decoder: %v", err)
	}
	var cfg Config
	if err := decoder.Decode(&cfg); err != nil {
		log.Fatalf("error decoding: %v", err)
	}
	log.Printf("decoded config: %+v", cfg)
}

There is also a Scanner interface that can be implemented by a target type to provide custom unmarshaling logic.

Index

Constants

This section is empty.

Variables

View Source
var (
	// Errors for decoder options validation.
	ErrEmptyKeySep   = fmt.Errorf("empty key separator")
	ErrEmptySliceSep = fmt.Errorf("empty slice separator")
	ErrorEmptyTag    = fmt.Errorf("empty tag name")
)

Functions

func Unmarshal

func Unmarshal(kv KV, v any) error

Unmarshal reads values from the key-value storage and decodes them into v. See UnmarshalContext for more details.

func UnmarshalContext

func UnmarshalContext(ctx context.Context, kv KV, v any) error

UnmarshalContext reads values from the key-value storage and decodes them into v using the provided context and default decoder configuration.

Types

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder reads and decodes values from a key-value storage.

func NewDecoder

func NewDecoder(kv KV, opts ...DecoderOption) (*Decoder, error)

NewDecoder returns a new decoder that reads from kv.

func (*Decoder) Decode

func (d *Decoder) Decode(v any) error

Decode reads values from the key-value storage and decodes them into v.

func (*Decoder) DecodeContext

func (d *Decoder) DecodeContext(ctx context.Context, v any) error

DecodeContext reads values from the key-value storage and decodes them into v. It uses the provided context for the deadline and cancellation.

type DecoderOption

type DecoderOption func(*decoderConfig) error

DecoderOption is an option for decoder configuration.

It returns an error if the option parameter is invalid.

func WithPrefix

func WithPrefix(prefix string) DecoderOption

WithPrefix sets the prefix for all keys.

func WithSeparator

func WithSeparator(separator string) DecoderOption

WithSeparator sets the key separator for decoder.

Default is "/".

func WithSliceSeparator

func WithSliceSeparator(separator string) DecoderOption

WithSliceSeparator sets the separator of string values for slice fields.

Default is ",".

func WithTag

func WithTag(tag string) DecoderOption

WithTag sets the tag name for decoder.

Default is "kv".

type KV

type KV interface {
	Get(ctx context.Context, key string) (Value, error)
}

KV is a key-value storage API.

It provides a method to get a value by key.

type MapKV

type MapKV map[string]string

MapKV is a simple key-value storage implementation based on a map of strings.

func (MapKV) Get

func (m MapKV) Get(ctx context.Context, key string) (Value, error)

type Scanner

type Scanner interface {
	// Scan scans a value to a target type.
	Scan(v any) error
}

Scanner is an interface for scanning values.

It can scan a value by itself. The scan method could be called by [Value.UnmarshalTo](#Value.UnmarshalTo) implementation to scan a value to a target type.

Example:

type Custom struct {
	Foo string
	Bar int
}

func (c *Custom) Scan(v any) error {
	val, ok := v.(string)
	if !ok {
		return errors.New("unexpected type")
	}
	parts := strings.Split(val, ",")
	c.Foo = parts[0]
	i, err := strconv.Atoi(parts[1])
	if err != nil {
		return err
	}
	c.Bar = i
	return nil
}

type StringValue

type StringValue struct {
	// contains filtered or unexported fields
}

StringValue holds a string value, that can be unmarshaled to a target type.

It supports unmarshaling to the following types: - string - int, int8, int16, int32, int64 - uint, uint8, uint16, uint32, uint64 - bool - float32, float64 - time.Duration - time.Time (RFC3339) - []string - Scanner

func NewBytesValue

func NewBytesValue(value []byte) StringValue

NewBytesValue creates a new string value from a byte slice.

func NewStringValue

func NewStringValue(value string) StringValue

NewStringValue creates a new string value from a string.

func (StringValue) UnmarshalTo

func (v StringValue) UnmarshalTo(out any, opts ValueUnmarshalOpts) error

UnmarshalTo unmarshals the string value to a target type using the provided options.

type Value

type Value interface {
	// UnmarshalTo unmarshal value to a target type or return an error
	// if it's not possible.
	UnmarshalTo(out any, opts ValueUnmarshalOpts) error
}

Value is a kv-storage value, that can be unmarshaled to a target type.

KV implementation can use provided Value implementation to unmarshal, like StringValue(#StringValue) or implement custom Value type.

var NullValue Value = nullValue{}

NullValue is a special value that represents a null value.

It doesn't perfor any unmarshaling operatrion.

type ValueUnmarshalOpts

type ValueUnmarshalOpts struct {
	// SliceSep is a separator for slice values.
	SliceSep string
}

ValueUnmarshalOpts is a set of options for value unmarshaling.

Jump to

Keyboard shortcuts

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