1 // Copyright 2016 Amanieu d'Antras
2 // Copyright 2020 Amari Robinson
3 //
4 // Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
5 // http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
6 // http://opensource.org/licenses/MIT>, at your option. This file may not be
7 // copied, modified, or distributed except according to those terms.
8 
9 use crate::adapter::Adapter;
10 use crate::pointer_ops::PointerOps;
11 
12 /// Extension of the `Adapter` trait to provide a way of extracting a key from
13 /// an object. This key can then be used as an index in certain intrusive
14 /// collections (currently only `RBTree` uses this).
15 ///
16 /// The key can be returned either as a value or as a reference, which allows
17 /// you to
18 ///
19 /// # Examples
20 ///
21 /// ```
22 /// use intrusive_collections::intrusive_adapter;
23 /// use intrusive_collections::{RBTreeLink, KeyAdapter};
24 ///
25 /// struct S {
26 ///     link: RBTreeLink,
27 ///     key: u32,
28 ///     value: u64,
29 /// }
30 ///
31 /// // Adapter which returns a key by value
32 /// intrusive_adapter!(MyAdapter = Box<S>: S { link : RBTreeLink });
33 /// impl<'a> KeyAdapter<'a> for MyAdapter {
34 ///     type Key = u32;
35 ///     fn get_key(&self, s: &'a S) -> u32 { s.key }
36 /// }
37 ///
38 /// // Adapter which returns a key by reference
39 /// intrusive_adapter!(MyAdapter2 = Box<S>: S { link : RBTreeLink });
40 /// impl<'a> KeyAdapter<'a> for MyAdapter2 {
41 ///     type Key = &'a u32;
42 ///     fn get_key(&self, s: &'a S) -> &'a u32 { &s.key }
43 /// }
44 ///
45 /// struct U {
46 ///     link: RBTreeLink,
47 ///     key1: i32,
48 ///     key2: String,
49 ///     key3: f64,
50 /// }
51 ///
52 /// // Adapter which returns a tuple as a key. When used in a RBTree, this will
53 /// // keep all elements sorted by `key1` first, then `key2` and finally `key3`.
54 /// intrusive_adapter!(MyAdapter3 = Box<U>: U { link : RBTreeLink });
55 /// impl<'a> KeyAdapter<'a> for MyAdapter3 {
56 ///     type Key = (i32, &'a str, f64);
57 ///     fn get_key(&self, u: &'a U) -> Self::Key { (u.key1, &u.key2, u.key3) }
58 /// }
59 /// ```
60 pub trait KeyAdapter<'a>: Adapter {
61     /// Type of the key returned by `get_key`.
62     type Key;
63 
64     /// Gets the key for the given object.
get_key(&self, value: &'a <Self::PointerOps as PointerOps>::Value) -> Self::Key65     fn get_key(&self, value: &'a <Self::PointerOps as PointerOps>::Value) -> Self::Key;
66 }
67