[feat](trx-app): support combined trx-rs.toml config file

Both trx-server and trx-client now look for a combined trx-rs.toml
with [trx-server] and [trx-client] section headers respectively,
falling back to per-binary config files as before.

Search order per tier: combined trx-rs.toml → flat per-binary file,
checked in CWD, ~/.config/trx-rs/, and /etc/trx-rs/.

--print-config now outputs the config under the appropriate section
header so the combined file can be generated directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-02-28 08:08:45 +01:00
parent 6a47fb00ad
commit 06312abe42
6 changed files with 185 additions and 11 deletions
+44
View File
@@ -691,6 +691,46 @@ impl ServerConfig {
toml::to_string_pretty(&example).unwrap_or_default()
}
/// Generate an example configuration wrapped under the `[trx-server]`
/// section header, suitable for use in a combined `trx-rs.toml` file.
pub fn example_combined_toml() -> String {
#[derive(serde::Serialize)]
struct Wrapper {
#[serde(rename = "trx-server")]
inner: ServerConfig,
}
let example = ServerConfig {
general: GeneralConfig {
callsign: Some("N0CALL".to_string()),
log_level: Some("info".to_string()),
latitude: Some(52.2297),
longitude: Some(21.0122),
},
rig: RigConfig {
model: Some("ft817".to_string()),
initial_freq_hz: 144_300_000,
initial_mode: RigMode::USB,
access: AccessConfig {
access_type: Some("serial".to_string()),
port: Some("/dev/ttyUSB0".to_string()),
baud: Some(9600),
host: None,
tcp_port: None,
args: None,
},
},
behavior: BehaviorConfig::default(),
listen: ListenConfig::default(),
audio: AudioConfig::default(),
pskreporter: PskReporterConfig::default(),
aprsfi: AprsFiConfig::default(),
decode_logs: DecodeLogsConfig::default(),
sdr: SdrConfig::default(),
rigs: Vec::new(),
};
toml::to_string_pretty(&Wrapper { inner: example }).unwrap_or_default()
}
}
fn validate_log_level(level: Option<&str>) -> Result<(), String> {
@@ -789,6 +829,10 @@ impl ConfigFile for ServerConfig {
"server.toml"
}
fn combined_key() -> Option<&'static str> {
Some("trx-server")
}
fn default_search_paths() -> Vec<PathBuf> {
let mut paths = Vec::new();
paths.push(PathBuf::from("trx-server.toml"));
+1 -1
View File
@@ -663,7 +663,7 @@ async fn main() -> DynResult<()> {
let cli = Cli::parse();
if cli.print_config {
println!("{}", ServerConfig::example_toml());
println!("{}", ServerConfig::example_combined_toml());
return Ok(());
}