Skip to main content

HandleGroups

Struct HandleGroups 

Source
pub struct HandleGroups { /* private fields */ }
Expand description

Groups of handle rows that belong to one person.

We group rows when their id values match byte-for-byte (one address registered on several services) or their person_centric_id values match. Call HandleGroups::union to add relationships from outside the database, such as contact matches. Call HandleGroups::finalize to assign one sequential group ID to each class.

Compare stored id values without normalization. Messages lowercases email addresses and canonicalizes phone numbers before storing them. Do not match phone numbers on digits alone; you could combine a short code with a full number that shares its suffix.

The iMessage server attached person_centric_id to incoming messages as a merge ID, but stopped issuing it for new senders long ago. Current databases retain this field only for the oldest handles. Keep a present ID as a grouping edge; it remains reliable even though current databases rarely include it.

§Example:

use imessage_database::util::dirs::default_db_path;
use imessage_database::tables::table::get_connection;
use imessage_database::tables::handle::HandleGroups;

let db_path = default_db_path().unwrap();
let conn = get_connection(&db_path).unwrap();
let mut groups = HandleGroups::from_db(&conn).unwrap();
groups.union(3, 7);
let group_by_handle = groups.finalize();

Implementations§

Source§

impl HandleGroups

Source

pub fn from_db(db: &Connection) -> Result<Self, TableError>

Seed groups from every row of the handle table.

Load the table through Handle::load, then seed the groups with HandleGroups::from_rows.

Source

pub fn from_rows(handles: &[Handle]) -> Self

Seed groups from loaded handle rows.

Include row ID 0 as its own group. Chat participant lists can use it for the local user.

Source

pub fn union(&mut self, a: i32, b: i32)

Merge the groups containing two handle row IDs.

Pass row IDs from the table. Unknown IDs have no effect, so an external source cannot create a phantom group with a stale ID.

Source

pub fn finalize(self) -> HashMap<i32, i32>

Assign a sequential group ID to each class and return it keyed by handle row ID.

Order classes by their smallest row ID before assigning sequential IDs. This keeps results stable for an unchanged table, even when union-find picks a different representative.

Trait Implementations§

Source§

impl Debug for HandleGroups

Source§

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

Formats the value using the given formatter. Read more

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> 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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.