Documentation
¶
Overview ¶
Package fj (Fast JSON) provides a fast and simple way to retrieve, query, and transform values from a JSON document without unmarshalling the entire structure into Go types.
fj uses a dot-notation path syntax supporting wildcards, array indexing, conditional queries, multi-selectors, pipe operators, and a rich set of built-in transformers. Custom transformers can be registered at runtime.
Path Syntax ¶
user.name → object field access
roles.0.name → array index access
roles.#.name → iterate all array elements
roles.#(roleName=="Admin").roleId → conditional query
name.@uppercase → built-in transformer
name.@word:upper → transformer with argument
{id,name} → multi-selector (new object)
[id,name] → multi-selector (new array)
Basic Usage ¶
ctx := fj.Get(json, "user.roles.#.roleName") fmt.Println(ctx.String()) // ["Admin","Editor"]
Custom Transformers ¶
fj.AddTransformer("word", func(json, arg string) string {
if arg == "upper" { return strings.ToUpper(json) }
return json
})
fj is safe for concurrent use by multiple goroutines.
Index ¶
- Variables
- func AddTransformer(name string, t Transformer)
- func Avg(json, path string) (float64, bool)
- func CoerceTo(ctx Context, into any) error
- func CollectFloat64(json, path string) []float64
- func Contains(json, path, target string) bool
- func ContainsMatch(json, path, pattern string) bool
- func Count(json, path string) int
- func FindPath(json, value string) string
- func FindPathMatch(json, valuePattern string) string
- func FindPaths(json, value string) []string
- func FindPathsMatch(json, valuePattern string) []string
- func Foreach(json string, iterator func(line Context) bool)
- func GroupBy(json, path, keyField string) map[string][]Context
- func IsTransformerRegistered(name string) bool
- func IsValidJSON(json string) bool
- func IsValidJSONBytes(json []byte) bool
- func Max(json, path string) (float64, bool)
- func MaxFloat32(json, path string) (float32, bool)
- func MaxInt(json, path string) (int, bool)
- func MaxInt8(json, path string) (int8, bool)
- func MaxInt16(json, path string) (int16, bool)
- func MaxInt32(json, path string) (int32, bool)
- func MaxInt64(json, path string) (int64, bool)
- func MaxUint(json, path string) (uint, bool)
- func MaxUint8(json, path string) (uint8, bool)
- func Min(json, path string) (float64, bool)
- func MinFloat32(json, path string) (float32, bool)
- func MinInt(json, path string) (int, bool)
- func MinInt8(json, path string) (int8, bool)
- func MinInt16(json, path string) (int16, bool)
- func MinInt32(json, path string) (int32, bool)
- func MinInt64(json, path string) (int64, bool)
- func MinUint(json, path string) (uint, bool)
- func MinUint8(json, path string) (uint8, bool)
- func MinUint16(json, path string) (uint16, bool)
- func MinUint32(json, path string) (uint32, bool)
- func MinUint64(json, path string) (uint64, bool)
- func Sum(json, path string) float64
- func SumFloat32(json, path string) float32
- func SumInt(json, path string) int
- func SumInt8(json, path string) int8
- func SumInt16(json, path string) int16
- func SumInt32(json, path string) int32
- func SumInt64(json, path string) int64
- func SumUint(json, path string) uint
- func SumUint8(json, path string) uint8
- func SumUint16(json, path string) uint16
- func SumUint32(json, path string) uint32
- func SumUint64(json, path string) uint64
- func UnsafeBytes(s string) []byte
- type Context
- func Distinct(json, path string) []Context
- func Filter(json, path string, fn func(Context) bool) []Context
- func First(json, path string, fn func(Context) bool) Context
- func Get(json, path string) Context
- func GetBytes(json []byte, path string) Context
- func GetBytesMulti(json []byte, path ...string) []Context
- func GetMulti(json string, path ...string) []Context
- func Parse(json string) Context
- func ParseBytes(json []byte) Context
- func ParseJSONFile(filepath string) Context
- func ParseReader(in io.Reader) Context
- func Pluck(json, path string, fields ...string) []Context
- func Search(json, keyword string) []Context
- func SearchByKey(json string, keys ...string) []Context
- func SearchByKeyPattern(json, keyPattern string) []Context
- func SearchMatch(json, pattern string) []Context
- func SortBy(json, path, keyField string, ascending bool) []Context
- func (ctx Context) Array() []Context
- func (ctx Context) Bool() bool
- func (ctx Context) Cause() string
- func (ctx Context) Duration() time.Duration
- func (ctx Context) Exists() bool
- func (ctx Context) Float32() float32
- func (ctx Context) Float64() float64
- func (ctx Context) Foreach(iterator func(key, value Context) bool)
- func (ctx Context) Get(path string) Context
- func (ctx Context) GetMulti(path ...string) []Context
- func (ctx Context) Index() int
- func (ctx Context) Indexes() []int
- func (ctx Context) Int() int
- func (ctx Context) Int8() int8
- func (ctx Context) Int16() int16
- func (ctx Context) Int32() int32
- func (ctx Context) Int64() int64
- func (ctx Context) IsArray() bool
- func (ctx Context) IsBool() bool
- func (ctx Context) IsError() bool
- func (ctx Context) IsObject() bool
- func (ctx Context) Kind() Type
- func (ctx Context) Less(token Context, caseSensitive bool) bool
- func (ctx Context) Map() map[string]Context
- func (ctx Context) Number() float64
- func (ctx Context) Path(json string) string
- func (ctx Context) Paths(json string) []string
- func (ctx Context) Raw() string
- func (ctx Context) String() string
- func (ctx Context) StringColored() string
- func (ctx Context) Time() time.Time
- func (ctx Context) Uint() uint
- func (ctx Context) Uint8() uint8
- func (ctx Context) Uint16() uint16
- func (ctx Context) Uint32() uint32
- func (ctx Context) Uint64() uint64
- func (ctx Context) Value() any
- func (ctx Context) WithStringColored(style *encoding.Style) string
- func (ctx Context) WithTime(format string) (time.Time, error)
- type Transformer
- type TransformerFunc
- type Type
Constants ¶
This section is empty.
Variables ¶
var ( // DarkStyle uses darker tones for styling. DarkStyle = &encoding.Style{ Key: [2]string{"\033[38;5;25m", "\033[0m"}, String: [2]string{"\033[38;5;34m", "\033[0m"}, Number: [2]string{"\033[38;5;178m", "\033[0m"}, True: [2]string{"\033[38;5;127m", "\033[0m"}, False: [2]string{"\033[38;5;127m", "\033[0m"}, Null: [2]string{"\033[38;5;127m", "\033[0m"}, Escape: [2]string{"\033[38;5;124m", "\033[0m"}, Brackets: [2]string{"\033[38;5;245m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // NeonStyle is a vibrant style using neon-like colors. NeonStyle = &encoding.Style{ Key: [2]string{"\033[1;96m", "\033[0m"}, String: [2]string{"\033[1;92m", "\033[0m"}, Number: [2]string{"\033[1;93m", "\033[0m"}, True: [2]string{"\033[1;95m", "\033[0m"}, False: [2]string{"\033[1;95m", "\033[0m"}, Null: [2]string{"\033[1;95m", "\033[0m"}, Escape: [2]string{"\033[1;91m", "\033[0m"}, Brackets: [2]string{"\033[1;97m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // PastelStyle applies softer colors for a subdued look. PastelStyle = &encoding.Style{ Key: [2]string{"\033[38;5;152m", "\033[0m"}, String: [2]string{"\033[38;5;121m", "\033[0m"}, Number: [2]string{"\033[38;5;180m", "\033[0m"}, True: [2]string{"\033[38;5;139m", "\033[0m"}, False: [2]string{"\033[38;5;139m", "\033[0m"}, Null: [2]string{"\033[38;5;139m", "\033[0m"}, Escape: [2]string{"\033[38;5;167m", "\033[0m"}, Brackets: [2]string{"\033[38;5;253m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // HighContrastStyle uses bold and contrasting colors for better visibility. HighContrastStyle = &encoding.Style{ Key: [2]string{"\033[1;37;44m", "\033[0m"}, String: [2]string{"\033[1;37;42m", "\033[0m"}, Number: [2]string{"\033[1;37;43m", "\033[0m"}, True: [2]string{"\033[1;37;45m", "\033[0m"}, False: [2]string{"\033[1;37;45m", "\033[0m"}, Null: [2]string{"\033[1;37;45m", "\033[0m"}, Escape: [2]string{"\033[1;37;41m", "\033[0m"}, Brackets: [2]string{"\033[1;30;47m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VintageStyle uses muted tones reminiscent of old terminal displays. VintageStyle = &encoding.Style{ Key: [2]string{"\033[38;5;94m", "\033[0m"}, String: [2]string{"\033[38;5;130m", "\033[0m"}, Number: [2]string{"\033[38;5;136m", "\033[0m"}, True: [2]string{"\033[38;5;95m", "\033[0m"}, False: [2]string{"\033[38;5;95m", "\033[0m"}, Null: [2]string{"\033[38;5;95m", "\033[0m"}, Escape: [2]string{"\033[38;5;124m", "\033[0m"}, Brackets: [2]string{"\033[38;5;242m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // CyberpunkStyle mimics a futuristic neon cyberpunk aesthetic. CyberpunkStyle = &encoding.Style{ Key: [2]string{"\033[1;35;45m", "\033[0m"}, String: [2]string{"\033[1;36;46m", "\033[0m"}, Number: [2]string{"\033[1;33;43m", "\033[0m"}, True: [2]string{"\033[1;32;42m", "\033[0m"}, False: [2]string{"\033[1;31;41m", "\033[0m"}, Null: [2]string{"\033[1;37;40m", "\033[0m"}, Escape: [2]string{"\033[1;31;41m", "\033[0m"}, Brackets: [2]string{"\033[1;30;47m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // OceanStyle is inspired by oceanic hues and soft contrasts. OceanStyle = &encoding.Style{ Key: [2]string{"\033[38;5;27m", "\033[0m"}, String: [2]string{"\033[38;5;45m", "\033[0m"}, Number: [2]string{"\033[38;5;33m", "\033[0m"}, True: [2]string{"\033[38;5;77m", "\033[0m"}, False: [2]string{"\033[38;5;77m", "\033[0m"}, Null: [2]string{"\033[38;5;67m", "\033[0m"}, Escape: [2]string{"\033[38;5;196m", "\033[0m"}, Brackets: [2]string{"\033[38;5;15m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // FieryStyle uses intense warm colors like flames. FieryStyle = &encoding.Style{ Key: [2]string{"\033[38;5;166m", "\033[0m"}, String: [2]string{"\033[38;5;202m", "\033[0m"}, Number: [2]string{"\033[38;5;220m", "\033[0m"}, True: [2]string{"\033[38;5;214m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;196m", "\033[0m"}, Escape: [2]string{"\033[38;5;124m", "\033[0m"}, Brackets: [2]string{"\033[38;5;244m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // GalaxyStyle uses space-themed colors with a starry effect. GalaxyStyle = &encoding.Style{ Key: [2]string{"\033[38;5;57m", "\033[0m"}, String: [2]string{"\033[38;5;93m", "\033[0m"}, Number: [2]string{"\033[38;5;141m", "\033[0m"}, True: [2]string{"\033[38;5;219m", "\033[0m"}, False: [2]string{"\033[38;5;219m", "\033[0m"}, Null: [2]string{"\033[38;5;250m", "\033[0m"}, Escape: [2]string{"\033[38;5;129m", "\033[0m"}, Brackets: [2]string{"\033[38;5;244m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // SunsetStyle mimics the colors of a sunset, using warm hues and deep purples. SunsetStyle = &encoding.Style{ Key: [2]string{"\033[38;5;214m", "\033[0m"}, String: [2]string{"\033[38;5;213m", "\033[0m"}, Number: [2]string{"\033[38;5;178m", "\033[0m"}, True: [2]string{"\033[38;5;229m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;236m", "\033[0m"}, Escape: [2]string{"\033[38;5;202m", "\033[0m"}, Brackets: [2]string{"\033[38;5;15m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // JungleStyle draws inspiration from a dense jungle with deep greens and browns. JungleStyle = &encoding.Style{ Key: [2]string{"\033[38;5;22m", "\033[0m"}, String: [2]string{"\033[38;5;28m", "\033[0m"}, Number: [2]string{"\033[38;5;130m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;166m", "\033[0m"}, Null: [2]string{"\033[38;5;143m", "\033[0m"}, Escape: [2]string{"\033[38;5;94m", "\033[0m"}, Brackets: [2]string{"\033[38;5;23m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // MonochromeStyle uses different shades of black and white for a simple, high-contrast theme. MonochromeStyle = &encoding.Style{ Key: [2]string{"\033[38;5;235m", "\033[0m"}, String: [2]string{"\033[38;5;255m", "\033[0m"}, Number: [2]string{"\033[38;5;240m", "\033[0m"}, True: [2]string{"\033[38;5;255m", "\033[0m"}, False: [2]string{"\033[38;5;232m", "\033[0m"}, Null: [2]string{"\033[38;5;243m", "\033[0m"}, Escape: [2]string{"\033[38;5;237m", "\033[0m"}, Brackets: [2]string{"\033[38;5;255m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ForestStyle uses deep greens and browns to create a natural, earthy look. ForestStyle = &encoding.Style{ Key: [2]string{"\033[38;5;28m", "\033[0m"}, String: [2]string{"\033[38;5;35m", "\033[0m"}, Number: [2]string{"\033[38;5;130m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;88m", "\033[0m"}, Null: [2]string{"\033[38;5;102m", "\033[0m"}, Escape: [2]string{"\033[38;5;136m", "\033[0m"}, Brackets: [2]string{"\033[38;5;24m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // IceStyle brings a cool, frosty aesthetic with blues and whites. IceStyle = &encoding.Style{ Key: [2]string{"\033[38;5;63m", "\033[0m"}, String: [2]string{"\033[38;5;159m", "\033[0m"}, Number: [2]string{"\033[38;5;81m", "\033[0m"}, True: [2]string{"\033[38;5;39m", "\033[0m"}, False: [2]string{"\033[38;5;35m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;44m", "\033[0m"}, Brackets: [2]string{"\033[38;5;66m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // RetroStyle brings back the vibrant colors from older computer systems and arcade games. RetroStyle = &encoding.Style{ Key: [2]string{"\033[1;38;5;208m", "\033[0m"}, String: [2]string{"\033[1;38;5;119m", "\033[0m"}, Number: [2]string{"\033[1;38;5;220m", "\033[0m"}, True: [2]string{"\033[1;38;5;51m", "\033[0m"}, False: [2]string{"\033[1;38;5;160m", "\033[0m"}, Null: [2]string{"\033[1;38;5;232m", "\033[0m"}, Escape: [2]string{"\033[1;38;5;161m", "\033[0m"}, Brackets: [2]string{"\033[1;38;5;227m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // AutumnStyle uses rich oranges, reds, and browns, evoking the colors of fall. AutumnStyle = &encoding.Style{ Key: [2]string{"\033[38;5;130m", "\033[0m"}, String: [2]string{"\033[38;5;214m", "\033[0m"}, Number: [2]string{"\033[38;5;52m", "\033[0m"}, True: [2]string{"\033[38;5;166m", "\033[0m"}, False: [2]string{"\033[38;5;88m", "\033[0m"}, Null: [2]string{"\033[38;5;240m", "\033[0m"}, Escape: [2]string{"\033[38;5;166m", "\033[0m"}, Brackets: [2]string{"\033[38;5;54m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // GothicStyle uses darker colors with a moody atmosphere, ideal for dark themes. GothicStyle = &encoding.Style{ Key: [2]string{"\033[38;5;235m", "\033[0m"}, String: [2]string{"\033[38;5;244m", "\033[0m"}, Number: [2]string{"\033[38;5;8m", "\033[0m"}, True: [2]string{"\033[38;5;68m", "\033[0m"}, False: [2]string{"\033[38;5;61m", "\033[0m"}, Null: [2]string{"\033[38;5;235m", "\033[0m"}, Escape: [2]string{"\033[38;5;16m", "\033[0m"}, Brackets: [2]string{"\033[38;5;232m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VaporWaveStyle embraces the retro aesthetics of vapor-wave, with bright neon and pastel colors. VaporWaveStyle = &encoding.Style{ Key: [2]string{"\033[38;5;219m", "\033[0m"}, String: [2]string{"\033[38;5;189m", "\033[0m"}, Number: [2]string{"\033[38;5;204m", "\033[0m"}, True: [2]string{"\033[38;5;207m", "\033[0m"}, False: [2]string{"\033[38;5;142m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;129m", "\033[0m"}, Brackets: [2]string{"\033[38;5;155m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VampireStyle brings dark and sinister colors, with a touch of red for a spooky theme. VampireStyle = &encoding.Style{ Key: [2]string{"\033[38;5;88m", "\033[0m"}, String: [2]string{"\033[38;5;124m", "\033[0m"}, Number: [2]string{"\033[38;5;16m", "\033[0m"}, True: [2]string{"\033[38;5;160m", "\033[0m"}, False: [2]string{"\033[38;5;88m", "\033[0m"}, Null: [2]string{"\033[38;5;16m", "\033[0m"}, Escape: [2]string{"\033[38;5;0m", "\033[0m"}, Brackets: [2]string{"\033[38;5;16m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // CarnivalStyle is inspired by a fun, bright carnival atmosphere, full of vivid, exciting colors. CarnivalStyle = &encoding.Style{ Key: [2]string{"\033[38;5;220m", "\033[0m"}, String: [2]string{"\033[38;5;204m", "\033[0m"}, Number: [2]string{"\033[38;5;202m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;214m", "\033[0m"}, Escape: [2]string{"\033[38;5;213m", "\033[0m"}, Brackets: [2]string{"\033[38;5;33m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // SteampunkStyle has a vintage industrial look with brass and copper colors. SteampunkStyle = &encoding.Style{ Key: [2]string{"\033[38;5;136m", "\033[0m"}, String: [2]string{"\033[38;5;214m", "\033[0m"}, Number: [2]string{"\033[38;5;130m", "\033[0m"}, True: [2]string{"\033[38;5;184m", "\033[0m"}, False: [2]string{"\033[38;5;52m", "\033[0m"}, Null: [2]string{"\033[38;5;94m", "\033[0m"}, Escape: [2]string{"\033[38;5;124m", "\033[0m"}, Brackets: [2]string{"\033[38;5;250m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // WoodlandStyle blends earthy tones with deep forest greens and browns. WoodlandStyle = &encoding.Style{ Key: [2]string{"\033[38;5;22m", "\033[0m"}, String: [2]string{"\033[38;5;36m", "\033[0m"}, Number: [2]string{"\033[38;5;130m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;143m", "\033[0m"}, Escape: [2]string{"\033[38;5;94m", "\033[0m"}, Brackets: [2]string{"\033[38;5;23m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // CandyStyle is bright, with pastel hues that resemble candy colors. CandyStyle = &encoding.Style{ Key: [2]string{"\033[38;5;218m", "\033[0m"}, String: [2]string{"\033[38;5;226m", "\033[0m"}, Number: [2]string{"\033[38;5;222m", "\033[0m"}, True: [2]string{"\033[38;5;45m", "\033[0m"}, False: [2]string{"\033[38;5;51m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;196m", "\033[0m"}, Brackets: [2]string{"\033[38;5;226m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // TwilightStyle brings in dusky, cool tones reminiscent of dusk. TwilightStyle = &encoding.Style{ Key: [2]string{"\033[38;5;54m", "\033[0m"}, String: [2]string{"\033[38;5;123m", "\033[0m"}, Number: [2]string{"\033[38;5;39m", "\033[0m"}, True: [2]string{"\033[38;5;108m", "\033[0m"}, False: [2]string{"\033[38;5;166m", "\033[0m"}, Null: [2]string{"\033[38;5;242m", "\033[0m"}, Escape: [2]string{"\033[38;5;124m", "\033[0m"}, Brackets: [2]string{"\033[38;5;239m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // EarthStyle reflects natural earthy colors with muted greens and browns. EarthStyle = &encoding.Style{ Key: [2]string{"\033[38;5;22m", "\033[0m"}, String: [2]string{"\033[38;5;130m", "\033[0m"}, Number: [2]string{"\033[38;5;52m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;208m", "\033[0m"}, Null: [2]string{"\033[38;5;130m", "\033[0m"}, Escape: [2]string{"\033[38;5;94m", "\033[0m"}, Brackets: [2]string{"\033[38;5;24m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ElectricStyle uses electric, bright neon colors for a futuristic vibe. ElectricStyle = &encoding.Style{ Key: [2]string{"\033[38;5;51m", "\033[0m"}, String: [2]string{"\033[38;5;87m", "\033[0m"}, Number: [2]string{"\033[38;5;93m", "\033[0m"}, True: [2]string{"\033[38;5;39m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;196m", "\033[0m"}, Brackets: [2]string{"\033[38;5;227m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // WitchingHourStyle combines deep purples with dark greens for a magical look. WitchingHourStyle = &encoding.Style{ Key: [2]string{"\033[38;5;128m", "\033[0m"}, String: [2]string{"\033[38;5;88m", "\033[0m"}, Number: [2]string{"\033[38;5;91m", "\033[0m"}, True: [2]string{"\033[38;5;24m", "\033[0m"}, False: [2]string{"\033[38;5;231m", "\033[0m"}, Null: [2]string{"\033[38;5;234m", "\033[0m"}, Escape: [2]string{"\033[38;5;29m", "\033[0m"}, Brackets: [2]string{"\033[38;5;102m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // MidnightStyle gives a mysterious and dark aesthetic, like a quiet midnight scene. MidnightStyle = &encoding.Style{ Key: [2]string{"\033[38;5;17m", "\033[0m"}, String: [2]string{"\033[38;5;73m", "\033[0m"}, Number: [2]string{"\033[38;5;135m", "\033[0m"}, True: [2]string{"\033[38;5;11m", "\033[0m"}, False: [2]string{"\033[38;5;124m", "\033[0m"}, Null: [2]string{"\033[38;5;244m", "\033[0m"}, Escape: [2]string{"\033[38;5;17m", "\033[0m"}, Brackets: [2]string{"\033[38;5;233m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // RetroFutureStyle combines retro tones with a futuristic neon palette for a vintage-tech feel. RetroFutureStyle = &encoding.Style{ Key: [2]string{"\033[1;38;5;214m", "\033[0m"}, String: [2]string{"\033[1;38;5;189m", "\033[0m"}, Number: [2]string{"\033[1;38;5;220m", "\033[0m"}, True: [2]string{"\033[1;38;5;49m", "\033[0m"}, False: [2]string{"\033[1;38;5;231m", "\033[0m"}, Null: [2]string{"\033[1;38;5;250m", "\033[0m"}, Escape: [2]string{"\033[1;38;5;135m", "\033[0m"}, Brackets: [2]string{"\033[1;38;5;254m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ForestMistStyle invokes the serene and cool vibes of a misty forest. ForestMistStyle = &encoding.Style{ Key: [2]string{"\033[38;5;22m", "\033[0m"}, String: [2]string{"\033[38;5;118m", "\033[0m"}, Number: [2]string{"\033[38;5;140m", "\033[0m"}, True: [2]string{"\033[38;5;45m", "\033[0m"}, False: [2]string{"\033[38;5;56m", "\033[0m"}, Null: [2]string{"\033[38;5;242m", "\033[0m"}, Escape: [2]string{"\033[38;5;235m", "\033[0m"}, Brackets: [2]string{"\033[38;5;249m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // PrismStyle offers a colorful, dazzling light prism effect for a modern, energetic look. PrismStyle = &encoding.Style{ Key: [2]string{"\033[38;5;39m", "\033[0m"}, String: [2]string{"\033[38;5;129m", "\033[0m"}, Number: [2]string{"\033[38;5;166m", "\033[0m"}, True: [2]string{"\033[38;5;51m", "\033[0m"}, False: [2]string{"\033[38;5;161m", "\033[0m"}, Null: [2]string{"\033[38;5;250m", "\033[0m"}, Escape: [2]string{"\033[38;5;33m", "\033[0m"}, Brackets: [2]string{"\033[38;5;15m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // SpringStyle brings the fresh, light colors of spring to life. SpringStyle = &encoding.Style{ Key: [2]string{"\033[38;5;82m", "\033[0m"}, String: [2]string{"\033[38;5;214m", "\033[0m"}, Number: [2]string{"\033[38;5;190m", "\033[0m"}, True: [2]string{"\033[38;5;87m", "\033[0m"}, False: [2]string{"\033[38;5;161m", "\033[0m"}, Null: [2]string{"\033[38;5;249m", "\033[0m"}, Escape: [2]string{"\033[38;5;33m", "\033[0m"}, Brackets: [2]string{"\033[38;5;255m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // DesertStyle evokes the warmth and serenity of a desert landscape. DesertStyle = &encoding.Style{ Key: [2]string{"\033[38;5;95m", "\033[0m"}, String: [2]string{"\033[38;5;130m", "\033[0m"}, Number: [2]string{"\033[38;5;137m", "\033[0m"}, True: [2]string{"\033[38;5;216m", "\033[0m"}, False: [2]string{"\033[38;5;197m", "\033[0m"}, Null: [2]string{"\033[38;5;248m", "\033[0m"}, Escape: [2]string{"\033[38;5;167m", "\033[0m"}, Brackets: [2]string{"\033[38;5;230m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // SolarFlareStyle uses vibrant oranges and fiery reds, inspired by the intense heat of the sun. SolarFlareStyle = &encoding.Style{ Key: [2]string{"\033[38;5;214m", "\033[0m"}, String: [2]string{"\033[38;5;196m", "\033[0m"}, Number: [2]string{"\033[38;5;226m", "\033[0m"}, True: [2]string{"\033[38;5;220m", "\033[0m"}, False: [2]string{"\033[38;5;161m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;203m", "\033[0m"}, Brackets: [2]string{"\033[38;5;208m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // IceQueenStyle reflects a cool, frosty appearance with icy blues and silvers. IceQueenStyle = &encoding.Style{ Key: [2]string{"\033[38;5;81m", "\033[0m"}, String: [2]string{"\033[38;5;153m", "\033[0m"}, Number: [2]string{"\033[38;5;77m", "\033[0m"}, True: [2]string{"\033[38;5;45m", "\033[0m"}, False: [2]string{"\033[38;5;250m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;59m", "\033[0m"}, Brackets: [2]string{"\033[38;5;96m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ForestGroveStyle brings earthy tones with a dense forest theme. ForestGroveStyle = &encoding.Style{ Key: [2]string{"\033[38;5;28m", "\033[0m"}, String: [2]string{"\033[38;5;48m", "\033[0m"}, Number: [2]string{"\033[38;5;130m", "\033[0m"}, True: [2]string{"\033[38;5;46m", "\033[0m"}, False: [2]string{"\033[38;5;238m", "\033[0m"}, Null: [2]string{"\033[38;5;144m", "\033[0m"}, Escape: [2]string{"\033[38;5;94m", "\033[0m"}, Brackets: [2]string{"\033[38;5;36m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // AutumnLeavesStyle uses warm, fall-inspired hues like browns, reds, and golden yellows. AutumnLeavesStyle = &encoding.Style{ Key: [2]string{"\033[38;5;130m", "\033[0m"}, String: [2]string{"\033[38;5;172m", "\033[0m"}, Number: [2]string{"\033[38;5;52m", "\033[0m"}, True: [2]string{"\033[38;5;214m", "\033[0m"}, False: [2]string{"\033[38;5;136m", "\033[0m"}, Null: [2]string{"\033[38;5;240m", "\033[0m"}, Escape: [2]string{"\033[38;5;217m", "\033[0m"}, Brackets: [2]string{"\033[38;5;95m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VaporStyle uses pastel tones and calming shades of pink, purple, and blue. VaporStyle = &encoding.Style{ Key: [2]string{"\033[38;5;189m", "\033[0m"}, String: [2]string{"\033[38;5;153m", "\033[0m"}, Number: [2]string{"\033[38;5;81m", "\033[0m"}, True: [2]string{"\033[38;5;159m", "\033[0m"}, False: [2]string{"\033[38;5;129m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;144m", "\033[0m"}, Brackets: [2]string{"\033[38;5;113m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // SunsetBoulevardStyle mimics the stunning colors of a sunset, featuring warm oranges, pinks, and purples. SunsetBoulevardStyle = &encoding.Style{ Key: [2]string{"\033[38;5;214m", "\033[0m"}, String: [2]string{"\033[38;5;205m", "\033[0m"}, Number: [2]string{"\033[38;5;93m", "\033[0m"}, True: [2]string{"\033[38;5;226m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;133m", "\033[0m"}, Brackets: [2]string{"\033[38;5;57m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // NeonCityStyle is bold and energetic, with electrifying neons of blue, pink, and green. NeonCityStyle = &encoding.Style{ Key: [2]string{"\033[38;5;51m", "\033[0m"}, String: [2]string{"\033[38;5;197m", "\033[0m"}, Number: [2]string{"\033[38;5;32m", "\033[0m"}, True: [2]string{"\033[38;5;82m", "\033[0m"}, False: [2]string{"\033[38;5;130m", "\033[0m"}, Null: [2]string{"\033[38;5;7m", "\033[0m"}, Escape: [2]string{"\033[38;5;21m", "\033[0m"}, Brackets: [2]string{"\033[38;5;93m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // MoonlitNightStyle gives a serene and calm atmosphere with cool blues and soft silvers. MoonlitNightStyle = &encoding.Style{ Key: [2]string{"\033[38;5;18m", "\033[0m"}, String: [2]string{"\033[38;5;153m", "\033[0m"}, Number: [2]string{"\033[38;5;110m", "\033[0m"}, True: [2]string{"\033[38;5;48m", "\033[0m"}, False: [2]string{"\033[38;5;238m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;73m", "\033[0m"}, Brackets: [2]string{"\033[38;5;99m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // CandyShopStyle features bright, sugary tones of pinks, blues, and yellows for a fun and sweet theme. CandyShopStyle = &encoding.Style{ Key: [2]string{"\033[38;5;219m", "\033[0m"}, String: [2]string{"\033[38;5;186m", "\033[0m"}, Number: [2]string{"\033[38;5;81m", "\033[0m"}, True: [2]string{"\033[38;5;112m", "\033[0m"}, False: [2]string{"\033[38;5;196m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;222m", "\033[0m"}, Brackets: [2]string{"\033[38;5;174m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // UnderwaterStyle is inspired by the deep ocean, featuring calming blues and aquatic greens. UnderwaterStyle = &encoding.Style{ Key: [2]string{"\033[38;5;32m", "\033[0m"}, String: [2]string{"\033[38;5;51m", "\033[0m"}, Number: [2]string{"\033[38;5;39m", "\033[0m"}, True: [2]string{"\033[38;5;33m", "\033[0m"}, False: [2]string{"\033[38;5;236m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;73m", "\033[0m"}, Brackets: [2]string{"\033[38;5;45m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // OceanBreezeStyle reflects the calm and refreshing hues of the ocean. OceanBreezeStyle = &encoding.Style{ Key: [2]string{"\033[38;5;33m", "\033[0m"}, String: [2]string{"\033[38;5;75m", "\033[0m"}, Number: [2]string{"\033[38;5;51m", "\033[0m"}, True: [2]string{"\033[38;5;44m", "\033[0m"}, False: [2]string{"\033[38;5;61m", "\033[0m"}, Null: [2]string{"\033[38;5;250m", "\033[0m"}, Escape: [2]string{"\033[38;5;32m", "\033[0m"}, Brackets: [2]string{"\033[38;5;244m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // CandyPopStyle brings a playful and sweet color palette, like a candy store. CandyPopStyle = &encoding.Style{ Key: [2]string{"\033[38;5;201m", "\033[0m"}, String: [2]string{"\033[38;5;207m", "\033[0m"}, Number: [2]string{"\033[38;5;220m", "\033[0m"}, True: [2]string{"\033[38;5;51m", "\033[0m"}, False: [2]string{"\033[38;5;160m", "\033[0m"}, Null: [2]string{"\033[38;5;248m", "\033[0m"}, Escape: [2]string{"\033[38;5;33m", "\033[0m"}, Brackets: [2]string{"\033[38;5;255m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // NoirStyle gives a film-noir inspired look with dark, moody colors. NoirStyle = &encoding.Style{ Key: [2]string{"\033[38;5;16m", "\033[0m"}, String: [2]string{"\033[38;5;249m", "\033[0m"}, Number: [2]string{"\033[38;5;235m", "\033[0m"}, True: [2]string{"\033[38;5;231m", "\033[0m"}, False: [2]string{"\033[38;5;242m", "\033[0m"}, Null: [2]string{"\033[38;5;233m", "\033[0m"}, Escape: [2]string{"\033[38;5;245m", "\033[0m"}, Brackets: [2]string{"\033[38;5;255m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // GalacticStyle evokes the mysterious vastness of outer space with deep, cosmic hues. GalacticStyle = &encoding.Style{ Key: [2]string{"\033[38;5;54m", "\033[0m"}, String: [2]string{"\033[38;5;92m", "\033[0m"}, Number: [2]string{"\033[38;5;129m", "\033[0m"}, True: [2]string{"\033[38;5;106m", "\033[0m"}, False: [2]string{"\033[38;5;166m", "\033[0m"}, Null: [2]string{"\033[38;5;233m", "\033[0m"}, Escape: [2]string{"\033[38;5;25m", "\033[0m"}, Brackets: [2]string{"\033[38;5;247m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VintagePastelStyle offers a retro aesthetic with soft, pastel tones for a gentle, nostalgic atmosphere. VintagePastelStyle = &encoding.Style{ Key: [2]string{"\033[38;5;213m", "\033[0m"}, String: [2]string{"\033[38;5;187m", "\033[0m"}, Number: [2]string{"\033[38;5;153m", "\033[0m"}, True: [2]string{"\033[38;5;79m", "\033[0m"}, False: [2]string{"\033[38;5;226m", "\033[0m"}, Null: [2]string{"\033[38;5;248m", "\033[0m"}, Escape: [2]string{"\033[38;5;229m", "\033[0m"}, Brackets: [2]string{"\033[38;5;245m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // VintageFilmStyle is inspired by the golden era of cinema, featuring muted golds, sepias, and classic black. VintageFilmStyle = &encoding.Style{ Key: [2]string{"\033[38;5;220m", "\033[0m"}, String: [2]string{"\033[38;5;138m", "\033[0m"}, Number: [2]string{"\033[38;5;239m", "\033[0m"}, True: [2]string{"\033[38;5;220m", "\033[0m"}, False: [2]string{"\033[38;5;58m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;167m", "\033[0m"}, Brackets: [2]string{"\033[38;5;59m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // FireworksStyle captures the excitement of a night sky lit up by colorful fireworks, featuring bold reds, yellows, and purples. FireworksStyle = &encoding.Style{ Key: [2]string{"\033[38;5;196m", "\033[0m"}, String: [2]string{"\033[38;5;226m", "\033[0m"}, Number: [2]string{"\033[38;5;57m", "\033[0m"}, True: [2]string{"\033[38;5;196m", "\033[0m"}, False: [2]string{"\033[38;5;11m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;201m", "\033[0m"}, Brackets: [2]string{"\033[38;5;93m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ArcticSnowStyle brings the cool, crisp whites and icy blues of the arctic tundra into the design. ArcticSnowStyle = &encoding.Style{ Key: [2]string{"\033[38;5;15m", "\033[0m"}, String: [2]string{"\033[38;5;45m", "\033[0m"}, Number: [2]string{"\033[38;5;33m", "\033[0m"}, True: [2]string{"\033[38;5;8m", "\033[0m"}, False: [2]string{"\033[38;5;7m", "\033[0m"}, Null: [2]string{"\033[38;5;255m", "\033[0m"}, Escape: [2]string{"\033[38;5;153m", "\033[0m"}, Brackets: [2]string{"\033[38;5;75m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // ElectricVibeStyle takes on high-energy neon tones with a touch of electric brightness. ElectricVibeStyle = &encoding.Style{ Key: [2]string{"\033[38;5;27m", "\033[0m"}, String: [2]string{"\033[38;5;51m", "\033[0m"}, Number: [2]string{"\033[38;5;51m", "\033[0m"}, True: [2]string{"\033[38;5;15m", "\033[0m"}, False: [2]string{"\033[38;5;196m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;57m", "\033[0m"}, Brackets: [2]string{"\033[38;5;99m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // DesertSunsetStyle brings warm and deep hues inspired by the desert landscape at sunset. DesertSunsetStyle = &encoding.Style{ Key: [2]string{"\033[38;5;216m", "\033[0m"}, String: [2]string{"\033[38;5;215m", "\033[0m"}, Number: [2]string{"\033[38;5;166m", "\033[0m"}, True: [2]string{"\033[38;5;130m", "\033[0m"}, False: [2]string{"\033[38;5;52m", "\033[0m"}, Null: [2]string{"\033[38;5;15m", "\033[0m"}, Escape: [2]string{"\033[38;5;58m", "\033[0m"}, Brackets: [2]string{"\033[38;5;94m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // PastelDreamStyle evokes a dreamy, soft pastel palette perfect for relaxed and whimsical visuals. PastelDreamStyle = &encoding.Style{ Key: [2]string{"\033[38;5;226m", "\033[0m"}, String: [2]string{"\033[38;5;193m", "\033[0m"}, Number: [2]string{"\033[38;5;153m", "\033[0m"}, True: [2]string{"\033[38;5;118m", "\033[0m"}, False: [2]string{"\033[38;5;189m", "\033[0m"}, Null: [2]string{"\033[38;5;248m", "\033[0m"}, Escape: [2]string{"\033[38;5;41m", "\033[0m"}, Brackets: [2]string{"\033[38;5;245m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } // TropicalVibeStyle draws inspiration from lush tropical jungles, with bright and vibrant greens and yellows. TropicalVibeStyle = &encoding.Style{ Key: [2]string{"\033[38;5;46m", "\033[0m"}, String: [2]string{"\033[38;5;220m", "\033[0m"}, Number: [2]string{"\033[38;5;118m", "\033[0m"}, True: [2]string{"\033[38;5;105m", "\033[0m"}, False: [2]string{"\033[38;5;55m", "\033[0m"}, Null: [2]string{"\033[38;5;250m", "\033[0m"}, Escape: [2]string{"\033[38;5;39m", "\033[0m"}, Brackets: [2]string{"\033[38;5;43m", "\033[0m"}, Append: func(dst []byte, c byte) []byte { return append(dst, c) }, } )
var ( // DisableTransformers is a global flag that determines whether transformers should be applied // when processing JSON values. If set to true, transformers will not be applied to the JSON values. // If set to false, transformers will be applied as expected. DisableTransformers = false )
Functions ¶
func AddTransformer ¶
func AddTransformer(name string, t Transformer)
AddTransformer registers a Transformer implementation under the given name in the global registry. Registering with an existing name overwrites the previous entry. This function is safe for concurrent use.
To register a plain function, wrap it with TransformerFunc:
fj.AddTransformer("upper", fj.TransformerFunc(func(json, arg string) string {
return strings.ToUpper(json)
}))
To register a struct-based implementation, pass a value that satisfies the Transformer interface:
type myTransformer struct{ prefix string }
func (t *myTransformer) Apply(json, arg string) string {
return t.prefix + json
}
fj.AddTransformer("prefixed", &myTransformer{prefix: "data:"})
func Avg ¶
Avg returns the arithmetic mean of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The average value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,30]}`
v, ok := fj.Avg(json, "scores") // 20.0, true
func CoerceTo ¶
CoerceTo converts the JSON value held in ctx into the Go variable pointed to by into, using the conv.Infer conversion engine. into must be a non-nil pointer to a supported type (bool, int*, uint*, float*, string, time.Time, slices, maps, or any struct with JSON-compatible fields).
This function provides a bridge between fj's Context values and Go's type system, enabling ergonomic extraction of typed values without manual type-assertion chains.
Parameters:
- ctx: The Context whose value should be coerced.
- into: A non-nil pointer to the target variable.
Returns:
- An error if the context has no value, or if the conversion fails.
Example:
ctx := fj.Get(json, "user.age")
var age int
if err := fj.CoerceTo(ctx, &age); err == nil {
fmt.Println(age) // 30
}
ctx = fj.Get(json, "user.active")
var active bool
_ = fj.CoerceTo(ctx, &active) // active == true
func CollectFloat64 ¶
CollectFloat64 evaluates path against json and returns a slice of float64 values for every element that can be coerced to a number by conv.Float64. This includes both JSON Number values and JSON strings that represent valid numbers (e.g., "42", "3.14").
Non-numeric elements for which conv.Float64 returns an error are silently skipped.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path resolving to an array or a single scalar.
Returns:
- A slice of float64 values. Returns an empty (non-nil) slice when no elements can be coerced to float64.
Example:
json := `{"data":["10","20.5",30,null,"skip"]}`
vals := fj.CollectFloat64(json, "data")
// vals == []float64{10, 20.5, 30}
func Contains ¶
Contains reports whether the result of querying json at path contains the given target substring (case-sensitive). If the path does not exist, Contains returns false.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
- target: The substring to look for within the string representation of the value found at path.
Returns:
- true if the value exists and its string representation contains target.
Example:
json := `{"msg":"hello world"}`
fj.Contains(json, "msg", "world") // true
fj.Contains(json, "msg", "xyz") // false
func ContainsMatch ¶
ContainsMatch reports whether the value at path in json matches the given wildcard pattern. If the path does not exist, ContainsMatch returns false.
The pattern follows the same syntax as match.Match:
- '*' matches any sequence of characters.
- '?' matches exactly one character.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
- pattern: A wildcard pattern applied to the string representation of the value.
Returns:
- true if the value exists and its string representation matches pattern.
Example:
json := `{"email":"alice@example.com"}`
fj.ContainsMatch(json, "email", "*@example.com") // true
fj.ContainsMatch(json, "email", "*@other.com") // false
func Count ¶
Count returns the number of elements returned by evaluating path against json. For a path that produces a JSON array the count equals the array length. For a path that produces a single scalar value, Count returns 1. For a missing or null result, Count returns 0.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The count of matching elements (≥ 0).
Example:
json := `{"tags":["go","json","fast"]}`
fj.Count(json, "tags") // 3
fj.Count(json, "tags.0") // 1
fj.Count(json, "missing")// 0
func FindPath ¶
FindPath returns the first dot-notation path in the JSON document at which the given scalar value can be found (case-sensitive, exact string match against Context.String()). Object keys and array indices are joined by ".".
FindPath only searches leaf (scalar) values. If no leaf matches, an empty string is returned.
Parameters:
- json: A well-formed JSON string.
- value: The scalar string value to locate.
Returns:
- The dot-notation path of the first matching leaf, or "" when not found.
Example:
json := `{"user":{"name":"Alice","age":30}}`
fj.FindPath(json, "Alice") // "user.name"
func FindPathMatch ¶
FindPathMatch returns the first dot-notation path in the JSON document at which a scalar value matches the given wildcard pattern. Object keys and array indices are joined with ".".
Only leaf (scalar) values are tested. If no leaf matches, an empty string is returned.
Parameters:
- json: A well-formed JSON string.
- valuePattern: A wildcard pattern applied to the string representation of each scalar leaf.
Returns:
- The dot-notation path of the first matching leaf, or "" when not found.
Example:
json := `{"users":[{"name":"Alice"},{"name":"Bob"}]}`
fj.FindPathMatch(json, "Ali*") // "users.0.name"
func FindPaths ¶
FindPaths returns the dot-notation paths for every leaf in the JSON document whose string representation exactly equals value (case-sensitive).
Parameters:
- json: A well-formed JSON string.
- value: The scalar string value to locate.
Returns:
- All matching paths in depth-first order. Returns an empty slice when there are no matches.
Example:
json := `{"a":"x","b":{"c":"x","d":"y"}}`
fj.FindPaths(json, "x") // ["a", "b.c"]
func FindPathsMatch ¶
FindPathsMatch returns the dot-notation paths for every scalar leaf in the JSON document whose string representation matches the given wildcard pattern.
Parameters:
- json: A well-formed JSON string.
- valuePattern: A wildcard pattern applied to the string representation of each scalar leaf.
Returns:
- All matching paths in depth-first order. Returns an empty slice when there are no matches.
Example:
json := `{"a":"Alice","b":{"c":"Albany","d":"Bob"}}`
fj.FindPathsMatch(json, "Al*") // ["a", "b.c"]
func Foreach ¶
Foreach iterates through each line of JSON data in the JSON Lines format (http://jsonlines.org/), and applies a provided iterator function to each line. This is useful for processing large JSON data sets where each line is a separate JSON object, allowing for efficient parsing and handling of each object.
Parameters:
- `json`: A string containing JSON Lines formatted data, where each line is a separate JSON object.
- `iterator`: A callback function that is called for each line. It receives a `Context` representing the parsed JSON object for the current line. The iterator function should return `true` to continue processing the next line, or `false` to stop the iteration.
Example Usage:
json := `{"name": "Alice"}\n{"name": "Bob"}`
iterator := func(line Context) bool {
fmt.Println(line)
return true
}
Foreach(json, iterator)
// Output:
// {"name": "Alice"}
// {"name": "Bob"}
Notes:
- This function assumes the input `json` is formatted as JSON Lines, where each line is a valid JSON object.
- The function stops processing as soon as the `iterator` function returns `false` for a line.
- The function handles each line independently, meaning it processes one JSON object at a time and provides it to the iterator, which can be used to process or filter lines.
Returns:
- This function does not return a value. It processes the JSON data line-by-line and applies the iterator to each.
func GroupBy ¶
GroupBy evaluates path against json, treats the result as an array of objects, and groups the elements by the string value of the specified keyField using conv.String for key normalization.
Elements that do not contain keyField, or for which the key cannot be converted to a string, are placed under the empty-string group "".
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path resolving to an array of objects.
- keyField: The object field whose value is used as the group key.
Returns:
- A map from group-key string to a slice of Context values in that group. Returns an empty map when path does not exist or the result is not an array.
Example:
json := `{"books":[
{"title":"Clean Code","genre":"tech"},
{"title":"Dune","genre":"fiction"},
{"title":"The Go Book","genre":"tech"}
]}`
groups := fj.GroupBy(json, "books", "genre")
// groups["tech"] → 2 elements
// groups["fiction"] → 1 element
func IsTransformerRegistered ¶
IsTransformerRegistered reports whether a transformer with the given name has been registered in the global registry.
This function is safe for concurrent use by multiple goroutines.
func IsValidJSON ¶
IsValidJSON checks whether the provided string contains valid JSON data. It attempts to parse the JSON and returns a boolean indicating if the JSON is well-formed.
Parameters:
- `json`: A string representing the JSON data that needs to be validated.
Returns:
- A boolean value (`true` or `false`):
- `true`: The provided JSON string is valid and well-formed.
- `false`: The provided JSON string is invalid or malformed.
Notes:
- This function utilizes the `fromStr2Bytes` function to efficiently convert the input string into a byte slice without allocating new memory. It then passes the byte slice to the `verifyJSON` function to check if the string conforms to valid JSON syntax.
- If the input JSON is invalid, the function will return `false`, indicating that the JSON cannot be parsed or is improperly structured.
- The function does not perform deep validation of the content of the JSON, but merely checks if the string is syntactically correct according to JSON rules.
Example Usage:
json := `{"name": {"first": "Alice", "last": "Johnson"}, "age": 30}`
if !IsValidJSON(json) {
fmt.Println("Invalid JSON")
} else {
fmt.Println("IsValidJSON JSON")
}
// Output: "IsValidJSON JSON"
func IsValidJSONBytes ¶
IsValidJSONBytes checks whether the provided byte slice contains valid JSON data. It attempts to parse the JSON and returns a boolean indicating if the JSON is well-formed.
Parameters:
- `json`: A byte slice (`[]byte`) representing the JSON data that needs to be validated.
Returns:
- A boolean value (`true` or `false`):
- `true`: The provided JSON byte slice is valid and well-formed.
- `false`: The provided JSON byte slice is invalid or malformed.
Notes:
- This function works directly with a byte slice (`[]byte`) rather than a string, making it more efficient when dealing with raw byte data that represents JSON. It avoids the need to convert between strings and byte slices, which can improve performance and memory usage when working with large or binary JSON data.
- The function utilizes the `verifyJSON` function to check if the byte slice conforms to valid JSON syntax.
- If the input byte slice represents invalid JSON, the function will return `false`, indicating that the JSON cannot be parsed or is improperly structured.
- The function does not perform deep validation of the content of the JSON, but only checks whether the byte slice adheres to the syntax rules defined for JSON data structures.
Example Usage:
jsonBytes := []byte(`{"name": {"first": "Alice", "last": "Johnson"}, "age": 30}`)
if !IsValidJSONBytes(jsonBytes) {
fmt.Println("Invalid JSON")
} else {
fmt.Println("Valid JSON")
}
// Output: "Valid JSON"
func Max ¶
Max returns the maximum numeric value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.Max(json, "scores") // 30.0, true
func MaxFloat32 ¶
MaxFloat32 returns the maximum numeric value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxFloat32(json, "scores") // 30.0, true
func MaxInt ¶
MaxInt returns the maximum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxInt(json, "scores") // 30, true
func MaxInt8 ¶
MaxInt8 returns the maximum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxInt8(json, "scores") // 30, true
func MaxInt16 ¶
MaxInt16 returns the maximum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxInt16(json, "scores") // 30, true
func MaxInt32 ¶
MaxInt32 returns the maximum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxInt32(json, "scores") // 30, true
func MaxInt64 ¶
MaxInt64 returns the maximum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxInt64(json, "scores") // 30, true
func MaxUint ¶
MaxUint returns the maximum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxUint(json, "scores") // 30, true
func MaxUint8 ¶
MaxUint8 returns the maximum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The maximum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MaxUint8(json, "scores") // 30, true
func Min ¶
Min returns the minimum numeric value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.Min(json, "scores") // 5.0, true
func MinFloat32 ¶
MinFloat32 returns the minimum numeric value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinFloat32(json, "scores") // 5.0, true
func MinInt ¶
MinInt returns the minimum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinInt(json, "scores") // 5, true
func MinInt8 ¶
MinInt8 returns the minimum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinInt8(json, "scores") // 5, true
func MinInt16 ¶
MinInt16 returns the minimum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinInt16(json, "scores") // 5, true
func MinInt32 ¶
MinInt32 returns the minimum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinInt32(json, "scores") // 5, true
func MinInt64 ¶
MinInt64 returns the minimum integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinInt64(json, "scores") // 5, true
func MinUint ¶
MinUint returns the minimum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinUint(json, "scores") // 5, true
func MinUint8 ¶
MinUint8 returns the minimum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinUint8(json, "scores") // 5, true
func MinUint16 ¶
MinUint16 returns the minimum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinUint16(json, "scores") // 5, true
func MinUint32 ¶
MinUint32 returns the minimum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinUint32(json, "scores") // 5, true
func MinUint64 ¶
MinUint64 returns the minimum unsigned integer value among all results produced by evaluating path against json. Non-numeric results are silently ignored.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- The minimum value and true when at least one number is found.
- 0 and false when no numeric values are found.
Example:
json := `{"scores":[10,20,5,30]}`
v, ok := fj.MinUint64(json, "scores") // 5, true
func Sum ¶
Sum returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as float64.
Example:
json := `{"scores":[10,20,30]}`
fj.Sum(json, "scores") // 60.0
func SumFloat32 ¶
SumFloat32 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as float32.
Example:
json := `{"scores":[10,20,30]}`
fj.SumFloat32(json, "scores") // 60.0
func SumInt ¶
SumInt returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as int.
Example:
json := `{"scores":[10,20,30]}`
fj.SumInt(json, "scores") // 60
func SumInt8 ¶
SumInt8 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as int8.
Example:
json := `{"scores":[10,20,30]}`
fj.SumInt8(json, "scores") // 60
func SumInt16 ¶
SumInt16 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as int16.
Example:
json := `{"scores":[10,20,30]}`
fj.SumInt16(json, "scores") // 60
func SumInt32 ¶
SumInt32 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as int32.
Example:
json := `{"scores":[10,20,30]}`
fj.SumInt32(json, "scores") // 60
func SumInt64 ¶
SumInt64 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as int64.
Example:
json := `{"scores":[10,20,30]}`
fj.SumInt64(json, "scores") // 60
func SumUint ¶
SumUint returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as uint.
Example:
json := `{"scores":[10,20,30]}`
fj.SumUint(json, "scores") // 60
func SumUint8 ¶
SumUint8 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as uint8.
Example:
json := `{"scores":[10,20,30]}`
fj.SumUint8(json, "scores") // 60
func SumUint16 ¶
SumUint16 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as uint16.
Example:
json := `{"scores":[10,20,30]}`
fj.SumUint16(json, "scores") // 60
func SumUint32 ¶
SumUint32 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as uint32.
Example:
json := `{"scores":[10,20,30]}`
fj.SumUint32(json, "scores") // 60
func SumUint64 ¶
SumUint64 returns the sum of all numeric values produced by evaluating path against json. Non-numeric results are silently ignored. Returns 0 when no numeric values are found.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path. The path may resolve to a JSON array of numbers (e.g. "scores") or a single number (e.g. "scores.0").
Returns:
- The sum as uint64.
Example:
json := `{"scores":[10,20,30]}`
fj.SumUint64(json, "scores") // 60
func UnsafeBytes ¶
UnsafeBytes converts a string into a byte slice without allocating new memory for the data. This function uses unsafe operations to directly reinterpret the string's underlying data structure as a byte slice. This allows efficient access to the string's content as a mutable byte slice, but it also comes with risks.
Parameters:
- `s`: The input string that needs to be converted to a byte slice.
Returns:
- A byte slice (`[]byte`) that shares the same underlying data as the input string.
Notes:
- This function leverages Go's `unsafe` package to bypass the usual safety mechanisms of the Go runtime. It does this by manipulating memory layouts using `unsafe.Pointer`.
- The resulting byte slice must be treated with care. Modifying the byte slice can lead to undefined behavior since strings in Go are immutable by design.
- Any operation that depends on the immutability of the original string should avoid using this function.
Safety Considerations:
- Since this function operates on unsafe pointers, it is not portable across different Go versions or architectures.
- Direct modifications to the returned byte slice will violate Go's immutability guarantees for strings and may corrupt program state.
Example Usage:
s := "immutable string" b := UnsafeBytes(s) // Efficiently converts the string to []byte // WARNING: Modifying 'b' here can lead to undefined behavior.
Types ¶
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context represents a JSON value returned from the Get() function. It stores information about a specific JSON element, including its type, raw string data, string representation, numeric value, index in the original JSON, and the indexes of elements that match a path containing a '#'.
func Distinct ¶
Distinct evaluates path against json and returns a deduplicated slice of values using the string representation of each element as the equality key. Order is preserved (first occurrence wins).
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
Returns:
- A slice of unique Context values. Returns an empty slice when the path does not exist.
Example:
json := `{"tags":["go","json","go","fast","json"]}`
results := fj.Distinct(json, "tags")
// len(results) == 3: "go", "json", "fast"
func Filter ¶
Filter evaluates path against json, treats the result as an array, and returns only those elements for which fn returns true.
If path resolves to a non-array value (including a single scalar), that single value is treated as a one-element collection. If the path does not exist, an empty slice is returned.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
- fn: A predicate applied to each element. Returning true keeps the element.
Returns:
- A slice of matching Context values.
Example:
json := `{"items":[1,2,3,4,5]}`
results := fj.Filter(json, "items", func(ctx fj.Context) bool {
return ctx.Float64() > 2
})
// results holds Context values for 3, 4, 5
func First ¶
First evaluates path against json and returns the first element for which fn returns true. If no element matches, a zero-value Context is returned (use Context.Exists() to check).
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path.
- fn: A predicate applied to each element.
Returns:
- The first matching Context, or a zero-value Context when not found.
Example:
json := `{"items":[1,2,3,4,5]}`
ctx := fj.First(json, "items", func(c fj.Context) bool {
return c.Float64() > 3
})
ctx.Float64() // 4
func Get ¶
Get searches for a specified path within the provided JSON string and returns the corresponding value as a Context. The path is provided in dot notation, where each segment represents a key or index. The function supports wildcards (`*` and `?`), array indexing, and special characters like '#' to access array lengths or child paths. The function will return the first matching result it finds along the specified path.
Path Syntax: - Dot notation: "name.last" or "age" for direct key lookups. - Wildcards: "*" matches any key, "?" matches a single character. - Array indexing: "children.0" accesses the first item in the "children" array. - The '#' character returns the number of elements in an array (e.g., "children.#" returns the array length). - The dot (`.`) and wildcard characters (`*`, `?`) can be escaped with a backslash (`\`).
Example Usage:
json := `{
"user": {"firstName": "Alice", "lastName": "Johnson"},
"age": 29,
"siblings": ["Ben", "Clara", "David"],
"friends": [
{"firstName": "Tom", "lastName": "Smith"},
{"firstName": "Sophia", "lastName": "Davis"}
],
"address": {"city": "New York", "zipCode": "10001"}
}`
// Examples of Get function with paths:
Get(json, "user.lastName") // Returns: "Johnson"
Get(json, "age") // Returns: 29
Get(json, "siblings.#") // Returns: 3 (number of siblings)
Get(json, "siblings.1") // Returns: "Clara" (second sibling)
Get(json, "friends.#.firstName") // Returns: ["Tom", "Sophia"]
Get(json, "address.zipCode") // Returns: "10001"
Details:
- The function does not validate JSON format but expects well-formed input. Invalid JSON may result in unexpected behavior.
- transformers (e.g., `@` for adjusting paths) and special sub-selectors (e.g., `[` and `{`) are supported and processed in the path before extracting values.
- For complex structures, the function analyzes the provided path, handles nested arrays or objects, and returns a Context containing the value found at the specified location.
Parameters:
- `json`: A string containing the JSON data to search through.
- `path`: A string representing the path to the desired value, using dot notation or other special characters as described.
Returns:
- `Context`: A Context object containing the value found at the specified path, including information such as the type (`kind`), the raw JSON string (`raw`), and the parsed value if available (e.g., `str` for strings).
Notes:
- If the path is not found, the returned Context will reflect this with an empty or null value.
func GetBytes ¶
GetBytes searches the provided JSON byte slice for the specified path and returns a `Context` representing the extracted data. This method is preferred over `Get(string(data), path)` when working with JSON data in byte slice format, as it directly operates on the byte slice, minimizing memory allocations and unnecessary copies.
Parameters:
- `json`: A byte slice containing the JSON data to process.
- `path`: A string representing the path in the JSON data to extract.
Returns:
- A `Context` struct containing the processed JSON data. The `Context` struct includes both the raw unprocessed JSON string and the specific extracted string based on the given path.
Notes:
- This function internally calls the `getBytes` function, which uses unsafe pointer operations to minimize allocations and efficiently handle string slice headers.
- The function avoids unnecessary memory allocations by directly processing the byte slice and utilizing memory safety features to manage substring extraction when the `str` part is a substring of the `raw` part of the JSON data.
Example:
jsonBytes := []byte(`{"key": "value", "nested": {"innerKey": "innerValue"}}`)
path := "nested.innerKey"
context := GetBytes(jsonBytes, path)
fmt.Println("Unprocessed:", context.raw) // Output: `{"key": "value", "nested": {"innerKey": "innerValue"}}`
fmt.Println("Strings:", context.str) // Output: `"innerValue"`
func GetBytesMulti ¶
GetBytesMulti searches json for multiple paths in the provided JSON byte slice. The return value is a slice of `Context` objects, where the number of items will be equal to the number of input paths. Each `Context` represents the value extracted for the corresponding path. This method operates directly on the byte slice, which is preferred when working with JSON data in byte format to minimize memory allocations.
Parameters:
- `json`: A byte slice containing the JSON data to search through.
- `path`: A variadic list of paths to search for within the JSON data.
Returns:
- A slice of `Context` objects, one for each path provided in the `path` parameter.
Notes:
- The function will return a `Context` for each path, and the order of the `Context` objects in the result will match the order of the paths provided.
Example:
jsonBytes := []byte(`{"user": {"firstName": "Alice", "lastName": "Johnson"}, "age": 29}`)
paths := []string{"user.lastName", "age"}
results := GetBytesMulti(jsonBytes, paths...)
// The result will contain Contexts for each path: ["Johnson", 29]
func GetMulti ¶
GetMulti searches json for multiple paths. The return value is a slice of `Context` objects, where the number of items will be equal to the number of input paths. Each `Context` represents the value extracted for the corresponding path.
Parameters:
- `json`: A string containing the JSON data to search through.
- `path`: A variadic list of paths to search for within the JSON data.
Returns:
- A slice of `Context` objects, one for each path provided in the `path` parameter.
Notes:
- The function will return a `Context` for each path, and the order of the `Context` objects in the result will match the order of the paths provided.
Example:
json := `{
"user": {"firstName": "Alice", "lastName": "Johnson"},
"age": 29,
"siblings": ["Ben", "Clara", "David"],
"friends": [
{"firstName": "Tom", "lastName": "Smith"},
{"firstName": "Sophia", "lastName": "Davis"}
]
}`
paths := []string{"user.lastName", "age", "siblings.#", "friends.#.firstName"}
results := GetMulti(json, paths...)
// The result will contain Contexts for each path: ["Johnson", 29, 3, ["Tom", "Sophia"]]
func Parse ¶
Parse parses a JSON string and returns a Context representing the parsed value.
This function processes the input JSON string and attempts to determine the type of the value it represents. It handles objects, arrays, numbers, strings, booleans, and null values. The function does not validate whether the JSON is well-formed, and instead returns a Context object that represents the first valid JSON element found in the string. Invalid JSON may result in unexpected behavior, so for input from unpredictable sources, consider using the `Valid` function first.
Parameters:
- `json`: A string containing the JSON data to be parsed. This function expects well-formed JSON and does not perform comprehensive validation.
Returns:
- A `Context` that represents the parsed JSON element. The `Context` contains details about the type, value, and position of the JSON element, including raw and unprocessed string data.
Notes:
- The function attempts to determine the type of the JSON element by inspecting the first character in the string. It supports the following types: Object (`{`), Array (`[`), Number, String (`"`), Boolean (`true` / `false`), and Null (`null`).
- The function sets the `raw` field of the `Context` to the raw JSON string for further processing, and sets the `kind` field to represent the type of the value (e.g., `String`, `Number`, `True`, `False`, `JSON`, `Null`).
Example Usage:
json := "{\"name\": \"John\", \"age\": 30}"
ctx := Parse(json)
fmt.Println(ctx.kind) // Output: JSON (if the input starts with '{')
json := "12345"
ctx := Parse(json)
fmt.Println(ctx.kind) // Output: Number (if the input is a numeric value)
json := "\"Hello, World!\""
ctx := Parse(json)
fmt.Println(ctx.kind) // Output: String (if the input is a string)
Returns:
- `Context`: The parsed result, which may represent an object, array, string, number, boolean, or null.
func ParseBytes ¶
ParseBytes parses a JSON byte slice and returns a Context representing the parsed value.
This function is a wrapper around the `Parse` function, designed specifically for handling JSON data in the form of a byte slice. It converts the byte slice into a string and then calls `Parse` to process the JSON data. If you're working with raw JSON data as bytes, using this method is preferred over manually converting the bytes to a string and passing it to `Parse`.
Parameters:
- `json`: A byte slice containing the JSON data to be parsed.
Returns:
- A `Context` representing the parsed JSON element, similar to the behavior of `Parse`. The `Context` contains information about the type, value, and position of the JSON element, including the raw and unprocessed string data.
Example Usage:
json := []byte("{\"name\": \"Alice\", \"age\": 25}")
ctx := ParseBytes(json)
fmt.Println(ctx.kind) // Output: JSON (if the input is an object)
Returns:
- `Context`: The parsed result, representing the parsed JSON element, such as an object, array, string, number, boolean, or null.
func ParseJSONFile ¶
ParseJSONFile reads a JSON string from a file specified by the filepath and parses it into a Context.
This function opens the specified file, reads its contents using the `ParseReader` function, and returns a Context representing the parsed JSON element. If any error occurs during file reading or JSON parsing, the returned Context will include the error details.
Parameters:
- filepath: The path to the JSON file to be read and parsed.
Returns:
- A `Context` representing the parsed JSON element. If an error occurs during the file reading or parsing process, the `err` field of the returned Context will be set with the error, and the other fields will remain empty.
Example Usage:
ctx := ParseJSONFile("example.json")
if ctx.err != nil {
log.Fatalf("Failed to parse JSON: %v", ctx.err)
}
fmt.Println(ctx.String())
Notes:
- This function is useful for reading and parsing JSON directly from files.
- The file is opened and closed automatically within this function, and any errors encountered are captured in the returned `Context`.
func ParseReader ¶
ParseReader reads a JSON string from an `io.Reader` and parses it into a Context.
This function combines the reading and parsing operations. It first reads the JSON string using the `BufioRead` function, then processes the string using the `Parse` function to extract details about the first valid JSON element. If reading the JSON fails, the returned Context contains the encountered error.
Parameters:
- in: An `io.Reader` from which the JSON string will be read. This could be a file, network connection, or any other source that implements the `io.Reader` interface.
Returns:
- A `Context` representing the parsed JSON element. If an error occurs during the reading process, the `err` field of the `Context` is set with the error, and the other fields remain empty.
Example Usage:
// Reading JSON from a file
file, err := os.Open("example.json")
if err != nil {
log.Fatal(err)
}
defer file.Close()
ctx := ParseReader(file)
if ctx.err != nil {
log.Fatalf("Failed to parse JSON: %v", ctx.err)
}
fmt.Println(ctx.kind)
// Reading JSON from standard input
fmt.Println("Enter JSON:")
ctx = ParseReader(os.Stdin)
if ctx.err != nil {
log.Fatalf("Failed to parse JSON: %v", ctx.err)
}
fmt.Println(ctx.kind)
Notes:
- This function is particularly useful when working with JSON data from streams or large files.
- The `Parse` function is responsible for the actual parsing, while this function ensures the JSON string is read correctly before parsing begins.
- If the input JSON is malformed or invalid, the returned Context from `Parse` will reflect the issue as an empty Context or an error in the `err` field.
func Pluck ¶
Pluck evaluates path against json (expecting a JSON array of objects), and for each element builds a new JSON object containing only the specified fields. Fields absent from an element are omitted from its output object.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path resolving to an array of objects.
- fields: The field names to extract from each object.
Returns:
- A slice of Context values, one per element in the source array, each wrapping the projected JSON object. Returns an empty slice when path does not exist or no fields are provided.
Example:
json := `{"users":[
{"id":1,"name":"Alice","email":"a@example.com"},
{"id":2,"name":"Bob","email":"b@example.com"}
]}`
results := fj.Pluck(json, "users", "id", "name")
// results[0].String() == `{"id":1,"name":"Alice"}`
// results[1].String() == `{"id":2,"name":"Bob"}`
func Search ¶
Search performs a full-tree scan of the JSON document and returns all leaf values whose string representation contains the given keyword (case-sensitive substring match). Both string values and non-string scalar values (numbers, booleans, null) are compared against the keyword.
The traversal is depth-first; array elements and object values are each visited recursively. Compound values (objects and arrays) are never returned as matches — only scalar leaves are considered.
Parameters:
- json: A well-formed JSON string to scan.
- keyword: The substring to search for. An empty keyword matches every leaf.
Returns:
- A slice of Context values whose string representation contains keyword. Returns an empty (non-nil) slice when there are no matches.
Example:
json := `{"users":[{"name":"Alice"},{"name":"Bob"},{"name":"Charlie"}]}`
results := fj.Search(json, "Ali")
// results[0].String() == "Alice"
func SearchByKey ¶
SearchByKey performs a full-tree scan of the JSON document and returns all Context values that are stored under any of the given key names. The search is recursive — it descends into nested objects and arrays at every depth level.
Key matching is exact and case-sensitive. Multiple key names may be supplied; any value whose immediate parent key matches at least one of them is included.
Parameters:
- json: A well-formed JSON string to scan.
- keys: One or more object key names to look up. If no keys are provided the function returns an empty slice.
Returns:
- A slice of Context values stored under the given keys, in depth-first order.
Example:
json := `{"a":{"title":"Go"},"b":{"title":"Rust"},"c":{"other":"x"}}`
results := fj.SearchByKey(json, "title")
// len(results) == 2, results[0].String() == "Go"
func SearchByKeyPattern ¶
SearchByKeyPattern performs a full-tree scan of the JSON document and returns all Context values whose immediate parent object key matches the given wildcard pattern.
Key matching uses match.Match, supporting '*' (any sequence) and '?' (one character) wildcards. The scan is recursive, descending into nested objects and arrays.
Parameters:
- json: A well-formed JSON string to scan.
- keyPattern: A wildcard pattern applied to object key names.
Returns:
- A slice of Context values stored under matching keys, in depth-first order.
Example:
json := `{"author":"Donovan","authority":"admin","title":"Go"}`
results := fj.SearchByKeyPattern(json, "auth*")
// len(results) == 2: "Donovan" (author) and "admin" (authority)
func SearchMatch ¶
SearchMatch performs a full-tree scan of the JSON document and returns all scalar leaf values whose string representation matches the given wildcard pattern.
The pattern follows the same syntax as match.Match:
- '*' matches any sequence of characters (including empty).
- '?' matches exactly one character.
- Any other character is matched literally.
Both string and non-string scalar values (numbers, booleans, null) are tested against the pattern using their string representation.
Parameters:
- json: A well-formed JSON string to scan.
- pattern: A wildcard pattern. An empty pattern matches only an empty string.
Returns:
- A slice of Context values whose string representation matches pattern. Returns an empty (non-nil) slice when there are no matches.
Example:
json := `{"users":[{"name":"Alice"},{"name":"Bob"},{"name":"Albany"}]}`
results := fj.SearchMatch(json, "Al*")
// len(results) == 2: "Alice", "Albany"
func SortBy ¶
SortBy evaluates path against json, treats the result as an array, and returns a new slice sorted by the value of keyField on each element. Sorting uses conv.Float64 for numeric fields and falls back to the string representation for non-numeric or missing fields.
When keyField is empty, elements are sorted by their own top-level string representation, which is useful for arrays of scalars.
Parameters:
- json: A well-formed JSON string.
- path: A fj dot-notation path resolving to an array.
- keyField: The object field to sort by. Pass "" to sort scalar arrays directly.
- ascending: If true, sort in ascending order; if false, descending.
Returns:
- A new sorted slice of Context values. Returns an empty slice when path does not exist.
Example:
json := `{"items":[{"n":3},{"n":1},{"n":2}]}`
sorted := fj.SortBy(json, "items", "n", true)
// sorted[0].Get("n").Int64() == 1
// sorted[1].Get("n").Int64() == 2
// sorted[2].Get("n").Int64() == 3
func (Context) Array ¶
Array returns an array of `Context` values derived from the current `Context`.
Behavior:
- If the current `Context` represents a `Null` value, it returns an empty array.
- If the current `Context` is not a JSON array, it returns an array containing itself as a single element.
- If the current `Context` is a JSON array, it parses and returns the array's elements.
Returns:
- []Context: A slice of `Context` values representing the array elements.
Example Usage:
ctx := Context{kind: Null}
arr := ctx.Array()
// arr: []
ctx = Context{kind: JSON, raw: "[1, 2, 3]"}
arr = ctx.Array()
// arr: [Context, Context, Context]
Notes:
- This function uses `parseJSONElements` internally to extract array elements.
- If the JSON is malformed or does not represent an array, the behavior may vary.
func (Context) Bool ¶
Bool converts the Context value into a boolean representation. The conversion depends on the JSON type of the Context:
- For `True` type: Returns `true`.
- For `String` type: Attempts to parse the string as a boolean (case-insensitive). If parsing fails, defaults to `false`.
- For `Number` type: Returns `true` if the numeric value is non-zero, otherwise `false`.
- For all other types: Returns `false`.
Returns:
- bool: A boolean representation of the Context value.
func (Context) Cause ¶
Cause returns the error message if there is an error in the Context.
If the Context has an error (i.e., `err` is not `nil`), this function returns the error message as a string. If there is no error, it returns an empty string.
Example Usage:
ctx := Context{err: fmt.Errorf("parsing error")}
fmt.Println(ctx.Cause()) // Output: "parsing error"
ctx = Context{}
fmt.Println(ctx.Cause()) // Output: ""
Returns:
- string: The error message if there is an error, or an empty string if there is no error.
func (Context) Duration ¶
Duration converts the Context value into a time.Duration representation. The conversion depends on the JSON type of the Context:
- For `Number` type: Returns the numeric value as a time.Duration.
- For `String` type: Attempts to parse the string as a duration using `time.ParseDuration`. If parsing fails, defaults to `time.Duration(0)`.
- For all other types: Returns `time.Duration(0)`.
Returns:
- time.Duration: A time.Duration representation of the Context value. Defaults to `time.Duration(0)` if parsing fails.
func (Context) Exists ¶
Exists returns true if the value exists (i.e., it is not Null and contains data).
Example Usage:
if fj.Get(json, "user.name").Exists() {
println("value exists")
}
Returns:
- bool: Returns true if the value is not null and contains non-empty data, otherwise returns false.
func (Context) Float32 ¶
Float32 converts the Context value into a floating-point representation (Float32). This function provides a similar conversion mechanism as Float64 but with Float32 precision. The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1 as a Float32 value.
- For `String` type: Attempts to parse the string as a floating-point number (Float32 precision). If the parsing fails, it defaults to 0.
- For `Number` type: Returns the numeric value as a Float32, assuming the Context contains a numeric value in its `num` field.
Returns:
- Float32: A floating-point representation of the Context value.
Example Usage:
ctx := Context{kind: String, strings: "123.45"}
result := ctx.Float32()
// result: 123.45 (parsed as Float32)
ctx = Context{kind: True}
result = ctx.Float32()
// result: 1 (True is represented as 1.0)
ctx = Context{kind: Number, numeric: 678.9}
result = ctx.Float32()
// result: 678.9 (as Float32)
Details:
For the `True` type, the function always returns 1.0, representing the boolean `true` value.
For the `String` type, it uses `strconv.ParseFloat` with 32-bit precision to convert the string into a Float32. If parsing fails (e.g., if the string is not a valid numeric representation), the function returns 0 as a fallback.
For the `Number` type, the `num` field, assumed to hold a float64 value, is converted to a Float32 for the return value.
Notes:
The function gracefully handles invalid string inputs for the `String` type by returning 0, ensuring no runtime panic occurs due to a parsing error.
Precision may be lost when converting from float64 (`num` field) to Float32.
func (Context) Float64 ¶
Float64 converts the Context value into a floating-point representation (float64). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string as a floating-point number. Defaults to 0 on failure.
- For `Number` type: Returns the numeric value as a float64.
Returns:
- float64: A floating-point representation of the Context value.
func (Context) Foreach ¶
Foreach iterates through the values of a JSON object or array, applying the provided iterator function.
If the `Context` represents a non existent value (Null or invalid JSON), no iteration occurs. For JSON objects, the iterator receives both the key and value of each item. For JSON arrays, the iterator receives only the value of each item. If the `Context` is not an array or object, the iterator is called once with the whole value.
Example Usage:
ctx.Foreach(func(key, value Context) bool {
if key.str != "" {
fmt.Printf("Key: %s, Value: %v\n", key.str, value)
} else {
fmt.Printf("Value: %v\n", value)
}
return true // Continue iteration
})
Parameters:
- iterator: A function that receives a `key` (for objects) and `value` (for both objects and arrays). The function should return `true` to continue iteration or `false` to stop.
Notes:
- If the result is a JSON object, the iterator receives key-value pairs.
- If the result is a JSON array, the iterator receives only the values.
- If the result is not an object or array, the iterator is invoked once with the value.
Returns:
- None. The iteration continues until all items are processed or the iterator returns `false`.
func (Context) Get ¶
Get searches for a specified path within a JSON structure and returns the corresponding result.
This function allows you to search for a specific path in the JSON structure and retrieve the corresponding value as a `Context`. The path is represented as a string and can be used to navigate nested arrays or objects.
The `path` parameter specifies the JSON path to search for, and the function will attempt to retrieve the value associated with that path. The result is returned as a `Context`, which contains information about the matched JSON value, including its type, string representation, numeric value, and index in the original JSON.
Parameters:
- path: A string representing the path in the JSON structure to search for. The path may include array indices and object keys separated by dots or brackets (e.g., "user.name", "items[0].price").
Returns:
- Context: A `Context` instance containing the result of the search. The `Context` may represent various types of JSON values (e.g., string, number, object, array). If no match is found, the `Context` will be empty.
Example Usage:
ctx := Context{kind: JSON, raw: "{\"user\": {\"name\": \"John\"}, \"items\": [1, 2, 3]}"}
result := ctx.Get("user.name")
// result.str will contain "John", representing the value found at the "user.name" path.
Notes:
- The function uses the `Get` function (presumably another function) to process the `raw` JSON string and search for the specified path.
- The function adjusts the indices of the results (if any) to account for the original position of the `Context` in the JSON string.
func (Context) GetMulti ¶
GetMulti searches for multiple paths within a JSON structure and returns a slice of results.
This function allows you to search for multiple paths in the JSON structure, each represented as a string. It returns a slice of `Context` instances for each of the specified paths. The paths can be used to navigate nested arrays or objects.
The `path` parameters specify the JSON paths to search for, and the function will attempt to retrieve the values associated with those paths. Each result is returned as a `Context` containing information about the matched JSON value, including its type, string representation, numeric value, and index in the original JSON.
Parameters:
- path: One or more strings representing the paths in the JSON structure to search for. The paths may include array indices and object keys separated by dots or brackets (e.g., "user.name", "items[0].price").
Returns:
- []Context: A slice of `Context` instances, each containing the result of searching for one of the paths. Each `Context` may represent various types of JSON values (e.g., string, number, object, array). If no match is found for a path, the corresponding `Context` will be empty.
Example Usage:
ctx := Context{kind: JSON, raw: "{\"user\": {\"name\": \"John\"}, \"items\": [1, 2, 3]}"}
results := ctx.GetMulti("user.name", "items[1]")
// results[0].str will contain "John" for the "user.name" path,
// results[1].num will contain 2 for the "items[1]" path.
Notes:
- This function uses the `GetMulti` function (presumably another function) to process the `raw` JSON string and search for each of the specified paths.
- Each result is returned as a separate `Context` for each path, allowing for multiple values to be retrieved at once from the JSON structure.
func (Context) Index ¶
Index returns the index of the unprocessed JSON value in the original JSON string. This can be used to track the position of the value in the source data. If the index is unknown, it defaults to 0.
Returns:
- int: The position of the value in the original JSON string.
func (Context) Indexes ¶
Indexes returns a slice of indices for elements matching a path containing the '#' character. This is useful for handling path queries that involve multiple matches.
Returns:
- []int: A slice of indices for matching elements.
func (Context) Int ¶
Int converts the Context value into an integer representation (int). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to an integer if it's within the safe range.
- Parses the unprocessed string for integer values as a fallback.
- Defaults to converting the float64 numeric value to an int.
Returns:
- int: An integer representation of the Context value.
func (Context) Int8 ¶
Int8 converts the Context value into an 8-bit integer representation (int8). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an 8-bit integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to an 8-bit integer if it's within the safe range.
- Parses the unprocessed string for 8-bit integer values as a fallback.
- Defaults to converting the float64 numeric value to an int8.
Returns:
- int8: An 8-bit integer representation of the Context value.
func (Context) Int16 ¶
Int16 converts the Context value into a 16-bit integer representation (int16). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into a 16-bit integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a 16-bit integer if it's within the safe range.
- Parses the unprocessed string for 16-bit integer values as a fallback.
- Defaults to converting the float64 numeric value to an int16.
Returns:
- int16: A 16-bit integer representation of the Context value.
func (Context) Int32 ¶
Int32 converts the Context value into a 32-bit integer representation (int32). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into a 32-bit integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a 32-bit integer if it's within the safe range.
- Parses the unprocessed string for 32-bit integer values as a fallback.
- Defaults to converting the float64 numeric value to an int32.
Returns:
- int32: A 32-bit integer representation of the Context value.
func (Context) Int64 ¶
Int64 converts the Context value into an integer representation (int64). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to an integer if it's safe.
- Parses the unprocessed string for integer values as a fallback.
- Defaults to converting the float64 numeric value to an int64.
Returns:
- int64: An integer representation of the Context value.
func (Context) IsArray ¶
IsArray checks if the current `Context` represents a JSON array.
A value is considered a JSON array if:
- The `kind` is `JSON`.
- The `raw` string starts with the `[` character.
Returns:
- bool: Returns `true` if the `Context` is a JSON array; otherwise, `false`.
Example Usage:
ctx := Context{kind: JSON, raw: "[1, 2, 3]"}
isArr := ctx.IsArray()
// isArr: true
ctx = Context{kind: JSON, raw: "{"key": "value"}"}
isArr = ctx.IsArray()
// isArr: false
func (Context) IsBool ¶
IsBool checks if the current `Context` represents a JSON boolean value.
A value is considered a JSON boolean if:
- The `kind` is `True` or `False`.
Returns:
- bool: Returns `true` if the `Context` is a JSON boolean; otherwise, `false`.
Example Usage:
ctx := Context{kind: True}
isBool := ctx.IsBool()
// isBool: true
ctx = Context{kind: String, strings: "true"}
isBool = ctx.IsBool()
// isBool: false
func (Context) IsError ¶
IsError checks if there is an error associated with the Context.
This function checks whether the `err` field of the Context is set. If there is an error (i.e., `err` is not `nil`), the function returns `true`; otherwise, it returns `false`.
Example Usage:
ctx := Context{err: fmt.Errorf("invalid JSON")}
fmt.Println(ctx.IsError()) // Output: true
ctx = Context{}
fmt.Println(ctx.IsError()) // Output: false
Returns:
- bool: `true` if the Context has an error, `false` otherwise.
func (Context) IsObject ¶
IsObject checks if the current `Context` represents a JSON object.
A value is considered a JSON object if:
- The `kind` is `JSON`.
- The `raw` string starts with the `{` character.
Returns:
- bool: Returns `true` if the `Context` is a JSON object; otherwise, `false`.
Example Usage:
ctx := Context{kind: JSON, raw: "{"key": "value"}"}
isObj := ctx.IsObject()
// isObj: true
ctx = Context{kind: JSON, raw: "[1, 2, 3]"}
isObj = ctx.IsObject()
// isObj: false
func (Context) Kind ¶
Kind returns the JSON type of the Context. It provides the specific type of the JSON value, such as String, Number, Object, etc.
Returns:
- Type: The type of the JSON value represented by the Context.
func (Context) Less ¶
Less compares two Context values (tokens) and returns true if the first token is considered less than the second one. It performs comparisons based on the type of the tokens and their respective values. The comparison order follows: Null < False < Number < String < True < JSON. This function also supports case-insensitive comparisons for String type tokens based on the caseSensitive parameter.
Parameters:
- token: The other Context token to compare with the current one (t).
- caseSensitive: A boolean flag that indicates whether the comparison for String type tokens should be case-sensitive.
- If true, the comparison is case-sensitive (i.e., "a" < "b" but "A" < "b").
- If false, the comparison is case-insensitive (i.e., "a" == "A").
Returns:
- true: If the current token (t) is considered less than the provided token.
- false: If the current token (t) is not considered less than the provided token.
The function first compares the `kind` of both tokens, which represents their JSON types. If both tokens have the same kind, it proceeds to compare based on their specific types: - For String types, it compares the strings based on the case-sensitive flag. - For Number types, it compares the numeric values directly. - For other types, it compares the unprocessed JSON values as raw strings (this could be useful for types like Null, Boolean, etc.).
Example usage:
context1 := Context{kind: String, strings: "apple"}
context2 := Context{kind: String, strings: "banana"}
result := context1.Less(context2, true) // This would return true because "apple" < "banana" and case-sensitive comparison is used.
func (Context) Map ¶
Map returns a map of values extracted from a JSON object.
The function assumes that the `Context` represents a JSON object. It parses the JSON object and returns a map where the keys are strings, and the values are `Context` elements representing the corresponding JSON values.
If the `Context` does not represent a valid JSON object, the function will return an empty map.
Parameters:
- ctx: The `Context` instance that holds the raw JSON string. The function checks if the context represents a JSON object and processes it accordingly.
Returns:
- map[string]Context: A map where the keys are strings (representing the keys in the JSON object), and the values are `Context` instances representing the corresponding JSON values. If the context does not represent a valid JSON object, a nil is returned.
Example Usage:
ctx := Context{kind: JSON, raw: "{\"key1\": \"value1\", \"key2\": 42}"}
result := ctx.Map()
// result.OpMap contains the parsed key-value pairs: {"key1": "value1", "key2": 42}
Notes:
- The function calls `parseJSONElements` with the expected JSON object indicator ('{') to parse the JSON.
- If the `Context` is not a valid JSON object, it returns an empty map, which can be used to safely handle errors.
func (Context) Number ¶
Number returns the numeric value of the Context, if applicable. This is relevant when the Context represents a JSON number.
Returns:
- float64: The numeric value of the Context. If the Context does not represent a number, the value may be undefined.
func (Context) Path ¶
Path returns the original fj path for a Result where the Result came from a simple query path that returns a single value. For example, if the `Get` function was called with a query path like:
fj.Get(json, "employees.#(first=Admin)")
This function will return the original path that corresponds to the single value in the result, formatted as a JSON path.
The returned value will be in the form of a JSON string:
"employees.0"
The param 'json' must be the original JSON used when calling Get.
Returns:
- A string representing the original path for the single value in the result.
- If the paths cannot be determined (e.g., due to the result being from a multi-path, transformer, or a nested query), an empty string will be returned.
Notes:
- The `Path` function operates by tracing the position of the result within the original JSON string and reconstructing the query path based on this position.
- The function checks the surrounding JSON context (such as whether the result is within an array or object) and extracts the relevant path information.
- The path components are identified by traversing the string from the result's index and extracting the array or object keys that lead to the specific value.
Example Usage:
json := `{
"employees": [
{"id": 1, "name": {"first": "John", "last": "Doe"}, "department": "HR"},
{"id": 2, "name": {"first": "Jane", "last": "Smith"}, "department": "Engineering"},
{"id": 3, "name": {"first": "Admin", "last": "Land"}, "department": "Marketing"},
{"id": 4, "name": {"first": "Emily", "last": "Jones"}, "department": "Engineering"}
],
"companies": [
{"name": "TechCorp", "employees": [1, 2]},
{"name": "BizGroup", "employees": [3, 4]}
]
}`
// Get the employee's last name who works in the Engineering department
result := fj.Get(json, "employees.#(department=Engineering).name.last")
path := result.Path(json)
// Output: "employees.1.name.last"
// Explanation:
// The `Path` function returns the path to the "last" name of the second
// employee in the "employees" array who works in the "Engineering" department.
// The path "employees.1.name.last" corresponds to the "Jane Smith" employee,
// and the query specifically looks at the "last" name of that employee.
func (Context) Paths ¶
Paths returns the original fj paths for a Result where the Result came from a simple query path that returns an array. For example, if the `Get` function was called with a query path like:
fj.Get(json, "friends.#.first")
This function will return the paths for each element in the resulting array, formatted as a JSON array. The returned paths are the original query paths for each item in the array, reflecting the specific positions of the elements in the original JSON structure.
The returned value will be in the form of a JSON array, such as:
["friends.0.first", "friends.1.first", "friends.2.first"]
Parameters:
- `json`: A string representing the original JSON used in the query. This is required for resolving the specific paths corresponding to each element in the resulting array.
Returns:
- A slice of strings (`[]string`), each containing the original path for an element in the result array.
- If the result was a simple query that returns an array, each string will be a path to an individual element in the array.
- If the paths cannot be determined (e.g., due to the result being from a multi-path, transformer, or a nested query), an empty slice will be returned.
Notes:
- The `Paths` function relies on the `idxs` field in the `Context` object. If the `idxs` field is `nil`, the function will return `nil`.
- The function iterates over each element in the result (which is expected to be an array) and appends the corresponding path to the `paths` slice.
- If the paths cannot be determined (e.g., due to the result coming from a multi-path or more complex query), an empty slice will be returned.
- This function is useful for extracting the specific query paths for elements within a larger result array, providing a way to inspect or manipulate the paths of individual items.
Example Usage:
json := `{
"friends": [
{"first": "Tom", "last": "Smith"},
{"first": "Sophia", "last": "Davis"},
{"first": "James", "last": "Miller"}
]
}`
result := fj.Get(json, "friends.#.first")
paths := result.Paths(json)
// Output: ["friends.0.first", "friends.1.first", "friends.2.first"]
func (Context) Raw ¶
Raw returns the raw, unprocessed JSON string for the Context. This can be useful for inspecting the original data without any parsing or transformations.
Returns:
- string: The unprocessed JSON string.
func (Context) String ¶
String returns a string representation of the Context value. The output depends on the JSON type of the Context:
- For `False` type: Returns "false".
- For `True` type: Returns "true".
- For `Number` type: Returns the numeric value as a string. If the numeric value was calculated, it formats the float value. Otherwise, it preserves the original unprocessed string if valid.
- For `String` type: Returns the string value.
- For `JSON` type: Returns the raw unprocessed JSON string.
- For other types: Returns an empty string.
Returns:
- string: A string representation of the Context value.
func (Context) StringColored ¶
StringColored returns a colored string representation of the Context value. It applies the default style defined in `defaultStyle` to the string representation of the Context value.
Details:
- The function first retrieves the plain string representation using `ctx.String()`.
- If the string is empty (determined by `isEmpty`), it returns an empty string.
- Otherwise, it applies the coloring rules from `defaultStyle` using the `encoding.Color` function.
Returns:
- string: A colored string representation of the Context value if not empty. Returns an empty string for empty or invalid Context values.
Example Usage:
ctx := Context{kind: True}
fmt.Println(ctx.StringColored()) // Output: "\033[1;35mtrue\033[0m" (colored)
Notes:
- Requires the `encoding` library for styling and the `isEmpty` utility function to check for empty strings.
func (Context) Time ¶
Time converts the Context value into a time.Time representation. The conversion interprets the Context value as a string in RFC3339 format. If parsing fails, the zero time (0001-01-01 00:00:00 UTC) is returned.
Returns:
- time.Time: A time.Time representation of the Context value. Defaults to the zero time if parsing fails.
func (Context) Uint ¶
Uint converts the Context value into an unsigned integer representation (uint). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an unsigned integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a uint if it's safe and non-negative.
- Parses the unprocessed string for unsigned integer values as a fallback.
- Defaults to converting the float64 numeric value to a uint.
Returns:
- uint: An unsigned integer representation of the Context value.
func (Context) Uint8 ¶
Uint8 converts the Context value into an 8-bit unsigned integer representation (uint8). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an 8-bit unsigned integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a uint8 if it's safe and non-negative.
- Parses the unprocessed string for 8-bit unsigned integer values as a fallback.
- Defaults to converting the float64 numeric value to a uint8.
Returns:
- uint8: An 8-bit unsigned integer representation of the Context value.
func (Context) Uint16 ¶
Uint16 converts the Context value into a 16-bit unsigned integer representation (uint16). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into a 16-bit unsigned integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a uint16 if it's safe and non-negative.
- Parses the unprocessed string for 16-bit unsigned integer values as a fallback.
- Defaults to converting the float64 numeric value to a uint16.
Returns:
- uint16: A 16-bit unsigned integer representation of the Context value.
func (Context) Uint32 ¶
Uint32 converts the Context value into a 32-bit unsigned integer representation (uint32). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into a 32-bit unsigned integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a uint32 if it's safe and non-negative.
- Parses the unprocessed string for 32-bit unsigned integer values as a fallback.
- Defaults to converting the float64 numeric value to a uint32.
Returns:
- uint32: A 32-bit unsigned integer representation of the Context value.
func (Context) Uint64 ¶
Uint64 converts the Context value into an unsigned integer representation (uint64). The conversion depends on the JSON type of the Context:
- For `True` type: Returns 1.
- For `String` type: Attempts to parse the string into an unsigned integer. Defaults to 0 on failure.
- For `Number` type:
- Directly converts the numeric value to a uint64 if it's safe and non-negative.
- Parses the unprocessed string for unsigned integer values as a fallback.
- Defaults to converting the float64 numeric value to a uint64.
Returns:
- uint64: An unsigned integer representation of the Context value.
func (Context) Value ¶
Value returns the corresponding Go type for the JSON value represented by the Context.
The function returns one of the following types based on the JSON value:
- bool for JSON booleans (True or False)
- float64 for JSON numbers
- string for JSON string literals
- nil for JSON null
- map[string]interface{} for JSON objects
- []interface{} for JSON arrays
Example Usage:
value := ctx.Value()
switch v := value.(type) {
case bool:
fmt.Println("Boolean:", v)
case float64:
fmt.Println("Number:", v)
case string:
fmt.Println("String:", v)
case nil:
fmt.Println("Null value")
case map[string]interface{}:
fmt.Println("Object:", v)
case []interface{}:
fmt.Println("Array:", v)
}
Returns:
- interface{}: Returns the corresponding Go type for the JSON value, or nil if the type is not recognized.
func (Context) WithStringColored ¶
WithStringColored applies a customizable colored styling to the string representation of the Context value.
This function enhances the default coloring functionality by allowing the caller to specify a custom style for highlighting the Context value. If no custom style is provided, the default styling rules (`defaultStyle`) are used.
Parameters:
- style (*encoding.Style): A pointer to a Style structure that defines custom styling rules for JSON elements. If `style` is nil, the `defaultStyle` is applied.
Details:
- Retrieves the plain string representation of the Context value using `ctx.String()`.
- Checks if the string is empty using the `isEmpty` utility function. If empty, it returns an empty string immediately.
- If a custom style is provided, it applies the given style to the string representation using the `encoding.Color` function. Otherwise, it applies the default style.
Returns:
- string: A styled string representation of the Context value based on the provided or default style.
Example Usage:
customStyle := &encoding.Style{
Key: [2]string{"\033[1;36m", "\033[0m"},
String: [2]string{"\033[1;33m", "\033[0m"},
// Additional styling rules...
}
ctx := Context{kind: True}
fmt.Println(ctx.WithStringColored(customStyle)) // Output: "\033[1;35mtrue\033[0m" (custom colored)
Notes:
- The function uses the `encoding.Color` utility to apply the color rules defined in the style.
- Requires the `isEmpty` utility function to check for empty strings.
func (Context) WithTime ¶
WithTime parses the Context value into a time.Time representation using a custom format. This function allows for greater flexibility by enabling parsing with user-defined date and time formats, rather than relying on the fixed RFC3339 format used in `Time()`.
Parameters:
- format: A string representing the desired format to parse the Context value. This format must conform to the layouts supported by the `time.Parse` function.
Returns:
- time.Time: The parsed time.Time representation of the Context value if parsing succeeds.
- error: An error value if the parsing fails (e.g., due to an invalid format or mismatched value).
Example Usage:
ctx := Context{kind: String, strings: "12-25-2023"}
t, err := ctx.WithTime("01-02-2006")
if err != nil {
fmt.Println("Error parsing time:", err)
} else {
fmt.Println("Parsed time:", t)
}
// Output: Parsed time: 2023-12-25 00:00:00 +0000 UTC
Details:
The function relies on the `time.Parse` function to convert the string value from the Context into a time.Time representation.
The format parameter determines how the Context value should be interpreted. It must match the layout of the Context's string value. If the value cannot be parsed according to the given format, the function returns an error.
Unlike `Time()`, which defaults to the zero time on failure, this function explicitly returns an error to indicate parsing issues.
Notes:
The function assumes that `ctx.String()` returns a string representation of the Context value. If the Context does not contain a valid string, the parsing will fail.
This function is ideal for cases where date and time formats vary or when the RFC3339 standard is not suitable.
To handle parsing failures gracefully, always check the returned error before using the resulting `time.Time` value.
type Transformer ¶
Transformer is the interface implemented by all transformer types. A transformer receives the current JSON string and an optional argument string, and returns a transformed JSON string. Transformers are applied via the @ syntax in fj path expressions (e.g. "name.@uppercase").
Implement this interface to provide custom, stateful, or composable transformer logic that goes beyond plain function closures. For simple, stateless cases use the TransformerFunc adapter, which satisfies this interface automatically.
Example (struct-based):
type prefixTransformer struct{ prefix string }
func (t *prefixTransformer) Apply(json, arg string) string {
return t.prefix + json
}
fj.AddTransformer("prefix", &prefixTransformer{prefix: "data:"})
type TransformerFunc ¶
TransformerFunc is a function adapter that implements the Transformer interface. It allows any plain function with the signature func(json, arg string) string to satisfy Transformer without defining a named struct.
This mirrors the http.HandlerFunc pattern from the standard library.
Example:
fj.AddTransformer("upper", fj.TransformerFunc(func(json, arg string) string {
return strings.ToUpper(json)
}))
func (TransformerFunc) Apply ¶
func (f TransformerFunc) Apply(json, arg string) string
Apply calls f(json, arg), satisfying the Transformer interface.
type Type ¶
type Type int
Type represents the different possible types for a JSON value. It is used to indicate the specific type of a JSON value, such as a string, number, boolean, etc.
const ( // Null is a constant representing a JSON null value. // In JSON, null is used to represent the absence of a value. Null Type = iota // False is a constant representing a JSON false boolean value. // In JSON, false is a boolean value that represents a negative or off state. False // Number is a constant representing a JSON number value. // In JSON, numbers can be integers or floating-point values. Number // String is a constant representing a JSON string value. // In JSON, strings are sequences of characters enclosed in double quotes. String // True is a constant representing a JSON true boolean value. // In JSON, true is a boolean value that represents a positive or on state. True // JSON is a constant representing a raw JSON block. // This type can be used to represent any valid JSON object or array. JSON )
func (Type) String ¶
String provides a string representation of the `Type` enumeration.
This method converts the `Type` value into a human-readable string. It is particularly useful for debugging or logging purposes.
Mapping of `Type` values to strings:
- Null: "Null"
- False: "False"
- Number: "Number"
- String: "String"
- True: "True"
- JSON: "JSON"
- Default (unknown type): An empty string is returned.
Returns:
- string: A string representation of the `Type` value.
Example Usage:
var t Type = True fmt.Println(t.String()) // Output: "True"