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",
|
"clap",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"serde",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
@ -1017,6 +1019,15 @@ dependencies = [
|
||||||
"serde_core",
|
"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]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
@ -1175,6 +1186,45 @@ dependencies = [
|
||||||
"tokio",
|
"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]]
|
[[package]]
|
||||||
name = "tonic"
|
name = "tonic"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
|
@ -1513,6 +1563,12 @@ version = "0.53.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.8.27"
|
version = "0.8.27"
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ tracing = "0.1.41"
|
||||||
tracing-subscriber = "0.3.20"
|
tracing-subscriber = "0.3.20"
|
||||||
thiserror = "2.0.17"
|
thiserror = "2.0.17"
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
|
toml = "0.9.7"
|
||||||
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tokio-console = ["tokio/tracing", "console-subscriber"]
|
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,
|
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
|
// Conversion impls here
|
||||||
impl From<SenderError> for ListenerError {
|
impl From<SenderError> for ListenerError {
|
||||||
fn from(value: SenderError) -> Self {
|
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 anyhow::Error as AnyhowError;
|
||||||
|
use clap::Parser;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
io::{AsyncBufReadExt, BufReader as TokioBufReader, BufWriter as TokioBufWriter},
|
io::{AsyncBufReadExt, BufReader as TokioBufReader, BufWriter as TokioBufWriter},
|
||||||
|
|
@ -21,6 +22,7 @@ use tracing::instrument;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
channels::Channel,
|
channels::Channel,
|
||||||
|
config::ServerInfo,
|
||||||
error_structs::{HandlerError, ListenerError},
|
error_structs::{HandlerError, ListenerError},
|
||||||
login::send_motd,
|
login::send_motd,
|
||||||
messages::Message,
|
messages::Message,
|
||||||
|
|
@ -30,6 +32,7 @@ use crate::{
|
||||||
|
|
||||||
mod channels;
|
mod channels;
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod config;
|
||||||
mod error_structs;
|
mod error_structs;
|
||||||
mod login;
|
mod login;
|
||||||
mod messages;
|
mod messages;
|
||||||
|
|
@ -42,14 +45,12 @@ pub static JOINED_CHANNELS: Lazy<Mutex<HashSet<Channel>>> =
|
||||||
Lazy::new(|| Mutex::new(HashSet::new()));
|
Lazy::new(|| Mutex::new(HashSet::new()));
|
||||||
pub static SENDER: Lazy<Mutex<Option<Sender<Message>>>> = Lazy::new(|| Mutex::new(None));
|
pub static SENDER: Lazy<Mutex<Option<Sender<Message>>>> = Lazy::new(|| Mutex::new(None));
|
||||||
|
|
||||||
#[allow(dead_code)]
|
/// An IRCd written in Rust
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
struct ServerInfo {
|
struct Args {
|
||||||
ip: String,
|
/// Path to the config file
|
||||||
port: String,
|
#[arg(short, long)]
|
||||||
server_hostname: String,
|
pub config_path: Option<String>,
|
||||||
network_name: String,
|
|
||||||
operators: Vec<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
@ -57,13 +58,8 @@ async fn main() -> Result<(), AnyhowError> {
|
||||||
#[cfg(feature = "tokio-console")]
|
#[cfg(feature = "tokio-console")]
|
||||||
console_subscriber::init();
|
console_subscriber::init();
|
||||||
|
|
||||||
let info = ServerInfo {
|
let args = Args::parse();
|
||||||
ip: "0.0.0.0".into(),
|
let info = ServerInfo::load(args.config_path).unwrap();
|
||||||
port: "6667".into(),
|
|
||||||
server_hostname: "irc.blah.blah".into(),
|
|
||||||
network_name: "TeamDunno".into(),
|
|
||||||
operators: Vec::new(),
|
|
||||||
};
|
|
||||||
// TODO: ^ pull these from a config file
|
// TODO: ^ pull these from a config file
|
||||||
|
|
||||||
let listener = TcpListener::bind(SocketAddr::from_str(&format!("{}:{}", info.ip, info.port))?)?;
|
let listener = TcpListener::bind(SocketAddr::from_str(&format!("{}:{}", info.ip, info.port))?)?;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue