Analyze necessity and effects of checked arithmetic
This commit is contained in:
parent
5156161650
commit
21a710658d
3 changed files with 42 additions and 2 deletions
12
src/graph.rs
12
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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue