oneof

package
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Dec 6, 2023 License: Apache-2.0 Imports: 4 Imported by: 0

README

Slice helpers

GoDev

Realize OneOf type.

OneOf allows to store different types in one variable. It supports also JSON marshalling and unmarshalling.

For example see [examples_test.go].

Documentation

GoDoc

Documentation

Overview

Realize `OneOf` type. It allows to store different types in one variable. OneOf supports also JSON marshalling and unmarshalling.

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrEmpty = errors.New("empty")

ErrEmpty returned by the unmarshaler when data is empty '{}'.

Functions

This section is empty.

Types

type Factory

type Factory[V Value] interface {
	New(name string) (V, error)
}

Factory describe objects factory.

type OneOf

type OneOf[V Value, R Factory[V]] struct {
	Value V
	// contains filtered or unexported fields
}

OneOf is container of many values.

Example
package main

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"regexp"
)

type Matcher interface {
	GetName() string
	Match(s string) (matched bool, err error)
}

type Mask struct {
	Pattern string `json:"pattern,omitempty"`
}

func (*Mask) GetName() string {
	return "mask"
}

func (m *Mask) Match(s string) (matched bool, err error) {
	matched, err = filepath.Match(m.Pattern, s)
	if err != nil {
		return false, fmt.Errorf("mask matching '%s' with '%s': %w", s, m.Pattern, err)
	}
	return matched, nil
}

type Regexp struct {
	Pattern string `json:"pattern,omitempty"`
}

func (*Regexp) GetName() string {
	return "regexp"
}

func (r *Regexp) Match(s string) (matched bool, err error) {
	matched, err = regexp.MatchString(r.Pattern, s)
	if err != nil {
		return false, fmt.Errorf("regexp matching '%s' with '%s': %w", s, r.Pattern, err)
	}
	return matched, nil
}

type MatcherFactory struct{}

func (f MatcherFactory) New(name string) (Matcher, error) {
	switch {
	case (*Mask)(nil).GetName() == name:
		return new(Mask), nil
	case (*Regexp)(nil).GetName() == name:
		return new(Regexp), nil
	}
	return nil, fmt.Errorf("unknown type name %s", name)
}

type AnyMatcher = OneOf[Matcher, MatcherFactory]

type Matchers struct {
	Matchers []AnyMatcher `json:"matchers,omitempty"`
}

func (m Matchers) Match(s string) (bool, error) {
	for _, matcher := range m.Matchers {
		matched, err := matcher.Get().Match(s)
		if err != nil {
			return false, err
		}
		if matched {
			return true, nil
		}
	}
	return false, nil
}

func main() {
	matchers := Matchers{
		Matchers: []AnyMatcher{
			{Value: &Mask{Pattern: "hell?"}},
			{Value: &Regexp{Pattern: "g.*ye"}},
		},
	}

	// Marshall.
	b, err := json.Marshal(matchers)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))

	// Clear
	matchers = Matchers{}

	// Unmarshal.
	err = json.Unmarshal(b, &matchers)
	if err != nil {
		panic(err)
	}

	// Check matchers.
	matched, err := matchers.Match("hello")
	if err != nil {
		panic(err)
	}
	fmt.Println(matched)

	matched, err = matchers.Match("goodbye")
	if err != nil {
		panic(err)
	}
	fmt.Println(matched)

	matched, err = matchers.Match("unmatched")
	if err != nil {
		panic(err)
	}
	fmt.Println(matched)

	// Marshall unmarshalled.
	b, err = json.Marshal(matchers)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))

}
Output:

{"matchers":[{"mask":{"pattern":"hell?"}},{"regexp":{"pattern":"g.*ye"}}]}
true
true
false
{"matchers":[{"mask":{"pattern":"hell?"}},{"regexp":{"pattern":"g.*ye"}}]}

func (*OneOf[V, R]) Get

func (o *OneOf[V, R]) Get() V

Get the value.

func (OneOf[V, R]) MarshalJSON

func (o OneOf[V, R]) MarshalJSON() ([]byte, error)

MarshalJSON marshals OneOf value.

func (*OneOf[V, R]) Set

func (o *OneOf[V, R]) Set(v V)

Set the value.

func (*OneOf[V, R]) UnmarshalJSON

func (o *OneOf[V, R]) UnmarshalJSON(b []byte) error

UnmarshalJSON unmarshal OneOf value.

type Value

type Value interface {
	GetName() string
}

Value is the interface that must be implemented by any OneOf value.

Jump to

Keyboard shortcuts

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