From 78f114254c9ec6daf1810e3ecc0a44fbc7395957 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 2 Jul 2025 14:54:02 -0500 Subject: [PATCH] chore: cargo clippy fixes --- exp1/src/serve.rs | 75 +++++--- exp2/src/main.rs | 1 - offline-web-model/src/lib.rs | 125 ++++++-------- offline-web-model/src/test.rs | 315 ++++++++++++++++++---------------- 4 files changed, 269 insertions(+), 247 deletions(-) diff --git a/exp1/src/serve.rs b/exp1/src/serve.rs index 6483ddb..0a14b92 100644 --- a/exp1/src/serve.rs +++ b/exp1/src/serve.rs @@ -1,6 +1,12 @@ use std::{collections::HashMap, sync::Arc}; -use axum::{extract::Path, http, response::{Html, IntoResponse}, routing::get, Json, Router}; +use axum::{ + extract::Path, + http, + response::{Html, IntoResponse}, + routing::get, + Json, Router, +}; use offline_web_model::{Graph, Reference}; @@ -9,7 +15,10 @@ async fn all_references(root_ref: Arc) -> Json> { Json(root_ref) } -async fn ref_path(refs: Arc>>, Path(path): Path) -> Json> { +async fn ref_path( + refs: Arc>>, + Path(path): Path, +) -> Json> { let path = format!("/item/{}", path); match refs.get(&path) { Some(r) => Json(r.clone()), @@ -33,37 +42,51 @@ async fn get_client_js() -> impl IntoResponse { } pub fn endpoints(graph: Graph) -> Router { - Router::new().nest( - "/api/v1", - Router::new().nest( - "/ref", + Router::new() + .nest( + "/api/v1", Router::new() - .route("/all/username", get({ - let state = graph.root.clone(); - move || all_references(state) - })) - .route("/item/{*path}", get({ - let refs = graph.refs.clone(); - move |path| ref_path(refs, path) - })) - ).nest( - "/object", - Router::new() - .route("/{addr}", get({ - let objects = graph.objects.clone(); - move |addr| object_path(objects, addr) - })) - ), - ) - .route("/lib/client.js", get(get_client_js)) - .route("/ui/", get(|| async { Html(include_str!("../static/index.html")).into_response() })) + .nest( + "/ref", + Router::new() + .route( + "/all/username", + get({ + let state = graph.root.clone(); + move || all_references(state) + }), + ) + .route( + "/item/{*path}", + get({ + let refs = graph.refs.clone(); + move |path| ref_path(refs, path) + }), + ), + ) + .nest( + "/object", + Router::new().route( + "/{addr}", + get({ + let objects = graph.objects.clone(); + move |addr| object_path(objects, addr) + }), + ), + ), + ) + .route("/lib/client.js", get(get_client_js)) + .route( + "/ui/", + get(|| async { Html(include_str!("../static/index.html")).into_response() }), + ) } // TODO(jwall): Javascript test script pub async fn serve() { // run our app with hyper, listening globally on port 3000 let graph = Graph::random_graph(); - + let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") .await .unwrap(); diff --git a/exp2/src/main.rs b/exp2/src/main.rs index 4d9b0e8..9e8821c 100644 --- a/exp2/src/main.rs +++ b/exp2/src/main.rs @@ -1,4 +1,3 @@ - mod serve; #[tokio::main(flavor = "current_thread")] diff --git a/offline-web-model/src/lib.rs b/offline-web-model/src/lib.rs index 0178b2f..0393f6c 100644 --- a/offline-web-model/src/lib.rs +++ b/offline-web-model/src/lib.rs @@ -1,4 +1,4 @@ -use std::{cmp::Ordering, collections::HashMap, sync::Arc}; +use std::{collections::HashMap, sync::Arc}; use blake2::{Blake2b512, Digest}; use rand::Rng; @@ -37,7 +37,7 @@ impl Reference { // Calculate the reference_id from the content_address and path let hasher = Self::initial_hash(&content_address, &name); let calculated_id = format!("{:x}", hasher.finalize()); - + Self { id: calculated_id, content_address, @@ -61,12 +61,8 @@ impl Reference { let mut cloned = self.clone(); cloned.dependents.push(dep); // We ensure that our dependents are always sorted lexicographically by name. - cloned.dependents.sort_by(|left, right| if left.name == right.name { - Ordering::Equal - } else if left.name < right.name { - Ordering::Less - } else { - Ordering::Greater + cloned.dependents.sort_by(|left, right| { + left.name.cmp(&right.name) }); // Recalculate the ID based on dependents, content_address, and path let mut hasher = Self::initial_hash(&self.content_address, &self.name); @@ -77,7 +73,6 @@ impl Reference { cloned } - /// Converts this Reference into an Arc-wrapped Reference for shared ownership. /// /// This is useful when a Reference needs to be shared across multiple owners @@ -97,9 +92,9 @@ impl Reference { /// # Returns /// `true` if this Reference has no dependents, `false` otherwise pub fn is_leaf(&self) -> bool { - return self.dependents.is_empty(); + self.dependents.is_empty() } - + fn initial_hash(content_address: &Option, path: &String) -> Blake2b512 { let mut hasher = Blake2b512::new(); if let Some(content_address) = content_address { @@ -119,9 +114,7 @@ pub struct Graph { pub fn random_object() -> (String, Vec) { let mut rng = rand::rng(); let random_size = rng.random_range(50..=4096); - let random_bytes: Vec = (0..random_size) - .map(|_| rng.random::()) - .collect(); + let random_bytes: Vec = (0..random_size).map(|_| rng.random::()).collect(); let mut hasher = Blake2b512::new(); hasher.update(&random_bytes); @@ -147,7 +140,7 @@ impl Graph { pub fn get_reference(&self, path: &str) -> Option> { self.refs.get(path).cloned() } - + /// Gets an object by its content address pub fn get_object(&self, content_address: &str) -> Option<&Vec> { self.objects.get(content_address) @@ -158,97 +151,101 @@ impl Graph { /// /// The reference ID is calculated from the content address, name, and any dependents, /// ensuring that it's truly content-addressable. - pub fn update_object_reference(&mut self, name: &String, new_content: Vec) -> Result<(), String> { + pub fn update_object_reference( + &mut self, + name: &String, + new_content: Vec, + ) -> Result<(), String> { // Create a mutable copy of our maps let mut refs = HashMap::new(); for (k, v) in self.refs.as_ref() { refs.insert(k.clone(), v.clone()); } - + let mut objects = HashMap::new(); for (k, v) in self.objects.as_ref() { objects.insert(k.clone(), v.clone()); } - + // Find the reference to update - let ref_to_update = refs.get(name).ok_or_else(|| format!("Reference with name {} not found", name))?; - + let ref_to_update = refs + .get(name) + .ok_or_else(|| format!("Reference with name {} not found", name))?; + // Calculate hash for the new content let mut hasher = Blake2b512::new(); hasher.update(&new_content); let new_address = format!("{:x}", hasher.finalize()); - + // Create a new reference with the updated content address // The ID will be calculated based on the content address, name, and dependents - let mut updated_ref = Reference::new( - Some(new_address.clone()), - name.to_string() - ); - + let mut updated_ref = Reference::new(Some(new_address.clone()), name.to_string()); + // Add all dependents to the updated reference for dep in &ref_to_update.dependents { updated_ref = updated_ref.add_dep(dep.clone()); } - let updated_ref = updated_ref.to_arc(); - + // Update objects map with new content objects.insert(new_address.clone(), new_content); - + // Update references map with new reference refs.insert(name.to_string(), updated_ref.clone()); - + // Find and update all parent references that contain this reference self.update_parent_references(&mut refs, name); - + // Update the Arc maps self.refs = Arc::new(refs); self.objects = Arc::new(objects); - + Ok(()) } /// TODO(jwall): Add new reference - /// Recursively updates parent references when a child reference changes - fn update_parent_references(&mut self, refs: &mut HashMap>, updated_name: &str) { + fn update_parent_references( + &mut self, + refs: &mut HashMap>, + updated_name: &str, + ) { // Find all references that have the updated reference as a dependent let parent_names: Vec = refs .iter() .filter(|(_, r)| r.dependents.iter().any(|dep| dep.name == updated_name)) .map(|(name, _)| name.clone()) .collect(); - + for parent_name in parent_names { if let Some(parent_ref) = refs.get(&parent_name) { // Create a new reference with the same content address and name - let mut updated_parent = Reference::new( - parent_ref.content_address.clone(), - parent_ref.name.clone() - ); - + let mut updated_parent = + Reference::new(parent_ref.content_address.clone(), parent_ref.name.clone()); + // Add all dependents, replacing the updated one for dep in &parent_ref.dependents { // Update the root reference if needed if dep.name == updated_name { // Use the updated reference - updated_parent = updated_parent.add_dep(refs.get(updated_name).unwrap().clone()); + updated_parent = + updated_parent.add_dep(refs.get(updated_name).unwrap().clone()); } else { // Keep the existing dependent updated_parent = updated_parent.add_dep(dep.clone()); } } - + // The ID is automatically calculated in the add_dep method let updated_parent = Arc::new(updated_parent); if updated_parent.name == self.root.name { self.root = updated_parent.clone(); } - + // Update the references map refs.insert(parent_name.clone(), updated_parent); - + // Recursively update parents of this parent self.update_parent_references(refs, &parent_name); } @@ -259,56 +256,48 @@ impl Graph { let root_name = String::from("ref/0"); let mut objects = HashMap::new(); let mut refs = HashMap::new(); - + // Create the root reference - let mut root_ref = Reference::new( - Some(String::from("root_content")), - root_name.clone(), - ); - + let mut root_ref = Reference::new(Some(String::from("root_content")), root_name.clone()); + // Create 10 item references for i in 1..=10 { let item_name = format!("/item/{}", i); - let mut item_ref = Reference::new( - Some(format!("item_content_{}", i)), - item_name.clone(), - ); - + let mut item_ref = + Reference::new(Some(format!("item_content_{}", i)), item_name.clone()); + // Create 10 subitems for each item for j in 1..=10 { let (address, content) = random_object(); let subitem_name = format!("/item/{}/subitem/{}", i, j); - + // Create a leaf reference - let leaf_ref = Reference::new( - Some(address.clone()), - subitem_name, - ).to_arc(); - + let leaf_ref = Reference::new(Some(address.clone()), subitem_name).to_arc(); + // Add the leaf reference as a dependent to the item reference item_ref = item_ref.add_dep(leaf_ref.clone()); - + // Store the content in the objects map objects.insert(address.clone(), content); - + // Store the leaf reference in the refs map refs.insert(leaf_ref.name.clone(), leaf_ref); } - + // Convert the item reference to Arc and add it to the root reference let arc_item_ref = item_ref.to_arc(); root_ref = root_ref.add_dep(arc_item_ref.clone()); - + // Store the item reference in the refs map refs.insert(arc_item_ref.name.clone(), arc_item_ref); } - + // Convert the root reference to Arc let arc_root_ref = root_ref.to_arc(); - + // Store the root reference in the refs map refs.insert(arc_root_ref.name.clone(), arc_root_ref.clone()); - + Graph { root: arc_root_ref, refs: Arc::new(refs), diff --git a/offline-web-model/src/test.rs b/offline-web-model/src/test.rs index 3c7e501..37cd93d 100644 --- a/offline-web-model/src/test.rs +++ b/offline-web-model/src/test.rs @@ -2,19 +2,20 @@ use std::collections::HashMap; use std::collections::HashSet; use std::sync::Arc; - use crate::{Graph, Reference, random_object}; fn get_deterministic_candidate(graph: &Graph) -> Arc { // Pick a deterministic leaf node to update (first lexicographically) - let mut refs: Vec> = graph.refs.values() + let mut refs: Vec> = graph + .refs + .values() .filter(|r| r.name != graph.root.name && r.is_leaf()) .map(|r| r.clone()) .collect(); - + // Sort by name to ensure deterministic ordering refs.sort_by(|a, b| a.name.cmp(&b.name)); - + refs[0].clone() } @@ -23,25 +24,30 @@ fn get_deterministic_candidate(graph: &Graph) -> Arc { fn test_dependencies_updated_when_nodes_added() { // Create a simple graph let mut graph = create_test_graph(); - + // Get the initial content address of the root let initial_root_id = graph.root.id.clone(); - + let candidate = get_deterministic_candidate(&graph); - + // Update the leaf node with deterministic content let new_content = b"deterministic_test_content".to_vec(); - graph.update_object_reference(&candidate.name, new_content).unwrap(); - + graph + .update_object_reference(&candidate.name, new_content) + .unwrap(); + // Verify that the leaf node's ID has changed let updated_leaf = graph.get_reference(&candidate.name).unwrap(); - assert_ne!(updated_leaf.id, candidate.id, - "Leaf node ID should change when content is updated"); - + assert_ne!( + updated_leaf.id, candidate.id, + "Leaf node ID should change when content is updated" + ); + // Verify that the root's ID has changed - assert_ne!(graph.root.id, initial_root_id, - "Root ID should change when a dependent node is updated"); - + assert_ne!( + graph.root.id, initial_root_id, + "Root ID should change when a dependent node is updated" + ); } /// Tests that the root of the graph is not itself a dependency of any other node @@ -49,12 +55,14 @@ fn test_dependencies_updated_when_nodes_added() { fn test_root_not_a_dependency() { let graph = create_test_graph(); let root_name = graph.root.name.clone(); - + // Check all references to ensure none have the root as a dependent for (_, reference) in graph.refs.as_ref() { for dep in &reference.dependents { - assert_ne!(dep.name, root_name, - "Root should not be a dependency of any other node"); + assert_ne!( + dep.name, root_name, + "Root should not be a dependency of any other node" + ); } } } @@ -63,26 +71,29 @@ fn test_root_not_a_dependency() { #[test] fn test_all_nodes_connected_to_root() { let graph = create_test_graph(); - + // Collect all nodes reachable from the root let mut reachable = HashSet::new(); - + fn collect_reachable(node: &Arc, reachable: &mut HashSet) { reachable.insert(node.name.clone()); - + for dep in &node.dependents { if !reachable.contains(&dep.name) { collect_reachable(dep, reachable); } } } - + collect_reachable(&graph.root, &mut reachable); - + // Check that all nodes in the graph are reachable from the root for (name, _) in graph.refs.as_ref() { - assert!(reachable.contains(name), - "All nodes should be reachable from the root: {}", name); + assert!( + reachable.contains(name), + "All nodes should be reachable from the root: {}", + name + ); } } @@ -91,56 +102,47 @@ fn create_test_graph() -> Graph { let root_name = String::from("/root"); let mut objects = HashMap::new(); let mut refs = HashMap::new(); - + // Create the root reference - let mut root_ref = Reference::new( - Some(String::from("root_content")), - root_name.clone(), - ); - + let mut root_ref = Reference::new(Some(String::from("root_content")), root_name.clone()); + // Create 3 item references for i in 1..=3 { let item_name = format!("/item/{}", i); - let mut item_ref = Reference::new( - Some(format!("item_content_{}", i)), - item_name.clone(), - ); - + let mut item_ref = Reference::new(Some(format!("item_content_{}", i)), item_name.clone()); + // Create 3 subitems for each item for j in 1..=3 { let (address, content) = random_object(); let subitem_name = format!("/item/{}/subitem/{}", i, j); - + // Create a leaf reference - let leaf_ref = Reference::new( - Some(address.clone()), - subitem_name, - ).to_arc(); - + let leaf_ref = Reference::new(Some(address.clone()), subitem_name).to_arc(); + // Add the leaf reference as a dependent to the item reference item_ref = item_ref.add_dep(leaf_ref.clone()); - + // Store the content in the objects map objects.insert(address.clone(), content); - + // Store the leaf reference in the refs map refs.insert(leaf_ref.name.clone(), leaf_ref); } - + // Convert the item reference to Arc and add it to the root reference let arc_item_ref = item_ref.to_arc(); root_ref = root_ref.add_dep(arc_item_ref.clone()); - + // Store the item reference in the refs map refs.insert(arc_item_ref.name.clone(), arc_item_ref); } - + // Convert the root reference to Arc let arc_root_ref = root_ref.to_arc(); - + // Store the root reference in the refs map refs.insert(arc_root_ref.name.clone(), arc_root_ref.clone()); - + Graph { root: arc_root_ref, refs: Arc::new(refs), @@ -152,91 +154,106 @@ fn create_test_graph() -> Graph { #[test] fn test_content_addressable_properties() { let mut graph = create_test_graph(); - + // Update a leaf node with the same content let leaf_path = "/item/1/subitem/1".to_string(); let initial_leaf = graph.get_reference(&leaf_path).unwrap(); if let Some(content_address) = initial_leaf.content_address.clone() { // Get the content for this address let content = graph.get_object(&content_address).unwrap().clone(); - + // Update with the same content graph.update_object_reference(&leaf_path, content).unwrap(); } - + // Verify that nothing changed since the content is the same let updated_leaf = graph.get_reference(&leaf_path).unwrap(); - assert_eq!(updated_leaf.content_address, initial_leaf.content_address, - "Content address should not change when content remains the same"); + assert_eq!( + updated_leaf.content_address, initial_leaf.content_address, + "Content address should not change when content remains the same" + ); } /// Tests that the graph correctly handles ID calculation #[test] fn test_id_calculation() { let mut graph = create_test_graph(); - + // Update a leaf node let leaf_path = "/item/1/subitem/1".to_string(); let initial_leaf = graph.get_reference(&leaf_path).unwrap(); - - graph.update_object_reference(&leaf_path, "new content".as_bytes().to_vec()).unwrap(); - + + graph + .update_object_reference(&leaf_path, "new content".as_bytes().to_vec()) + .unwrap(); + // Verify that the ID changed let updated_leaf = graph.get_reference(&leaf_path).unwrap(); - assert_ne!(updated_leaf.id, initial_leaf.id, - "Reference ID should change when content changes"); - + assert_ne!( + updated_leaf.id, initial_leaf.id, + "Reference ID should change when content changes" + ); + // Verify that parent ID changed let parent_path = "/item/1".to_string(); let parent = graph.get_reference(&parent_path).unwrap(); - + // Create a reference with the same properties to calculate expected ID - let mut test_ref = Reference::new( - parent.content_address.clone(), - parent.name.clone(), - ); - + let mut test_ref = Reference::new(parent.content_address.clone(), parent.name.clone()); + // Add the same dependents for dep in &parent.dependents { test_ref = test_ref.add_dep(dep.clone()); } - + // Verify the ID calculation is consistent - assert_eq!(parent.id, test_ref.id, - "ID calculation should be consistent for the same reference properties"); + assert_eq!( + parent.id, test_ref.id, + "ID calculation should be consistent for the same reference properties" + ); } /// Tests that the root ID always changes when any reference is updated #[test] fn test_root_id_changes_for_any_reference_update() { let mut graph = create_test_graph(); - + // Get all non-root references sorted by name for deterministic iteration - let mut all_refs: Vec<(String, String)> = graph.refs.as_ref() + let mut all_refs: Vec<(String, String)> = graph + .refs + .as_ref() .iter() .filter(|(name, _)| **name != graph.root.name) .map(|(name, ref_arc)| (name.clone(), ref_arc.id.clone())) .collect(); - + all_refs.sort_by(|a, b| a.0.cmp(&b.0)); - + // Test each reference update for (ref_name, original_ref_id) in all_refs { // Record the current root ID let initial_root_id = graph.root.id.clone(); - + // Update the reference with new content let new_content = format!("updated_content_for_{}", ref_name).into_bytes(); - graph.update_object_reference(&ref_name, new_content).unwrap(); - + graph + .update_object_reference(&ref_name, new_content) + .unwrap(); + // Verify the reference itself changed let updated_ref = graph.get_reference(&ref_name).unwrap(); - assert_ne!(updated_ref.id, original_ref_id, - "Reference {} should have changed ID after update", ref_name); - + assert_ne!( + updated_ref.id, original_ref_id, + "Reference {} should have changed ID after update", + ref_name + ); + // Verify the root ID changed - assert_ne!(graph.root.id, initial_root_id, - "Root ID should change when reference {} is updated", ref_name); + assert_ne!( + graph.root.id, initial_root_id, + "Root ID should change when reference {} is updated", + ref_name + ); } } @@ -244,69 +261,61 @@ fn test_root_id_changes_for_any_reference_update() { #[test] fn test_reference_ids_stable_regardless_of_dependency_order() { // Create test dependencies - let dep_a = Reference::new( - Some(String::from("content_a")), - String::from("/dep_a"), - ).to_arc(); - - let dep_b = Reference::new( - Some(String::from("content_b")), - String::from("/dep_b"), - ).to_arc(); - - let dep_c = Reference::new( - Some(String::from("content_c")), - String::from("/dep_c"), - ).to_arc(); - - let dep_d = Reference::new( - Some(String::from("content_d")), - String::from("/dep_d"), - ).to_arc(); - + let dep_a = Reference::new(Some(String::from("content_a")), String::from("/dep_a")).to_arc(); + + let dep_b = Reference::new(Some(String::from("content_b")), String::from("/dep_b")).to_arc(); + + let dep_c = Reference::new(Some(String::from("content_c")), String::from("/dep_c")).to_arc(); + + let dep_d = Reference::new(Some(String::from("content_d")), String::from("/dep_d")).to_arc(); + // Create base reference - let base_ref = Reference::new( - Some(String::from("base_content")), - String::from("/base"), - ); - + let base_ref = Reference::new(Some(String::from("base_content")), String::from("/base")); + // Test multiple different orders of adding the same dependencies let orders = vec![ - vec![dep_a.clone(), dep_b.clone(), dep_c.clone(), dep_d.clone()], // alphabetical - vec![dep_d.clone(), dep_c.clone(), dep_b.clone(), dep_a.clone()], // reverse alphabetical - vec![dep_b.clone(), dep_d.clone(), dep_a.clone(), dep_c.clone()], // random order 1 - vec![dep_c.clone(), dep_a.clone(), dep_d.clone(), dep_b.clone()], // random order 2 - vec![dep_d.clone(), dep_a.clone(), dep_b.clone(), dep_c.clone()], // random order 3 + vec![dep_a.clone(), dep_b.clone(), dep_c.clone(), dep_d.clone()], // alphabetical + vec![dep_d.clone(), dep_c.clone(), dep_b.clone(), dep_a.clone()], // reverse alphabetical + vec![dep_b.clone(), dep_d.clone(), dep_a.clone(), dep_c.clone()], // random order 1 + vec![dep_c.clone(), dep_a.clone(), dep_d.clone(), dep_b.clone()], // random order 2 + vec![dep_d.clone(), dep_a.clone(), dep_b.clone(), dep_c.clone()], // random order 3 ]; - + let mut all_ids = Vec::new(); - + for (i, order) in orders.iter().enumerate() { let mut test_ref = base_ref.clone(); - + // Add dependencies in this specific order for dep in order { test_ref = test_ref.add_dep(dep.clone()); } - + all_ids.push(test_ref.id.clone()); - + // Verify that dependencies are always sorted lexicographically regardless of add order for j in 0..test_ref.dependents.len() - 1 { let current = &test_ref.dependents[j]; let next = &test_ref.dependents[j + 1]; - - assert!(current.name < next.name, - "Dependencies should be lexicographically ordered. Order {}: Found '{}' before '{}'", - i, current.name, next.name); + + assert!( + current.name < next.name, + "Dependencies should be lexicographically ordered. Order {}: Found '{}' before '{}'", + i, + current.name, + next.name + ); } } - + // Verify all IDs are identical let first_id = &all_ids[0]; for (i, id) in all_ids.iter().enumerate() { - assert_eq!(id, first_id, - "Reference ID should be stable regardless of dependency add order. Order {} produced different ID", i); + assert_eq!( + id, first_id, + "Reference ID should be stable regardless of dependency add order. Order {} produced different ID", + i + ); } } @@ -314,7 +323,7 @@ fn test_reference_ids_stable_regardless_of_dependency_order() { #[test] fn test_dependencies_lexicographically_ordered() { let graph = create_test_graph(); - + // Check all references to ensure their dependents are lexicographically ordered for (_, reference) in graph.refs.as_ref() { if reference.dependents.len() > 1 { @@ -322,44 +331,46 @@ fn test_dependencies_lexicographically_ordered() { for i in 0..reference.dependents.len() - 1 { let current = &reference.dependents[i]; let next = &reference.dependents[i + 1]; - - assert!(current.name < next.name, - "Dependencies should be lexicographically ordered by name. Found '{}' before '{}'", - current.name, next.name); + + assert!( + current.name < next.name, + "Dependencies should be lexicographically ordered by name. Found '{}' before '{}'", + current.name, + next.name + ); } } } - + // Also verify that when we add dependencies, they maintain the correct order let mut test_ref = Reference::new( Some(String::from("test_content")), String::from("/test_ordering"), ); - + // Add dependencies in non-lexicographical order - let dep_c = Reference::new( - Some(String::from("c_content")), - String::from("/c"), - ).to_arc(); - - let dep_a = Reference::new( - Some(String::from("a_content")), - String::from("/a"), - ).to_arc(); - - let dep_b = Reference::new( - Some(String::from("b_content")), - String::from("/b"), - ).to_arc(); - + let dep_c = Reference::new(Some(String::from("c_content")), String::from("/c")).to_arc(); + + let dep_a = Reference::new(Some(String::from("a_content")), String::from("/a")).to_arc(); + + let dep_b = Reference::new(Some(String::from("b_content")), String::from("/b")).to_arc(); + // Add in non-lexicographical order test_ref = test_ref.add_dep(dep_c.clone()); test_ref = test_ref.add_dep(dep_a.clone()); test_ref = test_ref.add_dep(dep_b.clone()); - - // Verify they are stored in lexicographical order - assert_eq!(test_ref.dependents[0].name, "/a", "First dependent should be '/a'"); - assert_eq!(test_ref.dependents[1].name, "/b", "Second dependent should be '/b'"); - assert_eq!(test_ref.dependents[2].name, "/c", "Third dependent should be '/c'"); -} + // Verify they are stored in lexicographical order + assert_eq!( + test_ref.dependents[0].name, "/a", + "First dependent should be '/a'" + ); + assert_eq!( + test_ref.dependents[1].name, "/b", + "Second dependent should be '/b'" + ); + assert_eq!( + test_ref.dependents[2].name, "/c", + "Third dependent should be '/c'" + ); +}