From 21a710658d308e337188c0ce53e3237c74d09166 Mon Sep 17 00:00:00 2001 From: jutty Date: Wed, 21 Jan 2026 16:52:54 -0300 Subject: [PATCH] Analyze necessity and effects of checked arithmetic --- src/graph.rs | 12 ++++++++++ src/syntax/content/parser/context/list.rs | 3 +++ src/syntax/content/parser/token/list.rs | 29 +++++++++++++++++++++-- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/graph.rs b/src/graph.rs index e94c936..914914e 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -207,6 +207,10 @@ impl Graph { } } + // Modulates nodes that have been deserialized and are still unprocessed. + // + // Performs checked arithmetic to the following effect: + // - Stats will saturate at u32::MAX (increment_detached calls) fn modulate_nodes(&mut self) { let in_nodes = self.nodes.clone(); @@ -306,6 +310,10 @@ impl Graph { } } + // Modulates edges that have been deserialized and are still unprocessed. + // + // This function performs checked arithmetic to the following effect: + // - Stats will saturate at u32::MAX fn modulate_edges(&mut self) { let graph = self.clone(); let iterator = self.nodes.iter_mut(); @@ -364,6 +372,10 @@ impl Graph { } } + // Increments detached node statistics for the given node ID + // + // This function performs checked arithmetic to the following effect: + // - Stats will saturate at u32::MAX fn increment_detached(&mut self, node_id: &str) { self.stats .detached diff --git a/src/syntax/content/parser/context/list.rs b/src/syntax/content/parser/context/list.rs index 415c0ea..45b5099 100644 --- a/src/syntax/content/parser/context/list.rs +++ b/src/syntax/content/parser/context/list.rs @@ -13,6 +13,9 @@ use crate::{ /// A return of `true` will trigger a continue in the outer parser, /// skipping any further parsing of the current lexeme. /// +/// Performs checked arithmetic to the following effect: +/// - The indent of list items will saturate at `u8::MAX` (255) spaces. +/// /// # Panics /// This parser can handle only the List context, and will panic if passed an /// unrelated context since it has no knowledge on how to handle them. diff --git a/src/syntax/content/parser/token/list.rs b/src/syntax/content/parser/token/list.rs index ca73804..82deb46 100644 --- a/src/syntax/content/parser/token/list.rs +++ b/src/syntax/content/parser/token/list.rs @@ -1,4 +1,5 @@ use crate::{ + prelude::*, syntax::content::{ Parseable, parser::{Lexeme, token::Item}, @@ -20,6 +21,14 @@ impl Parseable for List { panic!("Attempt to lex a List directly from a lexeme") } + /// Renders the list to the equivalent HTML representation. + /// + /// Performs checked arithmetic to the following effects: + /// - Strict division is performed but related panics are unreachable given + /// the guarantees described in `List::scale_indent` + /// - Saturates subtractions from indent levels at zero. This is not + /// unreachable, but a difference of zero is a no-op considering it + /// would cause an iteration of zero times (over an empty range). fn render(&self) -> String { let tag = if self.ordered { "ol" } else { "ul" }; let mut output = String::new(); @@ -68,6 +77,18 @@ impl List { } } + /// Calculates the scale to normalize indents. + /// + /// For example, if two contiguous items have differing indents of 2 and 4, + /// the indent scale is 2 and they can be normalized as having indents of + /// 1 and 2 respectively. + /// + /// Performs checked arithmetic to the following effects: + /// - The subtraction of outer from inner saturates at 0 due to u8 being + /// unsigned, but such a case is unreachable given the outer condition + /// that guards this subtraction + /// - Will not return zero even if it is the calculated width, instead + /// logging the event and returning 1 instead fn scale_indent(&self) -> u8 { let width = self .items @@ -79,8 +100,12 @@ impl List { }) .unwrap_or(1); - assert!(width != 0, "Width of zero can't be a divisor"); - width + if width == 0 { + log!("Scale indent of 0 can't be a divisor: returning 1 instead"); + 1 + } else { + width + } } }