Skip to main content

TreeDiff

Struct TreeDiff 

Source
pub struct TreeDiff {
    pub root_path: String,
    pub changes: Vec<FieldChangeEvent>,
    pub from_element: ElementData,
    pub to_element: ElementData,
    pub added: Vec<ElementData>,
    pub removed: Vec<ElementData>,
    pub child_diffs: Vec<TreeDiff>,
}
Expand description

A hierarchical diff between two versions of a USLM document tree

This struct captures all changes between two versions of the same legislative element and its children. It mirrors the tree structure of USLMElement, with diffs computed recursively for all matching children.

§Structure

The diff includes:

  • Field changes: Text modifications to the element’s own content fields
  • Added elements: New child elements in the new version
  • Removed elements: Child elements that existed in the old version but not the new
  • Child diffs: Recursive diffs for child elements that exist in both versions

§Examples

use words_to_data::{diff::TreeDiff, uslm::parser::parse};

// Parse two versions of a document
let old_doc = parse("tests/test_data/usc/2025-07-18/usc07.xml", "2025-07-18").unwrap();
let new_doc = parse("tests/test_data/usc/2025-07-30/usc07.xml", "2025-07-30").unwrap();

// Compute the diff
let diff = TreeDiff::from_elements(&old_doc, &new_doc);

// Examine changes
println!("Field changes: {}", diff.changes.len());
println!("Elements added: {}", diff.added.len());
println!("Elements removed: {}", diff.removed.len());

Fields§

§root_path: String

The structural path of the element being compared

§changes: Vec<FieldChangeEvent>

Text content field changes for this element

§from_element: ElementData

Metadata from the original version of this element

§to_element: ElementData

Metadata from the new version of this element

§added: Vec<ElementData>

Child elements that were added in the new version

§removed: Vec<ElementData>

Child elements that were removed from the old version

§child_diffs: Vec<TreeDiff>

Recursive diffs for child elements present in both versions

Implementations§

Source§

impl TreeDiff

Source

pub fn mention_regex(&self) -> Option<Regex>

Generate a regex for searching for mentions of an element

Amendments and other legal texts tend to exclude chapters and titles when discussing legal references instead, they have a tendency to directly state references, and pieces of them. e.g.

“According to Section 174 (a)(2)(A)”

This function will generate compatible regexes for relevant strucutural elements to match those.

Source

pub fn section_regex(&self) -> Option<Regex>

Source

pub fn all_regexes(&self) -> Vec<Regex>

Generates a list of all candidate regexes for a TreeDiff

Source

pub fn from_elements( from_element: &USLMElement, to_element: &USLMElement, ) -> TreeDiff

Compute the diff between two USLM element trees

Compares two versions of the same legislative element and computes all changes at both the current level and recursively through all children.

§Arguments
  • from_element - The original (older) version of the element
  • to_element - The new (newer) version of the element
§Panics

Panics if the two elements don’t have the same structural path, as they must represent the same logical element in different versions.

§Returns

A TreeDiff containing all detected changes between the two versions.

§Examples
let old = parse("tests/test_data/usc/2025-07-18/usc07.xml", "2025-07-18").unwrap();
let new = parse("tests/test_data/usc/2025-07-30/usc07.xml", "2025-07-30").unwrap();

let diff = TreeDiff::from_elements(&old, &new);
assert_eq!(diff.root_path, old.data.path);
Source

pub fn find(&self, path: &str) -> Option<&TreeDiff>

Search for a diff by its structural path

Recursively searches this element and all descendants for an element with the specified path. The path must be a fully qualified structural path (e.g., “uscode/title_7/chapter_1/section_1”).

§Arguments
  • path - The full structural path of the element to find
§Returns

Returns Some(&TreeDiff) if an element with the matching path is found, or None if no such element exists in this tree.

Source

pub fn calculate_amendment_similarities( &self, data: &Bill, ) -> HashMap<String, AmendmentSimilarity>

Calculate the similarity of diffs in the TreeDiff with the amendment data from a bill

Returns a hashmap with the key being the root_path in the tree diff and the value being the similarity data

Source

pub fn scan_for_mentions( &self, data: &Bill, ) -> HashMap<String, Vec<MentionMatch>>

Scan all amendment texts for mentions of changed sections.

Uses the regexes from all_regexes() to find section mentions in each amendment’s amending_text. This helps identify which amendments might be responsible for changes at specific structural paths.

§Arguments
  • data - Bill data from a parsed bill
§Returns

A map from amendment_id to list of matches found in that amendment’s text. For each tree_diff_path, only the most specific (longest) match is kept.

Source

pub fn shallow(&self) -> TreeDiff

Return a shallow copy of this TreeDiff without children.

Useful when correlating a specific diff node with other data without needing the full subtree.

Trait Implementations§

Source§

impl Clone for TreeDiff

Source§

fn clone(&self) -> TreeDiff

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TreeDiff

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for TreeDiff

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Hash for TreeDiff

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for TreeDiff

Source§

fn eq(&self, other: &TreeDiff) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for TreeDiff

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Eq for TreeDiff

Source§

impl StructuralPartialEq for TreeDiff

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,