Crate ownref[][src]

Expand description

References bundled with referee’s owner, ordered by pointer address or data content.

This crate provides the smart pointer type that bundles the data with its owner. It has the folloing features:

  • The data is either a reference to a portion of the owner, or a data type that may contain references to the owner.
  • The refernce can be ordered by data content or data pointer address.
  • The owner is contained in Box or Arc.

The following table shows Box-based reference types. The generic O denotes the owner type and I denotes the data type.

data type (I) \ orderingContent orderedPointer address ordered
ReferenceBoxRefC<O, I>BoxRefA<O, I>
OwnedBoxOwnedC<O, I>BoxOwnedA<O, I>

The following table shows Arc-based reference types.

data type (I) \ orderingContent orderedPointer address ordered
ReferenceArcRefC<O, I>ArcRefA<O, I>
OwnedArcOwnedC<O, I>ArcOwnedA<O, I>

For example,

  • BoxRefA<Vec<str>, str> is a reference to str within the owner Vec<str>, which is ordered by pointer address.
  • ArcOwnedC<Vec<str>, Option<&str>> stores the data type Option<&str>, which contains a reference within the owner Vec<str>. The reference is ordered by the data content.

Construction and destruction

The smart references are built in the following ways.

use ownref::{ArcRefA, ArcRefC, BoxRefA, BoxRefC};

struct Owner {
    a: u8,
    b: f32,
}

// direct method
let _: BoxRefA<Owner, Owner> = BoxRefA::new(Owner { a: 7, b: 3.14 });
let _: ArcRefA<Owner, Owner> = ArcRefA::new(Owner { a: 7, b: 3.14 });

// from boxed data
let boxed = Box::new(Owner { a: 7, b: 3.14 });
let _: BoxRefC<Owner, Owner> = BoxRefC::from(boxed);

let boxed = Arc::new(Owner { a: 7, b: 3.14 });
let _: ArcRefC<Owner, Owner> = ArcRefC::from(boxed);

BoxRef is destructed by BoxRef::into_owner().

let owner = ['a', 'b'];
let boxref = BoxRefA::new(owner); // box the owner
let owner = BoxRefA::into_owner(boxref); // recover the owner

ArcRef is destructed by ArcRef::unwrap_owner(). It panics of the strong count is more than one.

let owner = ['a', 'b'];
let arcref = ArcRefA::new(owner); // box the owner
let owner = ArcRefA::unwrap_owner(arcref); // recover the owner

Data type transformation

The family of methods map(), filter_map() and try_map() can transform the data type.

struct Owner {
    a: u8,
    b: f32,
}

let owner: BoxRefA<Owner, Owner> = BoxRefA::new(Owner { a: 7, b: 3.14 });
let inner: BoxRefA<Owner, f32> = owner.map(|data: &mut Owner| &mut data.b);

// above is equivalent to
let owner: BoxOwnedA<Owner, &mut Owner> = BoxOwnedA::new(Owner { a: 7, b: 3.14 });
let inner: BoxOwnedA<Owner, &mut f32> = owner.map(|data: &mut Owner| &mut data.b);

Note that for Owned types. It is possible to transform the data such that the outcome data does not reference to the owner.

let owner: BoxOwnedA<Owner, &mut Owner> = BoxOwnedA::new(Owner { a: 7, b: 3.14 });
let inner: BoxOwnedA<Owner, i32> = owner.map(|_| 5i32);

Ordering

ArcRefA is ordered by pointer address. The code below creates two references pointing to distinct elements of an array, which element values are identical. The references are distinguished by their pointer address.

let own1 = ArcRefA::new(['a', 'a']);
let own2 = own1.clone();

let ref1: ArcRefA<[char; 2], char> = own1.map(|array| &array[0]);
let ref2: ArcRefA<[char; 2], char> = own2.map(|array| &array[1]);
assert!(ref1 != ref2); // differ by pointer address

ArcRefC is ordered by data content. The code below shows two references pointing to distinct elements of an array, and are equalized by identical element value.

let own1 = ArcRefC::new(['a', 'a']);
let own2 = own1.clone();

let ref1: ArcRefC<[char; 2], char> = own1.map(|array| &array[0]);
let ref2: ArcRefC<[char; 2], char> = own2.map(|array| &array[1]);
assert!(ref1 == ref2); // equalized by content

Iterator flattening

ArcRef is able to flatten the referenced data if the data type can be turned into an iterator. For example, it can turn a reference to a vec into a vec of element references.

let vec: ArcRefC<Vec<char>> = ArcRefC::new(vec!['a', 'b', 'c']);
let collected: Vec<ArcRefC<Vec<char>, char>> = vec.flatten().collect();

ArcOwned is more versatile. It can flatten a map to references to its keys, values or key-value pairs.

let map: IndexMap<_, _> = [('a', 1), ('b', 2), ('c', 3)].into_iter().collect();
let own: ArcOwnedC<_> = ArcOwnedC::new(map);

let pairs: Vec<ArcOwnedC<_, (&char, &usize)>> =
    own.clone().flat_map(|map| map.iter()).collect();
let keys: Vec<ArcOwnedC<_, &char>> = own.clone().flat_map(|map| map.keys()).collect();
let values: Vec<ArcOwnedC<_, &usize>> = own.flat_map(|map| map.values()).collect();

Owner erasure

The owner type can forget the owner type and keeps the data reference.

let letter: BoxRefC<[char; 2], char> = BoxRefC::new(['a', 'b']).map(|array| &mut array[0]);

// erase the owner
let letter: BoxRefAnyC<char> = BoxRefC::into_any_owner(letter);

// recover the owner
let letter: BoxRefC<[char; 2], char> = match BoxRefC::downcast_owner(letter) {
    Ok(new_owner) => new_owner,
    Err(_old_owner) => unreachable!(),
};

This example creates two u64 references within distinct owner types. The owner type of references are erased so that they can be placed into a Vec.

struct OwnerX {
    a: u8,
    b: u64,
}

struct OwnerY {
    c: f32,
    d: u64,
}

let own1 = BoxRefC::new(OwnerX { a: 7, b: 314 });
let ref1 = own1.map(|data| &mut data.b);

let own2 = BoxRefC::new(OwnerY { c: 0.66, d: 52 });
let ref2 = own2.map(|data| &mut data.d);

// ref1 and ref2 have different owners, erase ownwer types
let ref1: BoxRefAnyC<u64> = BoxRefC::into_any_owner(ref1);
let ref2: BoxRefAnyC<u64> = BoxRefC::into_any_owner(ref2);

// so they can be stored in a vec
vec![ref1, ref2];

Modules

Marker types.

Structs

Owned data bundled with an owner in Arc.

Reference to data within an owner in Arc.

Owned data bundled with an owner in Box.

Reference to data within an owner in Box.

Type Definitions

Pointer address ordered owned data bundled with an owner in Arc.

Pointer address ordered owned data bundled with an Any owner in Arc.

Content ordered owned data bundled with an Any owner in Arc.

Content ordered owned data bundled with an owner in Arc.

Pointer address ordered reference to data within an owner in Arc.

Pointer address ordered reference to data within an Any owner in Arc.

Content ordered reference to data within an Any owner in Arc.

Content ordered reference to data within an owner in Arc.

Pointer address ordered owned data bundled with an owner in Box.

Pointer address ordered owned data bundled with an Any + Send owner in Box.

Content ordered owned data bundled with an Any + Send owner in Box.

Pointer address ordered owned data bundled with an Any owner in Box.

Content ordered owned data bundled with an Any owner in Box.

Content ordered owned data bundled with an owner in Box.

Pointer address ordered reference to data within an owner in Box.

Pointer address ordered reference to data within an Any + Send owner in Box.

Content ordered reference to data within an Any + Send owner in Box.

Pointer address ordered reference to data within an Any owner in Box.

Content ordered reference to data within an Any owner in Box.

Content ordered reference to data within an owner in Box.