1 unstable release
0.1.0 | Jul 25, 2024 |
---|
#872 in Data structures
27KB
579 lines
amalgamator
Description
amalgamator
is a set/map like data structure that allows you to combine members of the set/map together based on some criteria.
This is useful when you want to merge objects together that aren't strictly equal, but are similar enough that you want to treat them as the same object.
Installation
cargo add amalgamator
Serde Support
If you want to use serde
support, you can enable the serde
feature.
cargo add amalgamator --features serde
Documentation
View the docs on the docs.rs Documentation page.
License
This project is licensed under the MIT license or the Apache 2.0 license, at your option.
lib.rs
:
amalgamator
is a set/map like data structure that allows you to combine members of the set/map together
based on some criteria. This is useful when you want to merge objects together that aren't strictly equal,
but are similar enough that you want to treat them as the same object.
This can be useful in a variety of situations, such as:
- Merging data from multiple sources
- Entity deduplication
- Data normalization
Amalgamator is implemented as a set/map like data structure, generic over the type of the elements it contains.
Amalgamator uses a user-defined function to determine if two elements should be combined and a user-defined function
to merge two elements together. This is the Amalgamate
trait.
Lets first take a look at how we might implement Amalgamate
trait:
use amalgamator::Amalgamate;
use std::collections::HashSet;
struct Person {
name: String,
friends: HashSet<String>,
}
impl Amalgamate for Person {
type Key = String;
fn key(&self) -> Self::Key {
self.name.clone()
}
fn amalgamate(&mut self, other: Self) {
self.friends.extend(other.friends);
}
}
In this example, we have a Person
struct that has a name
and a set of friends
.
We implement the Amalgamate
trait for Person
by defining the Key
type as String
and
implementing the key
and amalgamate
functions.
We assume that the value of the name
field is unique to each person,
so we use it as the key to determine if two Person
objects should be combined.
Now that we have implemented the Amalgamate
trait, we can use the Amalgamator
data structure
to combine Person
objects together. Better yet, we can use it just like a regular set/map data structure.
use amalgamator::Amalgamator;
#
#
#
let mut amalgamator = Amalgamator::new();
let alice = Person {
name: "Alice".to_string(),
friends: ["Bob", "Charlie"].iter().map(|s| s.to_string()).collect(),
};
let bob = Person {
name: "Bob".to_string(),
friends: ["Alice", "Charlie"].iter().map(|s| s.to_string()).collect(),
};
let other_alice = Person {
name: "Alice".to_string(),
friends: ["David", "Eve"].iter().map(|s| s.to_string()).collect(),
};
amalgamator.add(alice);
amalgamator.add(bob);
amalgamator.add(other_alice);
assert_eq!(amalgamator.len(), 2);
let alice = &amalgamator["Alice"];
assert_eq!(alice.friends.len(), 4);
In this example, we create an Amalgamator
and add three Person
objects to it.
We then verify that the Amalgamator
contains only two Person
objects,
as the two Alice
objects (with the same name) have been combined.
We then retrieve the Alice
object from the Amalgamator
and verify that it has all the friends from both Alice
objects.
Features
serde
: Enables serialization and deserialization ofAmalgamator
using Serde.
Dependencies
~155KB