// Copyright (C) 2023-2099 The crate authors. // // This program is free software: you can redistribute it and/or modify it // under the terms of the GNU Affero General Public License as published by the // Free Software Foundation, either version 3 of the License, or (at your // option) any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License // for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use std::io::{Error as IoError, ErrorKind as IoErrorKind}; use std::net::{IpAddr, Ipv6Addr, SocketAddr}; use camino::{Utf8Path, Utf8PathBuf}; use log::debug; use serde::{Deserialize, Serialize}; use xmpp::jid::{BareJid, ResourcePart}; use crate::error::Error; #[derive(Debug, Serialize, Deserialize)] pub struct Config { /// Account address pub jid: BareJid, /// Account password pub password: String, /// Rooms to join, e.g., room@chat.example.org #[serde(default = "Vec::new")] pub rooms: Vec, /// Nickname to use in rooms #[serde(default = "Config::default_nickname")] pub nickname: ResourcePart, /// Secret that matches the one provided to the Webhook service #[serde(rename = "secret")] pub secret: String, /// HTTP Webhook listening address and port, e.g., 127.0.0.1:1234 or [::1]:1234 #[serde(default = "Config::default_addr")] pub addr: SocketAddr, } impl Config { pub fn default_nickname() -> ResourcePart { ResourcePart::new("cusku").unwrap().into() } pub fn default_addr() -> SocketAddr { SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 3000) } pub async fn from_file(file: Utf8PathBuf) -> Result { if tokio::fs::try_exists(&file).await.is_err() { let err = IoError::new(IoErrorKind::NotFound, format!("{:?} not found", file)); return Err(Error::Io(err)); } let buf = tokio::fs::read_to_string(file).await?; Ok(toml::from_str(&buf)?) } pub async fn from_arg(file: Option<&Utf8PathBuf>) -> Result { let path = if let Some(path) = file { // Provided by --config flag path.canonicalize_utf8()? } else { let confdir: Utf8PathBuf = match std::env::var("XDG_CONFIG_HOME") { Ok(ref dir) => Utf8Path::new(dir).to_path_buf(), Err(_) => { let home = std::env::var("HOME")?; Utf8Path::new(home.as_str()).join(".config") } }; confdir.join("cusku/config.toml") }; debug!("Using configuration file: {:?}", path); Self::from_file(path).await } }