calcit_fingertrees/reference.rs
1use std::ops::Deref;
2use std::rc::Rc;
3use std::sync::Arc;
4
5use crate::measure::Measured;
6use crate::node::NodeInner;
7use crate::tree::TreeInner;
8
9/// Interface that all reference types should impelmenet
10pub trait Ref: Clone + Deref
11where
12 Self::Target: Sized,
13{
14 /// Construct reference from target type
15 fn new(value: Self::Target) -> Self;
16}
17
18impl<T> Ref for Rc<T> {
19 fn new(value: Self::Target) -> Self {
20 Rc::new(value)
21 }
22}
23
24impl<T> Ref for Arc<T> {
25 fn new(value: Self::Target) -> Self {
26 Arc::new(value)
27 }
28}
29
30/// Interface which defines all reference types needed by finger tree implementation.
31///
32/// By implementing this interface for your reference type you can use finger treee
33/// with your reference type.
34///
35/// # Example:
36/// ```
37/// use std::rc::Rc;
38/// use std::ops::Deref;
39/// use calcit_fingertrees::measure::Size;
40/// use calcit_fingertrees::{FingerTree, Measured, Ref, fingertree_define_refs};
41///
42/// // your custom reference type
43/// struct MyRef<T>(Rc<T>);
44///
45/// impl<T> Clone for MyRef<T> {
46/// fn clone(&self) -> Self {
47/// MyRef(self.0.clone())
48/// }
49/// }
50///
51/// impl<T> Deref for MyRef<T> {
52/// type Target = T;
53/// fn deref(&self) -> &T {
54/// &*self.0
55/// }
56/// }
57///
58/// impl<T> Ref for MyRef<T> {
59/// fn new(value: T) -> Self {
60/// MyRef(Rc::new(value))
61/// }
62/// }
63///
64/// // define type family for your reference
65/// fingertree_define_refs!(MyRefs, MyRef);
66///
67/// // now you can construct fingertree using your reference type
68/// let _: FingerTree<MyRefs, _> = (0..128).map(Size).collect();
69/// ```
70pub trait Refs<V>: Sized
71where
72 V: Measured,
73{
74 /// Reference on a `Node`
75 type Node: Ref<Target = NodeInner<Self, V>>;
76 /// Reference on a `Tree`
77 type Tree: Ref<Target = TreeInner<Self, V>>;
78}
79
80/// Helper macro to define custom [`Refs`](trait.Refs.html) for `FingerTree`
81#[macro_export]
82macro_rules! fingertree_define_refs {
83 (pub $refs:ident, $ref:ident) => {
84 /// References type family
85 pub enum $refs {}
86 fingertree_define_refs!(@refs_impl $refs, $ref);
87 };
88
89 ($refs:ident, $ref:ident) => {
90 /// References type family
91 enum $refs {}
92 fingertree_define_refs!(@refs_impl $refs, $ref);
93 };
94
95 (@refs_impl $refs:ident, $ref:ident) => {
96 impl<V> $crate::Refs<V> for $refs
97 where
98 V: $crate::measure::Measured,
99 {
100 type Node = $ref<$crate::NodeInner<Self, V>>;
101 type Tree = $ref<$crate::TreeInner<Self, V>>;
102 }
103 };
104}
105
106fingertree_define_refs!(pub RcRefs, Rc);
107fingertree_define_refs!(pub ArcRefs, Arc);