Add and resolve an obscene amount of lints
This commit is contained in:
parent
b306f04664
commit
0d0627ba8f
5 changed files with 264 additions and 56 deletions
189
Cargo.toml
189
Cargo.toml
|
|
@ -9,6 +9,15 @@ repository = "https://codeberg.org/jutty/en"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
rust-version= "1.91.1"
|
rust-version= "1.91.1"
|
||||||
|
|
||||||
|
[lints.rust]
|
||||||
|
# levels: allow, expect, warn, force-warn, deny, forbid
|
||||||
|
unsafe_code = { level = "forbid", priority = 99 }
|
||||||
|
unused = { level = "warn", priority = 10 }
|
||||||
|
let_underscore= { level = "warn", priority = 10 }
|
||||||
|
nonstandard-style = "warn"
|
||||||
|
future-incompatible = "warn"
|
||||||
|
keyword-idents = "warn"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8.7"
|
axum = "0.8.7"
|
||||||
tokio = { version = "1.48.0", features = ["rt-multi-thread"] }
|
tokio = { version = "1.48.0", features = ["rt-multi-thread"] }
|
||||||
|
|
@ -16,3 +25,183 @@ tera = { version = "1.20.1", features = ["builtins"] }
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
serde = { version = "1.0.228", features = ["derive"] }
|
serde = { version = "1.0.228", features = ["derive"] }
|
||||||
toml = "0.9.8"
|
toml = "0.9.8"
|
||||||
|
|
||||||
|
[lints.clippy]
|
||||||
|
# levels: allow, warn, deny, forbid
|
||||||
|
|
||||||
|
# pedantic
|
||||||
|
assigning_clones = "warn"
|
||||||
|
borrow_as_ptr = "warn"
|
||||||
|
cast_lossless = "warn"
|
||||||
|
cast_possible_wrap = "warn"
|
||||||
|
cast_ptr_alignment = "warn"
|
||||||
|
cast_sign_loss = "warn"
|
||||||
|
checked_conversions = "warn"
|
||||||
|
cloned_instead_of_copied = "warn"
|
||||||
|
comparison_chain = "warn"
|
||||||
|
copy_iterator = "warn"
|
||||||
|
default_trait_access = "warn"
|
||||||
|
doc_broken_link = "warn"
|
||||||
|
doc_comment_double_space_linebreaks = "warn"
|
||||||
|
doc_link_with_quotes = "warn"
|
||||||
|
doc_markdown = "warn"
|
||||||
|
empty_enum = "warn"
|
||||||
|
enum_glob_use = "warn"
|
||||||
|
expl_impl_clone_on_copy = "warn"
|
||||||
|
explicit_deref_methods = "warn"
|
||||||
|
explicit_into_iter_loop = "warn"
|
||||||
|
explicit_iter_loop = "warn"
|
||||||
|
filter_map_next = "warn"
|
||||||
|
flat_map_option = "warn"
|
||||||
|
float_cmp = "warn"
|
||||||
|
fn_params_excessive_bools = "warn"
|
||||||
|
format_push_string = "warn"
|
||||||
|
from_iter_instead_of_collect = "warn"
|
||||||
|
if_not_else = "warn"
|
||||||
|
ignore_without_reason = "warn"
|
||||||
|
ignored_unit_patterns = "warn"
|
||||||
|
implicit_clone = "warn"
|
||||||
|
implicit_hasher = "warn"
|
||||||
|
inconsistent_struct_constructor = "warn"
|
||||||
|
index_refutable_slice = "warn"
|
||||||
|
inefficient_to_string = "warn"
|
||||||
|
invalid_upcast_comparisons = "warn"
|
||||||
|
ip_constant = "warn"
|
||||||
|
iter_filter_is_ok = "warn"
|
||||||
|
iter_filter_is_some = "warn"
|
||||||
|
large_digit_groups = "warn"
|
||||||
|
large_futures = "warn"
|
||||||
|
large_stack_arrays = "warn"
|
||||||
|
large_types_passed_by_value = "warn"
|
||||||
|
linkedlist = "warn"
|
||||||
|
manual_assert = "warn"
|
||||||
|
manual_instant_elapsed = "warn"
|
||||||
|
manual_is_power_of_two = "warn"
|
||||||
|
manual_is_variant_and = "warn"
|
||||||
|
manual_let_else = "warn"
|
||||||
|
manual_midpoint = "warn"
|
||||||
|
manual_string_new = "warn"
|
||||||
|
many_single_char_names = "warn"
|
||||||
|
map_unwrap_or = "warn"
|
||||||
|
match_bool = "warn"
|
||||||
|
match_same_arms = "warn"
|
||||||
|
match_wild_err_arm = "warn"
|
||||||
|
match_wildcard_for_single_variants = "warn"
|
||||||
|
maybe_infinite_iter = "warn"
|
||||||
|
mismatching_type_param_order = "warn"
|
||||||
|
missing_errors_doc = "warn"
|
||||||
|
missing_fields_in_debug = "warn"
|
||||||
|
missing_panics_doc = "warn"
|
||||||
|
must_use_candidate = "warn"
|
||||||
|
mut_mut = "warn"
|
||||||
|
naive_bytecount = "warn"
|
||||||
|
needless_continue = "warn"
|
||||||
|
needless_for_each = "warn"
|
||||||
|
needless_pass_by_value = "warn"
|
||||||
|
needless_raw_string_hashes = "warn"
|
||||||
|
no_effect_underscore_binding = "warn"
|
||||||
|
option_as_ref_cloned = "warn"
|
||||||
|
option_option = "warn"
|
||||||
|
ptr_as_ptr = "warn"
|
||||||
|
ptr_cast_constness = "warn"
|
||||||
|
pub_underscore_fields = "warn"
|
||||||
|
range_minus_one = "warn"
|
||||||
|
range_plus_one = "warn"
|
||||||
|
redundant_closure_for_method_calls = "warn"
|
||||||
|
ref_as_ptr = "warn"
|
||||||
|
ref_binding_to_reference = "warn"
|
||||||
|
ref_option = "warn"
|
||||||
|
ref_option_ref = "warn"
|
||||||
|
return_self_not_must_use = "warn"
|
||||||
|
same_functions_in_if_condition = "warn"
|
||||||
|
semicolon_if_nothing_returned = "warn"
|
||||||
|
should_panic_without_expect = "warn"
|
||||||
|
similar_names = "warn"
|
||||||
|
str_split_at_newline = "warn"
|
||||||
|
struct_excessive_bools = "warn"
|
||||||
|
struct_field_names = "warn"
|
||||||
|
trivially_copy_pass_by_ref = "warn"
|
||||||
|
unchecked_duration_subtraction = "warn"
|
||||||
|
unicode_not_nfc = "warn"
|
||||||
|
uninlined_format_args = "warn"
|
||||||
|
unnecessary_box_returns = "warn"
|
||||||
|
unnecessary_debug_formatting = "warn"
|
||||||
|
unnecessary_join = "warn"
|
||||||
|
unnecessary_literal_bound = "warn"
|
||||||
|
unnecessary_semicolon = "warn"
|
||||||
|
unnecessary_wraps = "warn"
|
||||||
|
unnested_or_patterns = "warn"
|
||||||
|
unreadable_literal = "warn"
|
||||||
|
unsafe_derive_deserialize = "warn"
|
||||||
|
unused_async = "warn"
|
||||||
|
unused_self = "warn"
|
||||||
|
used_underscore_binding = "warn"
|
||||||
|
wildcard_imports = "warn"
|
||||||
|
zero_sized_map_values = "warn"
|
||||||
|
|
||||||
|
# restrictive
|
||||||
|
allow_attributes = "forbid"
|
||||||
|
arithmetic_side_effects = "warn"
|
||||||
|
as_conversions = "warn"
|
||||||
|
as_pointer_underscore = "warn"
|
||||||
|
as_underscore = "warn"
|
||||||
|
default_numeric_fallback = "warn"
|
||||||
|
deref_by_slicing = "warn"
|
||||||
|
else_if_without_else = "warn"
|
||||||
|
empty_drop = "warn"
|
||||||
|
empty_enum_variants_with_brackets = "warn"
|
||||||
|
error_impl_error = "warn"
|
||||||
|
exit = "warn"
|
||||||
|
expect_used = "warn"
|
||||||
|
filetype_is_file = "warn"
|
||||||
|
float_cmp_const = "warn"
|
||||||
|
fn_to_numeric_cast_any = "warn"
|
||||||
|
get_unwrap = "warn"
|
||||||
|
if_then_some_else_none = "warn"
|
||||||
|
indexing_slicing = "warn"
|
||||||
|
infinite_loop = "warn"
|
||||||
|
integer_division = "warn"
|
||||||
|
integer_division_remainder_used = "warn"
|
||||||
|
let_underscore_must_use = "warn"
|
||||||
|
let_underscore_untyped = "warn"
|
||||||
|
lossy_float_literal = "warn"
|
||||||
|
map_err_ignore = "warn"
|
||||||
|
map_with_unused_argument_over_ranges = "warn"
|
||||||
|
missing_assert_message = "warn"
|
||||||
|
missing_asserts_for_indexing = "warn"
|
||||||
|
mixed_read_write_in_expression = "warn"
|
||||||
|
module_name_repetitions = "warn"
|
||||||
|
multiple_inherent_impl = "warn"
|
||||||
|
needless_raw_strings = "warn"
|
||||||
|
non_zero_suggestions = "warn"
|
||||||
|
panic_in_result_fn = "warn"
|
||||||
|
pathbuf_init_then_push = "warn"
|
||||||
|
pattern_type_mismatch = "warn"
|
||||||
|
pub_without_shorthand = "warn"
|
||||||
|
redundant_test_prefix = "warn"
|
||||||
|
redundant_type_annotations = "warn"
|
||||||
|
ref_patterns = "warn"
|
||||||
|
renamed_function_params = "warn"
|
||||||
|
rest_pat_in_fully_bound_structs = "warn"
|
||||||
|
return_and_then = "warn"
|
||||||
|
same_name_method = "warn"
|
||||||
|
semicolon_inside_block = "warn"
|
||||||
|
shadow_reuse = "warn"
|
||||||
|
shadow_same = "warn"
|
||||||
|
shadow_unrelated = "warn"
|
||||||
|
single_char_lifetime_names = "warn"
|
||||||
|
string_add = "warn"
|
||||||
|
string_lit_chars_any = "warn"
|
||||||
|
tests_outside_test_module = "warn"
|
||||||
|
unnecessary_self_imports = "warn"
|
||||||
|
unneeded_field_pattern = "warn"
|
||||||
|
unseparated_literal_suffix = "warn"
|
||||||
|
unused_result_ok = "warn"
|
||||||
|
unused_trait_names = "warn"
|
||||||
|
unwrap_used = "warn"
|
||||||
|
verbose_file_reads = "warn"
|
||||||
|
wildcard_enum_match_arm = "warn"
|
||||||
|
|
||||||
|
# cargo
|
||||||
|
negative_feature_names = "warn"
|
||||||
|
redundant_feature_names = "warn"
|
||||||
|
|
|
||||||
22
docs/notes.md
Normal file
22
docs/notes.md
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Notes
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
When adding CI jobs, consider the following lints:
|
||||||
|
|
||||||
|
- `clippy::dbg_macro`
|
||||||
|
- `clippy::print_stderr`
|
||||||
|
- `clippy::print_stdout`
|
||||||
|
- `clippy::todo`
|
||||||
|
- `clippy::unimplemented`
|
||||||
|
- `clippy::unreachable`
|
||||||
|
- `clippy::use_debug`
|
||||||
|
|
||||||
|
## BTreeMap
|
||||||
|
|
||||||
|
Consider replacing HashMap with BTreeMap to stop nodes from shifting position constantly on every page load.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
- <https://doc.rust-lang.org/std/collections/struct.BTreeMap.html#background>
|
||||||
|
- `clippy::iter_over_hash_type`
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::types::*;
|
use crate::types::{Graph, Node, Edge};
|
||||||
|
|
||||||
pub fn populate_graph() -> Graph {
|
pub fn populate_graph() -> Graph {
|
||||||
|
|
||||||
|
|
@ -8,22 +8,22 @@ pub fn populate_graph() -> Graph {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => format!("Error: {e}"),
|
Err(e) => format!("Error: {e}"),
|
||||||
};
|
};
|
||||||
let graph = deserialize_graph(Format::Toml, &toml_source);
|
let graph = deserialize_graph(&Format::Toml, &toml_source);
|
||||||
|
|
||||||
let nodes = modulate_nodes(graph.nodes.clone());
|
let nodes = modulate_nodes(&graph.nodes);
|
||||||
|
|
||||||
Graph {
|
Graph {
|
||||||
nodes: nodes.clone(),
|
nodes: nodes.clone(),
|
||||||
incoming: make_incoming(nodes.clone()),
|
incoming: make_incoming(&nodes),
|
||||||
..graph
|
..graph
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn modulate_nodes(old_nodes: HashMap<String, Node>) -> HashMap<String, Node> {
|
fn modulate_nodes(old_nodes: &HashMap<String, Node>) -> HashMap<String, Node> {
|
||||||
|
|
||||||
let mut nodes: HashMap<String, Node> = HashMap::new();
|
let mut nodes: HashMap<String, Node> = HashMap::new();
|
||||||
|
|
||||||
for (key, node) in old_nodes.iter() {
|
for (key, node) in old_nodes {
|
||||||
|
|
||||||
let connections = node.connections.clone().unwrap_or_default();
|
let connections = node.connections.clone().unwrap_or_default();
|
||||||
let mut new_edges = connections.clone();
|
let mut new_edges = connections.clone();
|
||||||
|
|
@ -33,8 +33,8 @@ fn modulate_nodes(old_nodes: HashMap<String, Node>) -> HashMap<String, Node> {
|
||||||
let mut new_edge = edge.clone();
|
let mut new_edge = edge.clone();
|
||||||
|
|
||||||
// Populate empty "from" IDs in edges with node's ID
|
// Populate empty "from" IDs in edges with node's ID
|
||||||
if edge.from == "" {
|
if edge.from.is_empty() {
|
||||||
new_edge.from = key.to_string();
|
new_edge.from.clone_from(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flag detached edges
|
// Flag detached edges
|
||||||
|
|
@ -42,17 +42,17 @@ fn modulate_nodes(old_nodes: HashMap<String, Node>) -> HashMap<String, Node> {
|
||||||
new_edge.detached = true;
|
new_edge.detached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_edges[i] = new_edge;
|
if let Some(e) = new_edges.get_mut(i) { *e = new_edge; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create connections for each link
|
// Create connections for each link
|
||||||
for link in node.links.iter() {
|
for link in &node.links {
|
||||||
new_edges.push(Edge {
|
new_edges.push(Edge {
|
||||||
from: key.to_string(),
|
from: key.clone(),
|
||||||
to: link.to_string(),
|
to: link.clone(),
|
||||||
anchor: String::new(),
|
anchor: String::new(),
|
||||||
detached: !old_nodes.contains_key(link),
|
detached: !old_nodes.contains_key(link),
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate empty titles with IDs
|
// Populate empty titles with IDs
|
||||||
|
|
@ -69,22 +69,22 @@ fn modulate_nodes(old_nodes: HashMap<String, Node>) -> HashMap<String, Node> {
|
||||||
..node.clone()
|
..node.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
nodes.insert(key.to_string(), new_node);
|
nodes.insert(key.clone(), new_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes
|
nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a HashMap with incoming connections (reversed edges)
|
// Construct a HashMap with incoming connections (reversed edges)
|
||||||
fn make_incoming(nodes: HashMap<String, Node>) -> HashMap<String, Vec<Edge>> {
|
fn make_incoming(nodes: &HashMap<String, Node>) -> HashMap<String, Vec<Edge>> {
|
||||||
|
|
||||||
let mut incoming: HashMap<String, Vec<Edge>> = HashMap::new();
|
let mut incoming: HashMap<String, Vec<Edge>> = HashMap::new();
|
||||||
for node in nodes.clone().into_values() {
|
for node in nodes.clone().into_values() {
|
||||||
|
|
||||||
let empty_vec: Vec<Edge> = vec![];
|
let empty_vec: Vec<Edge> = vec![];
|
||||||
for edge in node.connections.clone().unwrap_or_default().iter() {
|
for edge in &node.connections.clone().unwrap_or_default() {
|
||||||
let mut edges = incoming.get(&edge.to.clone()).unwrap_or(&empty_vec).clone();
|
let mut edges = incoming.get(&edge.to.clone()).unwrap_or(&empty_vec).clone();
|
||||||
edges.extend_from_slice(&[edge.clone()]);
|
edges.extend_from_slice(std::slice::from_ref(edge));
|
||||||
incoming.insert(edge.to.clone(), edges.clone());
|
incoming.insert(edge.to.clone(), edges.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,9 +97,9 @@ pub enum Format {
|
||||||
Json
|
Json
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn serialize_graph(out_format: Format, graph: &Graph) -> String {
|
pub fn serialize_graph(out_format: &Format, graph: &Graph) -> String {
|
||||||
|
|
||||||
match out_format {
|
match *out_format {
|
||||||
Format::Toml => {
|
Format::Toml => {
|
||||||
match toml::to_string(graph) {
|
match toml::to_string(graph) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
|
|
@ -115,14 +115,14 @@ pub fn serialize_graph(out_format: Format, graph: &Graph) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deserialize_graph(in_format: Format, serial: &String) -> Graph {
|
pub fn deserialize_graph(in_format: &Format, serial: &str) -> Graph {
|
||||||
|
|
||||||
match in_format {
|
match *in_format {
|
||||||
Format::Toml => { match toml::from_str(&serial) {
|
Format::Toml => { match toml::from_str(serial) {
|
||||||
Ok(g) => g,
|
Ok(g) => g,
|
||||||
Err(error) => Graph::new(Some(error.to_string()))
|
Err(error) => Graph::new(Some(error.to_string()))
|
||||||
}},
|
}},
|
||||||
Format::Json => { match serde_json::from_str(&serial) {
|
Format::Json => { match serde_json::from_str(serial) {
|
||||||
Ok(g) => g,
|
Ok(g) => g,
|
||||||
Err(error) => Graph::new(Some(error.to_string()))
|
Err(error) => Graph::new(Some(error.to_string()))
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
55
src/main.rs
55
src/main.rs
|
|
@ -7,11 +7,12 @@ use axum::{
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod types;
|
use formats::{populate_graph, serialize_graph, Format};
|
||||||
mod formats;
|
use types::Node;
|
||||||
|
|
||||||
|
mod formats;
|
||||||
|
mod types;
|
||||||
|
|
||||||
use formats::*;
|
|
||||||
use types::*;
|
|
||||||
static ONSET: std::sync::LazyLock<std::time::Instant> =
|
static ONSET: std::sync::LazyLock<std::time::Instant> =
|
||||||
std::sync::LazyLock::new(std::time::Instant::now);
|
std::sync::LazyLock::new(std::time::Instant::now);
|
||||||
|
|
||||||
|
|
@ -59,18 +60,17 @@ async fn main() {
|
||||||
|
|
||||||
fn make_body(
|
fn make_body(
|
||||||
name: &str,
|
name: &str,
|
||||||
context: tera::Context,
|
context: &tera::Context,
|
||||||
error_code: u16,
|
error_message: Option<&str>,
|
||||||
error_message: &str,
|
) -> (String, u16) {
|
||||||
) -> String {
|
|
||||||
|
|
||||||
let tera = match tera::Tera::new(
|
let tera = match tera::Tera::new(
|
||||||
concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*"),
|
concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*"),
|
||||||
) {
|
) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("Tera parsing error: {}", e);
|
println!("Tera parsing error: {e:#?}");
|
||||||
::std::process::exit(1);
|
panic!("{e}")
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -139,7 +139,7 @@ async fn node_view(Path(id): Path<String>) -> impl IntoResponse {
|
||||||
let graph = populate_graph();
|
let graph = populate_graph();
|
||||||
let nodes = graph.nodes;
|
let nodes = graph.nodes;
|
||||||
let empty_node = Node::new(
|
let empty_node = Node::new(
|
||||||
Some(format!("Could not find node with ID {}.", id)),
|
Some(format!("Could not find node with ID {id}.")),
|
||||||
);
|
);
|
||||||
|
|
||||||
let node: &Node = nodes.get(&id).unwrap_or(&empty_node);
|
let node: &Node = nodes.get(&id).unwrap_or(&empty_node);
|
||||||
|
|
@ -205,14 +205,14 @@ async fn query(Form(query): Form<Query>) -> Redirect {
|
||||||
|
|
||||||
async fn json_graph() -> impl IntoResponse {
|
async fn json_graph() -> impl IntoResponse {
|
||||||
let graph = populate_graph();
|
let graph = populate_graph();
|
||||||
let body = serialize_graph(Format::Json, &graph);
|
let body = serialize_graph(&Format::Json, &graph);
|
||||||
|
|
||||||
([(header::CONTENT_TYPE, "application/json")], body)
|
([(header::CONTENT_TYPE, "application/json")], body)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn toml_graph() -> impl IntoResponse {
|
async fn toml_graph() -> impl IntoResponse {
|
||||||
let graph = populate_graph();
|
let graph = populate_graph();
|
||||||
let body = serialize_graph(Format::Toml, &graph);
|
let body = serialize_graph(&Format::Toml, &graph);
|
||||||
|
|
||||||
([(header::CONTENT_TYPE, "text/plain")], body)
|
([(header::CONTENT_TYPE, "text/plain")], body)
|
||||||
}
|
}
|
||||||
|
|
@ -242,19 +242,17 @@ fn make_error_body(
|
||||||
|
|
||||||
let mut context = tera::Context::new();
|
let mut context = tera::Context::new();
|
||||||
|
|
||||||
let code = code.unwrap_or(501);
|
let out_code = code.unwrap_or(500);
|
||||||
let message = &message.unwrap_or("Unknown error");
|
let out_message = &message.unwrap_or("Unknown error");
|
||||||
|
|
||||||
context.insert("title", &StatusCode::from_u16(code)
|
context.insert("title", &StatusCode::from_u16(out_code)
|
||||||
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR).to_string());
|
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR).to_string());
|
||||||
context.insert("message", message);
|
context.insert("message", out_message);
|
||||||
context.insert("status_code", &code.to_string());
|
context.insert("status_code", &out_code.to_string());
|
||||||
|
|
||||||
make_body("error.html", context, 500, &format!(
|
make_body("error.html", &context, Some(&format!(
|
||||||
"Failed to render template for Error {}: {}",
|
"Failed to render template for Error {out_code}: {out_message}"
|
||||||
code,
|
))).0
|
||||||
message,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_error_response(
|
fn make_error_response(
|
||||||
|
|
@ -262,15 +260,16 @@ fn make_error_response(
|
||||||
message: Option<&str>,
|
message: Option<&str>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
|
||||||
let code = code.unwrap_or(501);
|
let out_code = code.unwrap_or(500);
|
||||||
let message = &message.unwrap_or("Unknown error");
|
let out_message = &message.unwrap_or("Unknown error");
|
||||||
|
|
||||||
let body = make_error_body(Some(code), Some(message));
|
let body = make_error_body(Some(out_code), Some(out_message));
|
||||||
|
|
||||||
(
|
(
|
||||||
StatusCode::from_u16(code).unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
|
StatusCode::from_u16(out_code)
|
||||||
|
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR),
|
||||||
[(header::CONTENT_TYPE, "text/html")],
|
[(header::CONTENT_TYPE, "text/html")],
|
||||||
body.to_string(),
|
body.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Eq, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Eq, Debug)]
|
||||||
pub struct Graph {
|
pub struct Graph {
|
||||||
pub nodes: HashMap<String, Node>,
|
pub nodes: HashMap<String, Node>,
|
||||||
|
|
@ -40,10 +41,7 @@ impl Graph {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_root(&self) -> Option<Node> {
|
pub fn get_root(&self) -> Option<Node> {
|
||||||
match self.nodes.get(&self.root_node) {
|
self.nodes.get(&self.root_node).cloned()
|
||||||
Some(n) => Some(n.clone()),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue