Remove code comments
This commit is contained in:
parent
a5e58493d8
commit
52d7c13013
17 changed files with 18 additions and 335 deletions
|
|
@ -1,33 +1,20 @@
|
|||
//! Configuration: the [`Config`] one network needs, and how a config file
|
||||
//! (with optional `[network]` sections) plus environment variables are layered
|
||||
//! into one [`Config`] per network.
|
||||
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::log;
|
||||
|
||||
/// Everything the bot needs to know to connect to one network and behave.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Config {
|
||||
/// Short label for this network, used in logs and as the thread name. Set
|
||||
/// via an INI-style `[section]` header (or a `name =` key); defaults to the
|
||||
/// server host. Only one network? It stays out of the logs entirely.
|
||||
pub name: String,
|
||||
pub server: String,
|
||||
pub port: u16,
|
||||
/// Connect over TLS (typically port 6697) instead of plaintext.
|
||||
pub tls: bool,
|
||||
pub nick: String,
|
||||
pub user: String,
|
||||
pub realname: String,
|
||||
pub channels: Vec<String>,
|
||||
/// Prefix that marks a chat message as a bot command, e.g. `!`.
|
||||
pub command_prefix: String,
|
||||
/// Optional server password (`PASS`). Not the same as SASL/NickServ.
|
||||
pub password: Option<String>,
|
||||
/// SASL PLAIN credentials. When both are set (and the server offers `sasl`),
|
||||
/// the bot authenticates during capability negotiation.
|
||||
pub sasl_user: Option<String>,
|
||||
pub sasl_pass: Option<String>,
|
||||
}
|
||||
|
|
@ -51,19 +38,8 @@ impl Default for Config {
|
|||
}
|
||||
}
|
||||
|
||||
/// A parsed `key = value` pair with its 1-based source line, for diagnostics.
|
||||
type Entry = (usize, String, String);
|
||||
|
||||
/// Build one [`Config`] per network by layering sources.
|
||||
///
|
||||
/// The config file is INI-flavoured: `key = value` lines, optionally grouped
|
||||
/// under `[network]` section headers. Keys *before* the first header are shared
|
||||
/// defaults; each `[section]` defines one network that inherits those defaults
|
||||
/// and overrides them. A file with **no** sections yields a single network —
|
||||
/// exactly the historical behaviour.
|
||||
///
|
||||
/// Precedence within a network: built-in defaults < shared file defaults <
|
||||
/// environment variables < that network's section.
|
||||
pub fn load() -> Vec<Config> {
|
||||
let path = config_path();
|
||||
let content = path.as_ref().and_then(|p| match fs::read_to_string(p) {
|
||||
|
|
@ -82,8 +58,6 @@ pub fn load() -> Vec<Config> {
|
|||
None => (Vec::new(), Vec::new()),
|
||||
};
|
||||
|
||||
// Shared defaults: built-ins, then top-level keys, then environment. Each
|
||||
// network is derived from this base.
|
||||
let mut base = Config::default();
|
||||
for (line, key, value) in &toplevel {
|
||||
apply_kv(&mut base, key, value, &loc(&path, *line));
|
||||
|
|
@ -93,8 +67,6 @@ pub fn load() -> Vec<Config> {
|
|||
assemble(base, sections, &path)
|
||||
}
|
||||
|
||||
/// Parse networks from config *text* alone — no file access, no environment.
|
||||
/// Handy for tests and for embedding rustbot. Warnings reference `line N`.
|
||||
pub fn parse_str(content: &str) -> Vec<Config> {
|
||||
let (toplevel, sections) = parse_sections(content);
|
||||
let mut base = Config::default();
|
||||
|
|
@ -104,9 +76,6 @@ pub fn parse_str(content: &str) -> Vec<Config> {
|
|||
assemble(base, sections, &None)
|
||||
}
|
||||
|
||||
/// Derive one finished [`Config`] per network from the shared `base` and the
|
||||
/// parsed sections. With no sections, `base` itself is the single network.
|
||||
/// `path` is used only to describe locations in warnings.
|
||||
fn assemble(base: Config, sections: Vec<(String, Vec<Entry>)>, path: &Option<PathBuf>) -> Vec<Config> {
|
||||
let mut configs = Vec::new();
|
||||
if sections.is_empty() {
|
||||
|
|
@ -127,9 +96,6 @@ fn assemble(base: Config, sections: Vec<(String, Vec<Entry>)>, path: &Option<Pat
|
|||
configs
|
||||
}
|
||||
|
||||
/// Per-network finishing touches: default the label to the server host, and
|
||||
/// honour the TLS-port convention (6697) when TLS is on but the port is still
|
||||
/// the plaintext default.
|
||||
fn finalize(c: &mut Config) {
|
||||
if c.name.is_empty() {
|
||||
c.name = c.server.clone();
|
||||
|
|
@ -139,12 +105,6 @@ fn finalize(c: &mut Config) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Split config text into shared top-level entries and `[name]` sections.
|
||||
///
|
||||
/// Blank lines and whole-line `#`/`;` comments are ignored. A `[name]` line
|
||||
/// opens a section; entries after it belong to that network until the next
|
||||
/// header. Lines that are neither a header nor `key = value` are reported and
|
||||
/// skipped.
|
||||
fn parse_sections(content: &str) -> (Vec<Entry>, Vec<(String, Vec<Entry>)>) {
|
||||
let mut toplevel: Vec<Entry> = Vec::new();
|
||||
let mut sections: Vec<(String, Vec<Entry>)> = Vec::new();
|
||||
|
|
@ -155,7 +115,6 @@ fn parse_sections(content: &str) -> (Vec<Entry>, Vec<(String, Vec<Entry>)>) {
|
|||
if line.is_empty() || line.starts_with('#') || line.starts_with(';') {
|
||||
continue;
|
||||
}
|
||||
// Section header: `[name]`.
|
||||
if let Some(inner) = line.strip_prefix('[').and_then(|s| s.strip_suffix(']')) {
|
||||
sections.push((inner.trim().to_string(), Vec::new()));
|
||||
continue;
|
||||
|
|
@ -173,8 +132,6 @@ fn parse_sections(content: &str) -> (Vec<Entry>, Vec<(String, Vec<Entry>)>) {
|
|||
(toplevel, sections)
|
||||
}
|
||||
|
||||
/// Apply a single `key = value` pair onto `c`. `where_` describes the source
|
||||
/// location for warnings (e.g. `rustbot.conf:12`).
|
||||
fn apply_kv(c: &mut Config, key: &str, value: &str, where_: &str) {
|
||||
match key {
|
||||
"name" => c.name = value.to_string(),
|
||||
|
|
@ -196,7 +153,6 @@ fn apply_kv(c: &mut Config, key: &str, value: &str, where_: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Format a source location for a line, including the file path when known.
|
||||
fn loc(path: &Option<PathBuf>, line: usize) -> String {
|
||||
match path {
|
||||
Some(p) => format!("{}:{}", p.display(), line),
|
||||
|
|
@ -204,8 +160,6 @@ fn loc(path: &Option<PathBuf>, line: usize) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
/// Decide which config file to read: CLI argument, then `RUSTBOT_CONFIG`, then
|
||||
/// `./rustbot.conf` if it happens to exist. Returns `None` when there is none.
|
||||
fn config_path() -> Option<PathBuf> {
|
||||
if let Some(arg) = std::env::args().nth(1) {
|
||||
return Some(PathBuf::from(arg));
|
||||
|
|
@ -217,12 +171,6 @@ fn config_path() -> Option<PathBuf> {
|
|||
default.exists().then_some(default)
|
||||
}
|
||||
|
||||
/// Overlay environment variables onto `c` (applied to the shared defaults, so
|
||||
/// they affect every network unless a `[section]` overrides them).
|
||||
///
|
||||
/// Vars: `IRC_SERVER`, `IRC_PORT`, `IRC_TLS`, `IRC_NICK`, `IRC_REALNAME`,
|
||||
/// `IRC_CHANNELS` (comma/space-separated), `IRC_PREFIX`, `IRC_PASSWORD`,
|
||||
/// `IRC_SASL_USER`, `IRC_SASL_PASS`.
|
||||
fn apply_env(c: &mut Config) {
|
||||
if let Ok(v) = std::env::var("IRC_SERVER") {
|
||||
c.server = v;
|
||||
|
|
@ -257,7 +205,6 @@ fn apply_env(c: &mut Config) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse a boolean config value. Accepts `1`, `true`, `yes`, `on` (any case).
|
||||
fn parse_bool(value: &str) -> bool {
|
||||
matches!(
|
||||
value.trim().to_ascii_lowercase().as_str(),
|
||||
|
|
@ -265,7 +212,6 @@ fn parse_bool(value: &str) -> bool {
|
|||
)
|
||||
}
|
||||
|
||||
/// Split a channel list on commas and/or whitespace, dropping empties.
|
||||
fn split_list(value: &str) -> Vec<String> {
|
||||
value
|
||||
.split(|ch: char| ch == ',' || ch.is_whitespace())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue