pub struct Digested(/* private fields */);Expand description
An Rc-guarded abstraction for any object encountered at the “digested” phase of processing
Implementations§
Source§impl Digested
impl Digested
Sourcepub fn data(&self) -> &DigestedData
pub fn data(&self) -> &DigestedData
immutably borrow the inner Digested data
Sourcepub fn cycle_fingerprint(&self) -> u64
pub fn cycle_fingerprint(&self) -> u64
A content-aware but COST-BOUNDED fingerprint for the stomach cycle guard
(crate::cycle_guard).
Design tension: it must (a) distinguish boxes by content so two
different boxes that merely share a shape (e.g. two Lists of equal
length but different children) don’t collide into a false cycle, yet
(b) be cheap on the digestion path. We reconcile both with a hard
node budget: at most FP_BUDGET sub-boxes are ever visited (a
depth-first sample of the content), so cost is O(1) per box regardless
of how large or deeply nested the structure is, while the sample is rich
enough that real content differences change the hash. (It is also only
ever invoked once box_list has already blown past the stomach guard’s
activation size, so ordinary conversions never pay for it at all.)
NOT a stable cross-process hash — for in-run loop detection only.
Sourcepub fn estimate_bytes(&self) -> usize
pub fn estimate_bytes(&self) -> usize
A COST-BOUNDED estimate of the heap bytes this digested box (and its
nested content) occupies. Used by the stomach’s portable
memory-budget guard (crate::stomach) to detect a runaway by the
resource that actually matters — bytes — rather than box COUNT, since
per-box weight varies several-fold (a bare text box vs a deeply nested
\hbox{\raise…\hbox{…}}). Traversal is capped at EB_BUDGET sub-boxes
(depth-first) so the estimate stays O(1) per box; deeply nested boxes
beyond the budget are under-counted, which is safe (the guard only needs
a monotone lower bound to catch unbounded growth).
Sourcepub fn value_of(&self) -> i64
pub fn value_of(&self) -> i64
Obtain the i64 value of the digested object, iff it wraps a RegisterValue
Sourcepub fn get_dimension(&self) -> Option<Dimension>
pub fn get_dimension(&self) -> Option<Dimension>
Obtain a Dimension from the digested object, iff it wraps a RegisterValue
Sourcepub fn pt_value(&self, prec: Option<u8>) -> f64
pub fn pt_value(&self, prec: Option<u8>) -> f64
Obtain the f64 value of the digested object, iff it wraps a RegisterValue
Sourcepub fn any<F>(&self, check: F) -> bool
pub fn any<F>(&self, check: F) -> bool
Predicate check - true if any element of the current object passes the check
Sourcepub fn all<F>(&self, check: F) -> bool
pub fn all<F>(&self, check: F) -> bool
Predicate check - true if all elements of the current object passes the check
Sourcepub fn is_empty(&self) -> Result<bool>
pub fn is_empty(&self) -> Result<bool>
Predicate check - delegates to .is_empty() of the underlying data
Sourcepub fn is_skippable(&self) -> bool
pub fn is_skippable(&self) -> bool
Check if all items are “empty” or only spaces or otherwise skippable in a table cell. Perl: isSkippable (Alignment.pm L484-508)
Sourcepub fn raw_tokens(&self) -> Option<&Tokens>
pub fn raw_tokens(&self) -> Option<&Tokens>
Provide a way of emulating an Undigested argument, by requesting
raw tokens, only when they are preserved – empty otherwise.
Sourcepub fn to_attribute(&self) -> String
pub fn to_attribute(&self) -> String
builds an attribute-friendly String form of the digested object, suitable for XML attributes
Sourcepub fn untex(&self) -> Result<String>
pub fn untex(&self) -> Result<String>
Reverts a digested object to Tokens and extracts a TeX-near string representation of its
content
pub fn alignment_cell(&self) -> Option<&RefCell<Alignment>>
Trait Implementations§
Source§impl BoxOps for Digested
impl BoxOps for Digested
Source§fn get_font(&self) -> Result<Option<Rc<Font>>>
fn get_font(&self) -> Result<Option<Rc<Font>>>
The box’s font as a SHARED handle.
This used to return Cow<'_, Font>, which was a false promise on exactly
the path that matters: the payloads live behind a RefCell, so a
Cow::Borrowed cannot outlive the borrow guard and every arm was forced
through Cow::Owned(v.into_owned()) — a deep Font clone on every call,
even though Tbox/List/Whatsit all already hold an Rc<Font>.
That clone was the single largest allocation in a conversion. Measured
2026-07-29 with --features dhat-heap on 100k words of plain prose:
Rc<Font>::new accounted for 392 MB of the 840 MB peak (47 %) across
1,196,000 blocks of 344 B — one per box absorbed — reached via
List::new ← append_node_box ← open_text ← absorb. The digested
boxes themselves came to 164 MB, so the font attached to each box cost
2.4x the box. No caller ever used Cow’s one advantage (to_mut).
Source§fn compute_size(
&self,
options: HashMap<Stored>,
) -> Result<(Dimension, Dimension, Dimension)>
fn compute_size( &self, options: HashMap<Stored>, ) -> Result<(Dimension, Dimension, Dimension)>
Note the difference between calling compute_size on a Digested object, and calling it on a
concrete box type. When called on Digested it will opt for caching the computed sizes,
but when called on the concrete types it will always compute sizes fresh.
Source§fn unlist(&self) -> Vec<Digested>
fn unlist(&self) -> Vec<Digested>
fn unlist_ref(&self) -> Vec<Cow<'_, Digested>>
Source§fn be_absorbed(&self, document: &mut Document) -> Result<Vec<Node>>
fn be_absorbed(&self, document: &mut Document) -> Result<Vec<Node>>
Document XML - returning the corresponding nodesSource§fn with_properties<R, FnR>(&self, caller: FnR) -> R
fn with_properties<R, FnR>(&self, caller: FnR) -> R
Source§fn set_property<T: Into<Stored>>(&mut self, key: &str, value: T)
fn set_property<T: Into<Stored>>(&mut self, key: &str, value: T)
Stored types for values)Source§fn get_property(&self, key: &str) -> Option<Cow<'_, Stored>>
fn get_property(&self, key: &str) -> Option<Cow<'_, Stored>>
Source§fn get_string(&self) -> Result<Cow<'_, str>>
fn get_string(&self) -> Result<Cow<'_, str>>
Source§fn has_property(&self, key: &str) -> bool
fn has_property(&self, key: &str) -> bool
Source§fn get_body(&self) -> Result<Option<Digested>>
fn get_body(&self) -> Result<Option<Digested>>
Source§fn get_property_bool(&self, key: &str) -> bool
fn get_property_bool(&self, key: &str) -> bool
Stored::Bool)Source§fn be_absorbed_mut(&mut self, _document: &mut Document) -> Result<Vec<Node>>
fn be_absorbed_mut(&mut self, _document: &mut Document) -> Result<Vec<Node>>
Alignment only)Source§fn get_tokens(&self) -> Option<&Tokens>
fn get_tokens(&self) -> Option<&Tokens>
Source§fn get_properties(&self) -> &HashMap<Stored>
fn get_properties(&self) -> &HashMap<Stored>
with_properties instead.Source§fn get_properties_mut(&mut self) -> &mut HashMap<Stored>
fn get_properties_mut(&mut self) -> &mut HashMap<Stored>
fn get_property_string(&self, key: &str) -> String
Source§fn get_property_mut(&mut self, key: &str) -> Option<&mut Stored>
fn get_property_mut(&mut self, key: &str) -> Option<&mut Stored>
Source§fn get_width(
&self,
options: Option<HashMap<Stored>>,
) -> Result<Option<RegisterValue>>
fn get_width( &self, options: Option<HashMap<Stored>>, ) -> Result<Option<RegisterValue>>
Source§fn set_height<T: Into<Stored>>(&mut self, width: T)
fn set_height<T: Into<Stored>>(&mut self, width: T)
Source§fn get_height(&self) -> Option<RegisterValue>
fn get_height(&self) -> Option<RegisterValue>
Source§fn get_depth(&self) -> Option<RegisterValue>
fn get_depth(&self) -> Option<RegisterValue>
Source§fn get_size(
&mut self,
options: Option<HashMap<Stored>>,
) -> Result<(Dimension, Dimension, Dimension, Dimension, Dimension, Dimension)>
fn get_size( &mut self, options: Option<HashMap<Stored>>, ) -> Result<(Dimension, Dimension, Dimension, Dimension, Dimension, Dimension)>
Digested::get_size for a variant with interior mutability which caches the box sizeSource§fn compute_size_and_cache(
&mut self,
options: HashMap<Stored>,
) -> Result<(Dimension, Dimension, Dimension)>
fn compute_size_and_cache( &mut self, options: HashMap<Stored>, ) -> Result<(Dimension, Dimension, Dimension)>
pad{top,bottom,left,right} to the computed dimensions. This is the SAFE
part of computeSizeStore — additive and inert until the app layer sets a
pad* property (display math \abovedisplayskip/\belowdisplayskip,
\overline/\underline 2pt, items/equations). The riskier requested-vs-
computed merge + full-spec bypass + isEmpty are deliberately NOT included
here — a mechanical port of those regressed (Rust boxes don’t use
width/height/depth uniformly as “requested box size”); see SYNC_STATUS U2.Source§impl From<RegisterValue> for Digested
impl From<RegisterValue> for Digested
Source§fn from(value: RegisterValue) -> Digested
fn from(value: RegisterValue) -> Digested
Source§impl Object for Digested
impl Object for Digested
Source§fn revert(&self) -> Result<Tokens>
fn revert(&self) -> Result<Tokens>
The source tokens this digested value came from — digestion run backwards, delegated to whichever variant is held.
What \meaning-style introspection and the tex attribute are built on:
a construct that has already become boxes, a whatsit or an alignment can
still show the LaTeX that produced it. A Postponed variant is already
tokens and reverts to itself.
fn stringify(&self) -> String
Source§fn get_locator(&self) -> Option<Locator>
fn get_locator(&self) -> Option<Locator>
None is the honest
“no recorded source position” (replacing the old Locator::default()
file!()/line!() sentinel). For “where the parser is now” (error
reporting, box creation), use the free fn gullet::get_locator().