barky

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2025 License: Apache-2.0 Imports: 8 Imported by: 2

README

barky

English | 中文

barky is a Go package for working with hierarchical key-value data structures, primarily for handling nested data in formats like JSON, YAML, or TOML.

Features

1. Data Flattening
  • Converts nested maps, slices, and arrays into a flat map[string]string.
  • Uses dot notation for maps (e.g., db.hosts).
  • Uses index notation for arrays/slices (e.g., hosts[0]).
  • Example: {"db": {"hosts": ["a", "b"]}} becomes {"db.hosts[0]": "a", "db.hosts[1]": "b"}.
2. Path Handling
  • Defines a Path abstraction, representing hierarchical keys as a sequence of typed segments (map keys or array indices).
  • Supports parsing string paths (e.g., "foo.bar[0]") into Path objects.
  • Supports converting Path objects back into string paths.
3. Storage Management
  • The Storage type manages a collection of flattened key-value pairs.
  • Internally builds and maintains a hierarchical tree structure to prevent key conflicts.
  • Associates values with their source files, supporting multi-file merging and source tracking.
4. Querying
  • Provides helper methods for retrieving values.
  • Checks for the existence of keys.
  • Enumerates subkeys.
  • Iterates in a deterministic order.

Typical Use Cases

  1. Standardizing configuration files from multiple sources into a flat key-value map for comparison, merging, or diffing.
  2. Querying nested data with simple string paths, avoiding direct reflection or manual traversal of nested maps.
  3. Building tools that unify structured data from multiple files while preserving source information and preventing conflicts.

Example

package main

import (
	"fmt"
	"github.com/go-spring/spring-base/barky"
)

func main() {
	// Create a nested data structure
	data := map[string]interface{}{
		"database": map[string]interface{}{
			"host": "localhost",
			"port": 5432,
			"credentials": map[string]interface{}{
				"username": "admin",
				"password": "secret",
			},
		},
		"features": []interface{}{
			"feature1",
			"feature2",
			map[string]interface{}{
				"name":    "feature3",
				"enabled": true,
			},
		},
	}

	// Flatten the data
	flat := barky.FlattenMap(data)

	// Print flattened results
	for key, value := range flat {
		fmt.Printf("%s: %s\n", key, value)
	}

	// Use Storage to manage data
	storage := barky.NewStorage()
	fileID := storage.AddFile("config.yaml")

	// Set values
	storage.Set("database.host", "localhost", fileID)
	storage.Set("database.port", "5432", fileID)

	// Retrieve values
	host := storage.Get("database.host")
	fmt.Printf("Database host: %s\n", host)

	// Check if a key exists
	if storage.Has("database.host") {
		fmt.Println("Database host exists")
	}
}

License

Apache License 2.0

Documentation

Overview

Package barky provides utilities for handling hierarchical key/value data structures that commonly appear in configuration formats such as JSON, YAML, or TOML. It is designed to transform nested data into a flat representation, while preserving enough metadata to reconstruct paths, detect conflicts, and manage data from multiple sources.

Key features include:

  • Flattening: Nested maps, slices, and arrays can be converted into a flat map[string]string using dot notation for maps and index notation for arrays/slices. For example, {"db": {"hosts": ["a", "b"]}} becomes {"db.hosts[0]": "a", "db.hosts[1]": "b"}.

  • Path handling: The package defines a Path abstraction that represents hierarchical keys as a sequence of typed segments (map keys or array indices). Paths can be split from strings like "foo.bar[0]" or joined back into their string form.

  • Storage: A Storage type manages a collection of flattened key/value pairs. It builds and maintains a hierarchical tree internally to prevent property conflicts (e.g., treating the same key as both a map and a value). Storage also associates values with the files they originated from, which allows multi-file merging and provenance tracking.

  • Querying: The Storage type provides helper methods for retrieving values, checking for the existence of keys, enumerating subkeys, and iterating in a deterministic order.

Typical use cases:

  • Normalizing configuration files from different sources into a flat key/value map for comparison, merging, or diffing.
  • Querying nested data using simple string paths without dealing with reflection or nested map structures directly.
  • Building tools that need to unify structured data from multiple files while preserving provenance information and preventing conflicts.

Overall, barky acts as a bridge between deeply nested structured data and flat, queryable representations that are easier to work with in configuration management, testing, or data transformation pipelines.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FlattenMap

func FlattenMap(m map[string]any) map[string]string

FlattenMap takes a nested map[string]any and flattens it into a map[string]string where nested structures are represented using dot-notation for maps and index-notation for slices/arrays. Nil values in maps are skipped (not included in the result). Nil elements in slices/arrays are preserved as empty strings. Empty maps/slices are represented as empty strings.

func FlattenValue

func FlattenValue(key string, val any, result map[string]string)

FlattenValue recursively flattens a value (map, slice, array, or primitive) into the result map under the given key. Nested structures are expanded using dot notation (for maps) and index notation (for slices/arrays).

func JoinPath

func JoinPath(path []Path) string

JoinPath converts a slice of Path objects into a string representation. Keys are joined with dots, and array indices are wrapped in square brackets. Example: [key, index(0), key] => "key[0].key".

func OrderedMapKeys

func OrderedMapKeys[M ~map[K]V, K cmp.Ordered, V any](m M) []K

OrderedMapKeys returns the sorted keys of a generic map with ordered keys. It is a utility function used to provide deterministic ordering of map keys.

Types

type Path

type Path struct {
	// Whether the element is a key or an index.
	Type PathType

	// Actual key or index value as a string.
	// For PathTypeKey, it's the key string;
	// for PathTypeIndex, it's the index number as a string.
	Elem string
}

Path represents a single segment in a parsed key path. A path is composed of multiple Path elements that can be joined or split. For example, "foo.bar[0]" parses into:

[{Type: PathTypeKey, Elem: "foo"},
 {Type: PathTypeKey, Elem: "bar"},
 {Type: PathTypeIndex, Elem: "0"}].

func SplitPath

func SplitPath(key string) (_ []Path, err error)

SplitPath parses a hierarchical key string into a slice of Path objects. It supports dot-notation for maps and bracket-notation for arrays. Examples:

"foo.bar[0]" -> [{Key:"foo"}, {Key:"bar"}, {Index:"0"}]
"a[1][2]"    -> [{Key:"a"}, {Index:"1"}, {Index:"2"}]

Rules:

  • Keys must be non-empty strings without spaces.
  • Indices must be unsigned integers (no sign, no decimal).
  • Empty maps/slices are not special-cased here.
  • Returns an error if the key is malformed (e.g. unbalanced brackets, unexpected characters, or empty keys if disallowed).

type PathType

type PathType int8

PathType represents the type of a path element in a hierarchical key. A path element can either be a key (map field) or an index (array/slice element).

const (
	PathTypeKey   PathType = iota // A named key in a map.
	PathTypeIndex                 // A numeric index in a list.
)

type Storage

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

Storage manages a collection of flattened key/value pairs while preserving hierarchical structure for validation and queries. It tracks both values and the files they come from, and prevents structural conflicts when setting values.

func NewStorage

func NewStorage() *Storage

NewStorage creates a new Storage instance.

func (*Storage) AddFile

func (s *Storage) AddFile(file string) int8

AddFile registers a file name into the storage, assigning it a unique int8 index if it has not been added before. The index is assigned incrementally starting from 0. Returns the index of the file.

func (*Storage) Data

func (s *Storage) Data() map[string]string

Data returns a simplified map of flattened key → string value, discarding file index information.

func (*Storage) Get

func (s *Storage) Get(key string, def ...string) string

Get retrieves the value associated with a key. If the key is not found and a default value is provided, the default is returned instead. If multiple default values are provided, only the first one is used.

func (*Storage) Has

func (s *Storage) Has(key string) bool

Has checks whether a key (or nested structure) exists in the storage. Returns false if the key is invalid or conflicts with existing structure.

func (*Storage) Keys

func (s *Storage) Keys() []string

Keys returns all flattened keys currently stored, sorted in lexicographic order.

func (*Storage) RawData

func (s *Storage) RawData() map[string]ValueInfo

RawData returns the internal map of flattened key → ValueInfo, Warning: exposes internal state directly.

func (*Storage) RawFile

func (s *Storage) RawFile() map[string]int8

RawFile returns the internal mapping of file names to their assigned indexes. Warning: exposes internal state directly.

func (*Storage) Set

func (s *Storage) Set(key string, val string, file int8) error

Set inserts or updates a key with the given value and file index. It ensures that the key path is valid and does not conflict with existing structure types. Returns an error if conflicts are detected.

func (*Storage) SubKeys

func (s *Storage) SubKeys(key string) (_ []string, err error)

SubKeys retrieves the immediate child keys under the given path. For example, given "a.b", it returns the keys directly under "a.b". Returns an error if the path is invalid or conflicts exist.

type ValueInfo

type ValueInfo struct {
	File  int8
	Value string
}

ValueInfo stores metadata about a flattened value in Storage. It includes both the string value and the file index that the value originated from.

Jump to

Keyboard shortcuts

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