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
138
139
140
141
142
143
144
145
//! LendingCell is a mutable container that
//! allows you to get an owned reference to the same
//! object. When the owned reference is dropped,
//! ownership returns to the original container.
//!
//! As opposed to a [`std::cell::Cell`] which moves Rust's
//! _ownership_ rules to runtime, a `LendingCell` moves Rust's
//! _lifetime_ rules to runtime.
//!
//! The value of a `LendingCell` is present at
//! construction-time, but you can convert it to a
//! `BorrowedCell<T>` by calling [`LendingCell::to_borrowed`].
//! While that `BorrowedCell` lives (that is, until it is dropped),
//! calling [`LendingCell::try_get`] will return `None`. The
//! `BorrowedCell` has exclusive access to your type, as though you
//! have a directly owned instance of the `T`, and so it is `Send`
//! as long as `T` is Send. At last, when you drop the `BorrowedCell`,
//! the `T` is returned to the `LendingCell`.
//!
//! If you drop your `LendingCell` before dropping the `BorrowedCell`,
//! then the `T` is dropped at the time you drop the `BorrowedCell`.
//!
//! The invariants that Rust's memory safety rules enforce, like
//! the single-mutable reference rule, are therefor partially ensured
//! at compile time (you can't get two mutable references to the
//! `T`), but also partially at runtime (while the `BorrowedCell`
//! is active, the `LendingCell` behaves as though it is an `Option`
//! containing `None`.
//!
//! # Why
//! A general use for this crate is when you need a reference to a variable,
//! but you're not able to use a lifetime. For example, Rust's [`Iterator`]
//! type [doesn't allow a lifetime](https://rust-lang.github.io/rfcs/1598-generic_associated_types.html)
//! on each `Item` that's independent of the container you're iterating over
//! which means that Rust only allows you to iterate over a container
//! with a lifetime exceeding your iterator, or to consume the container.
//! What if instead you had to modify your
use UnsafeCell;
use ;
use Arc;
/// A container that allows borrowing without lifetimes.
///
/// ```rust
/// # use lending_cell::*;
/// let mut lender = LendingCell::new("borrowed");
/// let borrowed = lender.to_borrowed();
/// assert!(lender.try_get().is_none()); // `lender` is empty because it was borrowed
/// assert_eq!(*borrowed, "borrowed"); // it's certain that `borrowed` is valid while in scope
/// drop(borrowed); // dropping `borrowed` returns its value to `lender`
/// assert!(lender.try_get().is_some());
/// ```
// SAFETY: type imitates T ownership
unsafe
unsafe
/// The container that ensures you have borrowed the [`LendingCell`].
// SAFETY: type imitates either a mutable reference or an ownership
unsafe
unsafe