use crate::{
context::{Node, Router},
error::RouterError,
operations::util::{normalize, split_path},
};
pub fn remove_route<T>(
router: &Router<T>,
method: &str,
path_pattern_to_remove: &str,
) -> Result<bool, RouterError> {
let normalized_path_string = normalize(path_pattern_to_remove);
let segments: Vec<&str> = split_path(&normalized_path_string).collect();
let mut root_lock = router.root.write();
let mut modified_in_trie = false;
if segments.is_empty() {
if let Some(handlers) = root_lock.methods.get_mut(method) {
if !handlers.is_empty() {
handlers.clear();
modified_in_trie = true;
}
}
if root_lock.methods.get(method).is_some_and(|h| h.is_empty()) {
root_lock.methods.remove(method);
}
} else {
modified_in_trie = recurse_remove(&mut *root_lock, method, &segments, 0);
}
let mut modified_in_static_map = false;
if !normalized_path_string.contains([':', '*']) {
let mut static_map_lock = router.static_map.write();
if let Some(methods_for_path) = static_map_lock.get_mut(&normalized_path_string) {
if methods_for_path.remove(method).is_some() {
modified_in_static_map = true;
}
if methods_for_path.is_empty() {
static_map_lock.shift_remove(&normalized_path_string);
}
}
}
Ok(modified_in_trie || modified_in_static_map)
}
fn recurse_remove<T>(
current_node: &mut Node<T>,
method: &str,
pattern_segments: &[&str],
idx: usize,
) -> bool {
if idx >= pattern_segments.len() {
let mut handler_removed_at_this_node = false;
if let Some(handlers) = current_node.methods.get_mut(method) {
if !handlers.is_empty() {
handlers.clear();
handler_removed_at_this_node = true;
}
}
if current_node
.methods
.get(method)
.is_some_and(|h| h.is_empty())
{
current_node.methods.remove(method);
}
return handler_removed_at_this_node;
}
let segment_str_of_pattern = pattern_segments[idx];
let mut modified_in_child_branch = false;
let temp_segment_for_type_check = segment_str_of_pattern
.strip_suffix('?')
.unwrap_or(segment_str_of_pattern);
if temp_segment_for_type_check.starts_with("**") {
if let Some(wc_child_box) = current_node.wildcard_child.as_mut() {
if recurse_remove(wc_child_box, method, pattern_segments, idx + 1) {
modified_in_child_branch = true;
if wc_child_box.as_ref().is_empty_recursive() {
current_node.wildcard_child = None;
}
}
}
} else if temp_segment_for_type_check.starts_with(':') || temp_segment_for_type_check == "*" {
if let Some(param_child_box) = current_node.param_child.as_mut() {
if recurse_remove(param_child_box, method, pattern_segments, idx + 1) {
modified_in_child_branch = true;
if param_child_box.as_ref().is_empty_recursive() {
current_node.param_child = None;
}
}
}
} else if let Some(static_child_box) =
current_node.static_children.get_mut(segment_str_of_pattern)
{
if recurse_remove(static_child_box, method, pattern_segments, idx + 1) {
modified_in_child_branch = true;
if static_child_box.as_ref().is_empty_recursive() {
current_node.static_children.remove(segment_str_of_pattern);
}
}
}
modified_in_child_branch
}