1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! The thread-safe version of the list.
use ;
/// A thread-safe list holding weak references to its elements.
///
/// The list does not hold strong references to its elements and the elements do not hold
/// strong references to the list. You must use some other mechanism to keep all parties
/// alive.
///
/// This list supports concurrent iteration and modification.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// use {
/// weak_lists::{SyncWeakList, SyncWeakListElement},
/// std::{
/// array,
/// },
/// };
///
/// pub struct Service {
/// callbacks: SyncWeakList<dyn Callback>,
/// }
///
/// pub trait Callback {
/// fn run(&self);
/// }
///
/// impl Service {
/// pub fn register_callback(&self, callback: &SyncWeakListElement<dyn Callback>) {
/// callback.attach(&self.callbacks);
/// }
///
/// pub fn run_callbacks(&self) {
/// for callback in &self.callbacks {
/// callback.run();
/// }
/// }
/// }
///
/// struct Client {
/// id: usize,
/// entry: SyncWeakListElement<dyn Callback>,
/// }
///
/// impl Callback for Client {
/// fn run(&self) {
/// eprintln!("Callback {} invoked", self.id);
/// if self.id == 1 {
/// self.entry.detach();
/// }
/// }
/// }
///
/// let service = Service {
/// callbacks: Default::default(),
/// };
/// let clients = array::from_fn::<_, 3, _>(|id| {
/// Arc::<Client>::new_cyclic(|slf| Client {
/// id,
/// entry: SyncWeakListElement::new(slf.clone()),
/// })
/// });
/// for client in &clients {
/// service.register_callback(&client.entry);
/// }
/// service.run_callbacks();
/// // Callback 0 invoked
/// // Callback 1 invoked
/// // Callback 2 invoked
/// service.run_callbacks();
/// // Callback 0 invoked
/// // Callback 2 invoked
/// ```
/// An thread-safe element that can be inserted into a weak list.
///
/// Each element can be attached to 0 or 1 list. Attaching it to a list automatically
/// detaches itself from the previous list.
///
/// When this object is dropped, it detaches itself from its current list.
/// An iterator over list elements.
///
/// This object is created by calling [iter](SyncWeakList::iter) or by using the
/// [IntoIterator] implementation of `&SyncWeakList`.