Documentation
¶
Overview ¶
Package configbuilder holds the HTTP-free core shared by the web Config Builder (internal/api) and the terminal Config Builder (internal/configtui): talkgroup CSV sidecar IO, the RadioReference→config projection, the canonical section list + validation-error section bucketing, frequency formatting, and the AdvancedJSON field allow-list. Keeping these here means the two builders cannot disagree on behaviour.
Index ¶
- Variables
- func DefaultConfigPath() string
- func ExpandConfigPath(p string) string
- func FieldMetas() map[string]FieldMeta
- func HzToDisplay(hz uint32) string
- func IsAdvanced(structName, field string) bool
- func ParseFreqList(text string) []uint32
- func ParseHz(text string) uint32
- func SectionOf(msg string) string
- func WriteTalkgroupCSV(path string, rows []TalkgroupCSVRow) error
- type FieldMeta
- type SectionMeta
- type SelectOption
- type TalkgroupCSVRow
Constants ¶
This section is empty.
Variables ¶
var AdvancedFields = map[string][]string{
"DeviceConfig": {
"BlogV4", "BlogV4Lite", "IQCorrect", "IQInvert", "DCAvoid", "DCAvoidOffsetHz",
},
"SystemConfig": {
"TETRAColourCode", "TETRAChannel", "TETRAChannelCoding", "TETRAClockMode",
"LTRFCSMode", "LTRManchesterMode",
"P25Phase1DemodMode",
"P25Phase2TrellisMode", "P25Phase2RSMode", "P25Phase2InterleaveMode",
"P25Phase2ScramblerMode", "P25Phase2ClockMode",
"DMRInterleavedVoice",
"NXDNViterbiMode", "NXDNDeviationHz",
"EDACSBCHMode",
"MPT1327BCHMode", "MPT1327CWSCTolerance",
"MotorolaBCHMode",
"DStarFECMode",
},
}
AdvancedFields lists the config fields that the builders intentionally do NOT give a bespoke widget: they round-trip through an "Advanced (JSON)" editor (web) / a raw-JSON or generic editor (TUI). Keyed by Go struct name. This is the single definition mirrored by the web's PROTOCOL_KNOBS (Trunking.tsx) + DEVICE_ADVANCED (SDR.tsx) and verified by the schema-drift tests, so adding a protocol knob is a one-line, reviewed decision.
Functions ¶
func DefaultConfigPath ¶
func DefaultConfigPath() string
DefaultConfigPath picks a sensible default config.yaml location:
- $GOPHERTRUNK_CONFIG (the Windows installer sets this);
- ./config.yaml when the cwd is writable;
- <os.UserConfigDir()>/GopherTrunk/config.yaml otherwise.
func ExpandConfigPath ¶
ExpandConfigPath resolves ~, $VAR/${VAR}, and %VAR% references in a config-file path (relocated from the old CLI wizard so the terminal Config Builder accepts the same operator-typed paths). Unknown vars are preserved. It delegates to pathutil.Expand, the shared leaf helper the daemon's config loader uses for the same resolution.
func FieldMetas ¶
FieldMetas returns the whole registry (the web builder serves it over /api/v1/config/fieldmeta). The returned map is the live registry; callers must not mutate it.
func HzToDisplay ¶
HzToDisplay renders an integer-Hz value as trimmed MHz (e.g. 851037500 → "851.0375 MHz", 852000000 → "852 MHz"). Mirrors hzToDisplay in web/configbuilder/src/components/fields.tsx.
func IsAdvanced ¶
IsAdvanced reports whether structName.field is in the AdvancedFields set.
func ParseFreqList ¶
ParseFreqList parses a comma/semicolon/newline-separated list of frequencies, each MHz (values < 10000) or Hz, into integer Hz. Mirrors parseFreqList in web/configbuilder/src/components/fields.tsx. Used by the freq-list widget and, taking element [0], the single-Hz widget.
func ParseHz ¶
ParseHz parses a single frequency (MHz or Hz) to integer Hz, returning 0 when nothing parses — the single-field analogue of ParseFreqList.
func SectionOf ¶
SectionOf extracts the top-level config section key from a validation error message (everything before the first '.', ':', '[', or ' ' in the leading token). E.g. "trunking.systems[0]: name required" → "trunking".
func WriteTalkgroupCSV ¶
func WriteTalkgroupCSV(path string, rows []TalkgroupCSVRow) error
WriteTalkgroupCSV writes a Trunk Recorder–style talkgroup CSV that trunking.TalkGroup loads (header columns it recognises).
Types ¶
type FieldMeta ¶
type FieldMeta struct {
Label string `json:"label,omitempty"`
Help string `json:"help,omitempty"`
Options []SelectOption `json:"options,omitempty"`
Hz bool `json:"hz,omitempty"`
FreqList bool `json:"freqList,omitempty"`
}
FieldMeta is the shared, per-field metadata BOTH Config Builders consume: the terminal builder (internal/configtui) reads it directly; the web builder reads it over GET /api/v1/config/fieldmeta. It is keyed "StructName.FieldName" in the registry below.
- Label overrides the humanized Go field name (empty ⇒ humanize).
- Help is the comprehensive per-field help shown under the focused row (TUI) / beside the widget (web). Every config leaf has one; the fieldmeta coverage test fails if a new field lands without it, so a schema change can't ship without updating the shared help (and thus both editors).
- Options turns a string/number into a select with these choices.
- Hz renders a uint/int as an MHz/Hz frequency widget.
- FreqList renders a []uint32 as a frequency-list widget.
func FieldMetaFor ¶
FieldMetaFor returns the shared metadata for structName.field. An absent entry yields the zero FieldMeta (humanized label, plain widget).
type SectionMeta ¶
type SectionMeta struct {
Key string
CfgField string
Label string
Instructions string
DocTitle string
DocURL string
}
SectionMeta names a top-level config section and carries its builder help: Key is the snake/lowercase id (nav, docs, validator buckets); CfgField is the Go config.Config field name; Label is the display name; Instructions is the section help text; DocTitle/DocURL are the "open docs" link. This is the Go source of truth that BOTH the web Config Builder (via /api/v1/config/docs) and the terminal builder consume, so their section help stays identical.
func SectionByKey ¶
func SectionByKey(key string) (SectionMeta, bool)
SectionByKey returns the section metadata for a snake/lowercase key.
func Sections ¶
func Sections() []SectionMeta
Sections returns the canonical ordered section list (matching the web builder's order) with help + docs.
type SelectOption ¶
SelectOption is one choice in a select / dropdown field (stored value + display label).
type TalkgroupCSVRow ¶
type TalkgroupCSVRow struct {
Decimal uint32 `json:"decimal"`
AlphaTag string `json:"alpha_tag,omitempty"`
Description string `json:"description,omitempty"`
Tag string `json:"tag,omitempty"`
Group string `json:"group,omitempty"`
Mode string `json:"mode,omitempty"`
}
TalkgroupCSVRow is one row of a Trunk Recorder–style talkgroup CSV sidecar. The json tags are the wire shape the web builder exchanges, so internal/api aliases this type to keep its responses byte-identical.
func RRToSystemConfig ¶
func RRToSystemConfig(full radioreference.FullSystem) (config.SystemConfig, []TalkgroupCSVRow)
RRToSystemConfig projects a RadioReference FullSystem into a config-ready SystemConfig (control channels collapsed + de-duplicated across sites) plus the talkgroup rows for its CSV sidecar. Shared by the web builder's /rr/system handler and the TUI's RadioReference import.
func ReadTalkgroupCSV ¶
func ReadTalkgroupCSV(path string) ([]TalkgroupCSVRow, error)
ReadTalkgroupCSV parses a Trunk Recorder–style talkgroup CSV into rows, mapping columns by (case/space-insensitive) header name so column order and extra columns are tolerated. Rows without a numeric Decimal are skipped.