Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
go-version: '1.19'

- name: Build
run: go build -v ./...
Expand Down
2 changes: 1 addition & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
tinyconf - a simple and universal library for parsing configs.

# Installation
Install via go get. Note that Go 1.18 or newer is required.
Install via go get. Note that Go 1.19 or newer is required.
```sh
go get github.com/insei/tinyconf@latest
```
Expand Down
52 changes: 52 additions & 0 deletions cmp118/cmp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package cmp118

// Ordered is a constraint that permits any ordered type: any type
// that supports the operators < <= >= >.
// If future releases of Go add new ordered types,
// this constraint will be modified to include them.
//
// Note that floating-point types may contain NaN ("not-a-number") values.
// An operator such as == or < will always report false when
// comparing a NaN value with any other value, NaN or not.
// See the [Compare] function for a consistent way to compare NaN values.
type Ordered interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
~string
}

// Compare returns
//
// -1 if x is less than y,
// 0 if x equals y,
// +1 if x is greater than y.
//
// For floating-point types, a NaN is considered less than any non-NaN,
// a NaN is considered equal to a NaN, and -0.0 is equal to 0.0.
func Compare[T Ordered](x, y T) int {
xNaN := isNaN(x)
yNaN := isNaN(y)
if xNaN {
if yNaN {
return 0
}
return -1
}
if yNaN {
return +1
}
if x < y {
return -1
}
if x > y {
return +1
}
return 0
}

// isNaN reports whether x is a NaN without requiring the math package.
// This will always return false if T is not floating-point.
func isNaN[T Ordered](x T) bool {
return x != x
}
17 changes: 9 additions & 8 deletions drivers/env/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@ package env

import (
"bufio"
"cmp"
"fmt"
"os"
"path"
"reflect"
"slices"
"strings"

"github.com/insei/tinyconf"
"github.com/insei/tinyconf/cmp118"
"github.com/insei/tinyconf/slices118"

"github.com/insei/cast"
"github.com/insei/fmap/v3"
"github.com/insei/tinyconf"
)

type envDriver struct {
Expand Down Expand Up @@ -73,7 +74,7 @@ func (d envDriver) getUniqueFields(registers []*tinyconf.Registered) []field {
tag: tag,
}

if slices.ContainsFunc(fields, func(item field) bool {
if slices118.ContainsFunc(fields, func(item field) bool {
return item.tag.Get(d.name) == member.tag.Get(d.name)
}) {
continue
Expand All @@ -98,17 +99,17 @@ func (d envDriver) getRootMap(fields []field) map[int]map[string]string {
func (d envDriver) GenDoc(registers ...*tinyconf.Registered) string {
uniqueFields := d.getUniqueFields(registers)

sortedFields := slices.Clone(uniqueFields)
slices.SortStableFunc(sortedFields, func(i, j field) int {
return cmp.Compare(j.depth, i.depth)
sortedFields := slices118.Clone(uniqueFields)
slices118.SortStableFunc(sortedFields, func(i, j field) int {
return cmp118.Compare(j.depth, i.depth)
})

roots := d.getRootMap(sortedFields)
marks := make([]string, 0)

var doc string
for _, field := range uniqueFields {
if slices.Contains(marks, field.path) {
if slices118.Contains(marks, field.path) {
continue
}
marks = append(marks, field.path)
Expand Down
13 changes: 7 additions & 6 deletions drivers/yaml/yaml.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
package yaml

import (
"cmp"
"fmt"
"reflect"
"slices"
"strings"

"github.com/insei/cast"
"github.com/insei/fmap/v3"

"github.com/insei/tinyconf"
"github.com/insei/tinyconf/cmp118"
"github.com/insei/tinyconf/slices118"
)

type yamlDriver struct {
Expand Down Expand Up @@ -116,7 +117,7 @@ func (d *yamlDriver) getUniqueFields(registers []*tinyconf.Registered) []field {
tag: tag,
}

if slices.ContainsFunc(fields, func(item field) bool {
if slices118.ContainsFunc(fields, func(item field) bool {
matchPath := item.path == member.path
matchTagDriver := tagDriver == item.tag.Get(d.name)
return matchPath && matchTagDriver
Expand Down Expand Up @@ -151,9 +152,9 @@ func (d *yamlDriver) getRootMap(fields []field) map[string]string {
func (d *yamlDriver) GenDoc(registers ...*tinyconf.Registered) string {
uniqueFields := d.getUniqueFields(registers)

sortedFields := slices.Clone(uniqueFields)
slices.SortStableFunc(sortedFields, func(i, j field) int {
return cmp.Compare(i.path, j.path)
sortedFields := slices118.Clone(uniqueFields)
slices118.SortStableFunc(sortedFields, func(i, j field) int {
return cmp118.Compare(i.path, j.path)
})

roots := d.getRootMap(sortedFields)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module github.com/insei/tinyconf

go 1.21
go 1.19

require (
github.com/insei/cast v1.1.1
github.com/insei/fmap/v3 v3.0.0
github.com/insei/fmap/v3 v3.1.2
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
gopkg.in/yaml.v3 v3.0.1
Expand Down
5 changes: 2 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/insei/cast v1.1.1 h1:Elrnc3yo5FvaN8B6KWP/+UWblgKG8uj0/UbE/olcLYM=
github.com/insei/cast v1.1.1/go.mod h1:WyueAs28LJPpteJTcUZbkt3eLffnNczOR7B4ODQ8lrE=
github.com/insei/fmap/v3 v3.0.0 h1:BpRsFgQ2nt5tl/8tzp6y+MWIAJhqCTeKBHC56L/Um30=
github.com/insei/fmap/v3 v3.0.0/go.mod h1:Kk0gs7nKb4E/JycKJFnrsX5hlyBBe0yetGKFCJG0vzk=
github.com/insei/fmap/v3 v3.1.2 h1:ZBr+WiZpIxFNeMo2X4QOST4AFl0sGAkG+EO08Ved3bY=
github.com/insei/fmap/v3 v3.1.2/go.mod h1:Kk0gs7nKb4E/JycKJFnrsX5hlyBBe0yetGKFCJG0vzk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
Expand Down
48 changes: 48 additions & 0 deletions slices118/slices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Package slices118 defines various functions useful with slices118 of any type.
package slices118

// Index returns the index of the first occurrence of v in s,
// or -1 if not present.
func Index[S ~[]E, E comparable](s S, v E) int {
for i := range s {
if v == s[i] {
return i
}
}
return -1
}

// IndexFunc returns the first index i satisfying f(s[i]),
// or -1 if none do.
func IndexFunc[S ~[]E, E any](s S, f func(E) bool) int {
for i := range s {
if f(s[i]) {
return i
}
}
return -1
}

// Contains reports whether v is present in s.
func Contains[S ~[]E, E comparable](s S, v E) bool {
return Index(s, v) >= 0
}

// ContainsFunc reports whether at least one
// element e of s satisfies f(e).
func ContainsFunc[S ~[]E, E any](s S, f func(E) bool) bool {
return IndexFunc(s, f) >= 0
}

// Clone returns a copy of the slice.
// The elements are copied using assignment, so this is a shallow clone.
// The result may have additional unused capacity.
func Clone[S ~[]E, E any](s S) S {
// Preserve nilness in case it matters.
if s == nil {
return nil
}
// Avoid s[:0:0] as it leads to unwanted liveness when cloning a
// zero-length slice of a large array; see https://go.dev/issue/68488.
return append(S{}, s...)
}
Loading