mirror of
https://github.com/akvorado/akvorado.git
synced 2025-12-11 22:14:02 +01:00
This is a first step to make it accept configuration. Most of the changes are quite trivial, but I also ran into some difficulties with query columns and filters. They need the schema for parsing, but parsing happens before dependencies are instantiated (and even if it was not the case, parsing is stateless). Therefore, I have added a `Validate()` method that must be called after instantiation. Various bits `panic()` if not validated to ensure we catch all cases. The alternative to make the component manages a global state would have been simpler but it would break once we add the ability to add or disable columns.
83 lines
2.0 KiB
Go
83 lines
2.0 KiB
Go
// SPDX-FileCopyrightText: 2022 Free Mobile
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
//go:build !release
|
|
|
|
package helpers
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/netip"
|
|
"reflect"
|
|
"time"
|
|
|
|
"github.com/kylelemons/godebug/pretty"
|
|
)
|
|
|
|
var prettyC = pretty.Config{
|
|
Diffable: true,
|
|
PrintStringers: false,
|
|
SkipZeroFields: true,
|
|
IncludeUnexported: false,
|
|
}
|
|
|
|
func defaultPrettyFormatters() map[reflect.Type]interface{} {
|
|
result := map[reflect.Type]interface{}{
|
|
reflect.TypeOf(net.IP{}): fmt.Sprint,
|
|
reflect.TypeOf(netip.Addr{}): fmt.Sprint,
|
|
reflect.TypeOf(time.Time{}): fmt.Sprint,
|
|
reflect.TypeOf(SubnetMap[string]{}): fmt.Sprint,
|
|
}
|
|
for t, fn := range nonDefaultPrettyFormatters {
|
|
result[t] = fn
|
|
}
|
|
return result
|
|
}
|
|
|
|
var nonDefaultPrettyFormatters = map[reflect.Type]interface{}{}
|
|
|
|
// AddPrettyFormatter add a global pretty formatter. We cannot put everything in
|
|
// the default map due to cycles.
|
|
func AddPrettyFormatter(t reflect.Type, fn interface{}) {
|
|
nonDefaultPrettyFormatters[t] = fn
|
|
}
|
|
|
|
// DiffOption changes the behavior of the Diff function.
|
|
type DiffOption struct {
|
|
kind int
|
|
// When this is a formatter
|
|
t reflect.Type
|
|
fn interface{}
|
|
}
|
|
|
|
// Diff return a diff of two objects. If no diff, an empty string is
|
|
// returned.
|
|
func Diff(a, b interface{}, options ...DiffOption) string {
|
|
prettyC := prettyC
|
|
prettyC.Formatter = defaultPrettyFormatters()
|
|
for _, option := range options {
|
|
switch option.kind {
|
|
case DiffUnexported.kind:
|
|
prettyC.IncludeUnexported = true
|
|
case DiffZero.kind:
|
|
prettyC.SkipZeroFields = false
|
|
case DiffFormatter(nil, nil).kind:
|
|
prettyC.Formatter[option.t] = option.fn
|
|
}
|
|
}
|
|
return prettyC.Compare(a, b)
|
|
}
|
|
|
|
var (
|
|
// DiffUnexported will display diff of unexported fields too.
|
|
DiffUnexported = DiffOption{kind: 1}
|
|
// DiffZero will include zero-field in diff
|
|
DiffZero = DiffOption{kind: 2}
|
|
)
|
|
|
|
// DiffFormatter adds a new formatter
|
|
func DiffFormatter(t reflect.Type, fn interface{}) DiffOption {
|
|
return DiffOption{kind: 3, t: t, fn: fn}
|
|
}
|