Case-insensitive node routing

This commit is contained in:
Juno Takano 2025-12-21 14:51:26 -03:00
commit 76b836f0a0
3 changed files with 35 additions and 5 deletions

View file

@ -18,10 +18,22 @@ pub fn populate_graph() -> Graph {
Graph {
nodes: nodes.clone(),
incoming: make_incoming(&nodes),
lowercase_keymap: map_lowercase_keys(&nodes),
..graph
}
}
fn map_lowercase_keys(
source_map: &HashMap<String, Node>,
) -> HashMap<String, String> {
let mut out_map: HashMap<String, String> = HashMap::new();
let keys = source_map.keys();
for key in keys {
out_map.insert(key.clone().to_lowercase(), key.clone());
}
out_map
}
fn modulate_nodes(old_nodes: &HashMap<String, Node>) -> HashMap<String, Node> {
let mut nodes: HashMap<String, Node> = HashMap::new();

View file

@ -1,4 +1,6 @@
use axum::{body::Body, extract::Path, http::Response};
use axum::response::IntoResponse as _;
use axum::{body::Body, extract::Path, http::Response, response::Redirect};
use crate::syntax::content;
use crate::{formats::populate_graph, handlers, types::Node};
@ -6,7 +8,12 @@ use crate::{formats::populate_graph, handlers, types::Node};
pub async fn node(Path(id): Path<String>) -> Response<Body> {
let graph = populate_graph();
let empty_node = Node::new(Some(format!("Could not find node ID {id}.")));
let node: &Node = graph.nodes.get(&id).unwrap_or(&empty_node);
let node = graph.find_node(&id).unwrap_or(empty_node.clone());
if !graph.nodes.contains_key(&id) {
return Redirect::permanent(format!("/node/{}", node.id).as_str())
.into_response();
}
let mut context = tera::Context::new();
context.insert("node", &node);
@ -14,11 +21,10 @@ pub async fn node(Path(id): Path<String>) -> Response<Body> {
context.insert("incoming", &graph.incoming.get(&id));
context.insert("config", &graph.meta.config.parse_text());
let not_found = *node == empty_node;
let template_name = "node.html".to_string();
let not_found = node == empty_node;
handlers::template::by_filename(
&template_name,
"node.html",
&context,
if not_found { 404 } else { 500 },
Some(

View file

@ -10,6 +10,8 @@ pub struct Graph {
pub root_node: String,
#[serde(skip_deserializing)]
pub incoming: HashMap<String, Vec<Edge>>,
#[serde(skip_deserializing)]
pub lowercase_keymap: HashMap<String, String>,
#[serde(default)]
pub meta: Meta,
}
@ -113,6 +115,7 @@ impl Graph {
nodes: HashMap::new(),
root_node: "VoidNode".to_string(),
incoming: HashMap::new(),
lowercase_keymap: HashMap::new(),
meta: Meta {
config: Config {
site_title: String::new(),
@ -140,6 +143,15 @@ impl Graph {
}
}
pub fn find_node(&self, query: &str) -> Option<Node> {
self.nodes.get(query).cloned().or_else(|| {
self.lowercase_keymap
.get(query)
.and_then(|lower_key| self.nodes.get(lower_key))
.cloned()
})
}
pub fn get_root(&self) -> Option<Node> {
self.nodes.get(&self.root_node).cloned()
}