Handle CLI arguments as structured argument-parameter pairs
This commit is contained in:
parent
f811c33192
commit
2040854e82
7 changed files with 83 additions and 15 deletions
|
|
@ -1,9 +1,13 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use crate::types::{Graph, Node, Edge};
|
||||
use crate::{
|
||||
syntax::arguments::Arguments,
|
||||
types::{Edge, Graph, Node},
|
||||
};
|
||||
|
||||
pub fn populate_graph() -> Graph {
|
||||
let toml_source = match std::fs::read_to_string("./static/graph.toml") {
|
||||
let args = Arguments::new().parse();
|
||||
let toml_source = match std::fs::read_to_string(args.graph_path) {
|
||||
Ok(s) => s,
|
||||
Err(e) => format!("Error: {e}"),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@ use axum::{
|
|||
http::{Response, StatusCode, header, HeaderValue},
|
||||
};
|
||||
|
||||
use crate::formats::{Format, populate_graph, serialize_graph};
|
||||
use crate::{
|
||||
formats::{Format, populate_graph, serialize_graph},
|
||||
};
|
||||
use crate::handlers;
|
||||
|
||||
pub async fn file(file_path: &str, content_type: &str) -> Response<Body> {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,14 @@
|
|||
use axum::{body::Body, extract::Path, http::Response};
|
||||
|
||||
use crate::{formats::populate_graph, types::Node, handlers};
|
||||
use crate::{formats::populate_graph, handlers, types::Node};
|
||||
|
||||
pub async fn node(Path(id): Path<String>) -> Response<Body> {
|
||||
let mut context = tera::Context::new();
|
||||
|
||||
let graph = populate_graph();
|
||||
let nodes = graph.nodes;
|
||||
let empty_node =
|
||||
Node::new(Some(format!("Could not find node with ID {id}.")));
|
||||
let empty_node = Node::new(Some(format!("Could not find node ID {id}.")));
|
||||
|
||||
let node: &Node = nodes.get(&id).unwrap_or(&empty_node);
|
||||
let node: &Node = graph.nodes.get(&id).unwrap_or(&empty_node);
|
||||
|
||||
context.insert("id", &id);
|
||||
context.insert("title", &node.title);
|
||||
|
|
|
|||
10
src/main.rs
10
src/main.rs
|
|
@ -1,4 +1,4 @@
|
|||
use std::{backtrace, env, io, panic, sync, time};
|
||||
use std::{backtrace, io, panic, sync, time};
|
||||
|
||||
use axum::{routing::get, Router};
|
||||
|
||||
|
|
@ -7,6 +7,7 @@ use formats::Format;
|
|||
mod formats;
|
||||
mod types;
|
||||
mod handlers;
|
||||
mod syntax;
|
||||
mod dev;
|
||||
|
||||
static ONSET: sync::LazyLock<time::Instant> =
|
||||
|
|
@ -14,9 +15,8 @@ static ONSET: sync::LazyLock<time::Instant> =
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
let default_address = "0.0.0.0:0".to_string();
|
||||
let address: &String = args.get(1).unwrap_or(&default_address);
|
||||
let args = syntax::arguments::Arguments::new().parse();
|
||||
let address = args.make_address();
|
||||
|
||||
panic::set_hook(Box::new(|info| {
|
||||
let payload = info
|
||||
|
|
@ -73,7 +73,7 @@ async fn main() -> io::Result<()> {
|
|||
.fallback(handlers::error::not_found);
|
||||
|
||||
let listener =
|
||||
tokio::net::TcpListener::bind(address).await.map_err(|e| {
|
||||
tokio::net::TcpListener::bind(&address).await.map_err(|e| {
|
||||
dev::log(
|
||||
&main,
|
||||
&format!("Failed to create listener at {address}: {e:#?}"),
|
||||
|
|
|
|||
1
src/syntax.rs
Normal file
1
src/syntax.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
pub mod arguments;
|
||||
63
src/syntax/arguments.rs
Normal file
63
src/syntax/arguments.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Arguments {
|
||||
pub hostname: String,
|
||||
pub port: u16,
|
||||
pub graph_path: PathBuf,
|
||||
}
|
||||
|
||||
impl Arguments {
|
||||
pub fn make_address(&self) -> String {
|
||||
format!("{}:{}", self.hostname, self.port)
|
||||
}
|
||||
|
||||
pub fn new() -> Arguments {
|
||||
Arguments {
|
||||
hostname: String::from("0.0.0.0"),
|
||||
port: 0,
|
||||
graph_path: PathBuf::from("./static/graph.toml"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(&self) -> Arguments {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
parse(self, &args)
|
||||
}
|
||||
}
|
||||
|
||||
fn parse(defaults: &Arguments, args: &[String]) -> Arguments {
|
||||
let mut out_args = defaults.clone();
|
||||
|
||||
let filtered_args = if let Some((head, tail)) = args.split_first() {
|
||||
if head.starts_with('-') { args } else { tail }
|
||||
} else {
|
||||
args
|
||||
};
|
||||
|
||||
for arg in filtered_args.chunks(2) {
|
||||
if let Some(argument) = arg.first()
|
||||
&& let Some(parameter) = arg.last()
|
||||
{
|
||||
if argument.eq("-h") || argument.eq("--hostname") {
|
||||
out_args.hostname = String::from(parameter);
|
||||
} else if argument.eq("-p") || argument.eq("--port") {
|
||||
out_args.port = parameter.parse().unwrap_or(out_args.port);
|
||||
} else if argument.eq("-g") || argument.eq("--graph") {
|
||||
out_args.graph_path = PathBuf::from(parameter);
|
||||
} else {
|
||||
crate::dev::log(
|
||||
&parse,
|
||||
&format!("Dropped unrecognized argument {argument}"),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
crate::dev::log(
|
||||
&parse,
|
||||
"Dropped: Couldn't pair either one of or
|
||||
both argument \"{argument}\", parameter \"{parameter}\"",
|
||||
);
|
||||
}
|
||||
}
|
||||
out_args
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue