Documentation
¶
Overview ¶
Package config provides bounded Hujson config reads and patch operations.
It accepts Hujson on reads, enforces a finite byte cap at the read boundary, and applies RFC 6902 patches through the Hujson AST so comments survive human-maintained config mutations.
Index ¶
- Constants
- func Parse(ctx context.Context, r io.Reader, dst any, opts ...Option) error
- func ParseFile(ctx context.Context, path string, dst any, opts ...Option) error
- func Patch(ctx context.Context, r io.Reader, patch []byte, opts ...Option) ([]byte, error)
- func PatchFile(ctx context.Context, path string, patch []byte, opts ...Option) error
- type Option
Examples ¶
Constants ¶
View Source
const ( // DefaultMaxBytes is the default maximum config size: 1 MiB. DefaultMaxBytes int64 = 1 << 20 // MaxBytesCeiling is the largest valid config read limit: 1 GiB. MaxBytesCeiling int64 = internalconfig.MaxConfigBytesCeiling )
Variables ¶
This section is empty.
Functions ¶
func Parse ¶
Parse parses Hujson from r under a bounded read cap and unmarshals into dst.
Example ¶
package main
import (
"context"
"fmt"
"strings"
"github.com/rshade/ax-go/config"
)
func main() {
const hujson = `{
// comments and trailing commas are allowed on reads
"name": "ax",
"replicas": 3,
}`
var cfg struct {
Name string `json:"name"`
Replicas int `json:"replicas"`
}
if err := config.Parse(
context.Background(),
strings.NewReader(hujson),
&cfg,
config.WithMaxBytes(1<<10),
); err != nil {
fmt.Println("error:", err)
return
}
fmt.Printf("%s x%d\n", cfg.Name, cfg.Replicas)
}
Output: ax x3
func ParseFile ¶
ParseFile opens path and applies Parse's contract to its contents.
Example ¶
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"github.com/rshade/ax-go/config"
)
func main() {
dir, err := os.MkdirTemp("", "ax-config")
if err != nil {
fmt.Println("error:", err)
return
}
defer os.RemoveAll(dir)
path := filepath.Join(dir, "config.hujson")
if err := os.WriteFile(path, []byte(`{"name": "ax"}`), 0o600); err != nil {
fmt.Println("error:", err)
return
}
var cfg struct {
Name string `json:"name"`
}
if err := config.ParseFile(context.Background(), path, &cfg); err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(cfg.Name)
}
Output: ax
func Patch ¶
Patch reads Hujson from r, applies RFC 6902 JSON patch operations, and returns patched Hujson content with comments preserved.
Example ¶
package main
import (
"context"
"fmt"
"strings"
"github.com/rshade/ax-go/config"
)
func main() {
const existing = `{
// service endpoint
"host": "localhost",
"port": 8080,
}`
patch := []byte(`[{"op":"replace","path":"/port","value":9090}]`)
patched, err := config.Patch(
context.Background(),
strings.NewReader(existing),
patch,
)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(strings.Contains(string(patched), "// service endpoint"))
fmt.Println(strings.Contains(string(patched), "9090"))
}
Output: true true
func PatchFile ¶
PatchFile reads path as Hujson, applies RFC 6902 patch operations, and writes the patched result back to path atomically.
Example ¶
package main
import (
"context"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/rshade/ax-go/config"
)
func main() {
dir, err := os.MkdirTemp("", "ax-patch")
if err != nil {
fmt.Println("error:", err)
return
}
defer os.RemoveAll(dir)
path := filepath.Join(dir, "config.hujson")
initial := []byte(`{
// production endpoint
"host": "prod.example.com",
"port": 443,
}`)
if err := os.WriteFile(path, initial, 0o600); err != nil {
fmt.Println("error:", err)
return
}
patch := []byte(`[{"op":"replace","path":"/port","value":8443}]`)
if err := config.PatchFile(context.Background(), path, patch); err != nil {
fmt.Println("error:", err)
return
}
result, err := os.ReadFile(path)
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println(strings.Contains(string(result), "// production endpoint"))
fmt.Println(strings.Contains(string(result), "8443"))
}
Output: true true
Types ¶
Click to show internal directories.
Click to hide internal directories.