feat: config file support
This commit is contained in:
parent
594e376e21
commit
69fe2d00bc
6 changed files with 141 additions and 15 deletions
56
Cargo.lock
generated
56
Cargo.lock
generated
|
|
@ -617,8 +617,10 @@ dependencies = [
|
|||
"clap",
|
||||
"console-subscriber",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
|
@ -1017,6 +1019,15 @@ dependencies = [
|
|||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.7"
|
||||
|
|
@ -1175,6 +1186,45 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
|
||||
dependencies = [
|
||||
"indexmap 2.11.4",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.12.3"
|
||||
|
|
@ -1513,6 +1563,12 @@ version = "0.53.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.27"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ tracing = "0.1.41"
|
|||
tracing-subscriber = "0.3.20"
|
||||
thiserror = "2.0.17"
|
||||
anyhow = "1.0.100"
|
||||
toml = "0.9.7"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
|
||||
[features]
|
||||
tokio-console = ["tokio/tracing", "console-subscriber"]
|
||||
|
|
|
|||
5
examples/example_config.toml
Normal file
5
examples/example_config.toml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
ip = "0.0.0.0"
|
||||
port = 6667
|
||||
server_hostname = "irc.foo.bar"
|
||||
network_name = "MyCoolFooNet" # this SHOULDN'T HAVE SPACES!
|
||||
operators = []
|
||||
52
src/config.rs
Normal file
52
src/config.rs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
use std::{env::home_dir, fs::read_to_string, path::PathBuf};
|
||||
|
||||
use crate::error_structs::ConfigReadError;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
pub struct ServerInfo {
|
||||
pub ip: String,
|
||||
pub port: u64,
|
||||
pub server_hostname: String,
|
||||
pub network_name: String,
|
||||
pub operators: Vec<String>,
|
||||
}
|
||||
|
||||
fn get_config_path() -> Result<PathBuf, ConfigReadError> {
|
||||
if cfg!(target_os = "linux") {
|
||||
if let Some(mut homedir) = home_dir() {
|
||||
homedir.push(".config");
|
||||
homedir.push("irs");
|
||||
homedir.push("config.toml");
|
||||
|
||||
if homedir.exists() {
|
||||
return Ok(homedir);
|
||||
}
|
||||
}
|
||||
|
||||
let dir = PathBuf::from("/etc/irs/config.toml");
|
||||
if dir.exists() {
|
||||
dir
|
||||
} else {
|
||||
return Err(ConfigReadError::NoConfigFile);
|
||||
}
|
||||
} else {
|
||||
return Err(ConfigReadError::UnsupportedOS);
|
||||
};
|
||||
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
impl ServerInfo {
|
||||
pub fn load(path: Option<String>) -> Result<Self, ConfigReadError> {
|
||||
let path = if let Some(path) = path {
|
||||
PathBuf::from(path)
|
||||
} else {
|
||||
get_config_path()?
|
||||
};
|
||||
let config: ServerInfo = toml::from_str(&read_to_string(path)?)?;
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,21 @@ pub enum CommandExecError {
|
|||
NonexistantCommand,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ConfigReadError {
|
||||
#[error("could not find a config file")]
|
||||
NoConfigFile,
|
||||
|
||||
#[error("unsupported OS")]
|
||||
UnsupportedOS,
|
||||
|
||||
#[error("std::io error")]
|
||||
StdIoError(#[from] std::io::Error),
|
||||
|
||||
#[error("toml reading error")]
|
||||
TomlError(#[from] toml::de::Error),
|
||||
}
|
||||
|
||||
// Conversion impls here
|
||||
impl From<SenderError> for ListenerError {
|
||||
fn from(value: SenderError) -> Self {
|
||||
|
|
|
|||
26
src/main.rs
26
src/main.rs
|
|
@ -6,6 +6,7 @@ use std::{
|
|||
};
|
||||
|
||||
use anyhow::Error as AnyhowError;
|
||||
use clap::Parser;
|
||||
use once_cell::sync::Lazy;
|
||||
use tokio::{
|
||||
io::{AsyncBufReadExt, BufReader as TokioBufReader, BufWriter as TokioBufWriter},
|
||||
|
|
@ -21,6 +22,7 @@ use tracing::instrument;
|
|||
|
||||
use crate::{
|
||||
channels::Channel,
|
||||
config::ServerInfo,
|
||||
error_structs::{HandlerError, ListenerError},
|
||||
login::send_motd,
|
||||
messages::Message,
|
||||
|
|
@ -30,6 +32,7 @@ use crate::{
|
|||
|
||||
mod channels;
|
||||
mod commands;
|
||||
mod config;
|
||||
mod error_structs;
|
||||
mod login;
|
||||
mod messages;
|
||||
|
|
@ -42,14 +45,12 @@ pub static JOINED_CHANNELS: Lazy<Mutex<HashSet<Channel>>> =
|
|||
Lazy::new(|| Mutex::new(HashSet::new()));
|
||||
pub static SENDER: Lazy<Mutex<Option<Sender<Message>>>> = Lazy::new(|| Mutex::new(None));
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Clone, Debug)]
|
||||
struct ServerInfo {
|
||||
ip: String,
|
||||
port: String,
|
||||
server_hostname: String,
|
||||
network_name: String,
|
||||
operators: Vec<String>,
|
||||
/// An IRCd written in Rust
|
||||
#[derive(Parser, Debug)]
|
||||
struct Args {
|
||||
/// Path to the config file
|
||||
#[arg(short, long)]
|
||||
pub config_path: Option<String>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
|
|
@ -57,13 +58,8 @@ async fn main() -> Result<(), AnyhowError> {
|
|||
#[cfg(feature = "tokio-console")]
|
||||
console_subscriber::init();
|
||||
|
||||
let info = ServerInfo {
|
||||
ip: "0.0.0.0".into(),
|
||||
port: "6667".into(),
|
||||
server_hostname: "irc.blah.blah".into(),
|
||||
network_name: "TeamDunno".into(),
|
||||
operators: Vec::new(),
|
||||
};
|
||||
let args = Args::parse();
|
||||
let info = ServerInfo::load(args.config_path).unwrap();
|
||||
// TODO: ^ pull these from a config file
|
||||
|
||||
let listener = TcpListener::bind(SocketAddr::from_str(&format!("{}:{}", info.ip, info.port))?)?;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue