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
use std::ops::{Deref, DerefMut};
/// A container type which holds a value that may be temporarily owned by a
/// consumer.
pub struct Owner<T> {
inner: Option<T>
}
impl<T> Owner<T> {
/// Creates a new `Owner` which holds the given value.
pub fn new(value: T) -> Owner<T> {
Owner { inner: Some(value) }
}
/// Takes temporary ownership of the contained value by passing it to `f`.
/// The function must return a value of the same type (the same value, or a
/// new value to take its place).
///
/// # Example
/// ```
/// # use merk::owner::Owner;
/// # struct SomeType();
/// # impl SomeType {
/// # fn method_which_requires_ownership(self) -> SomeType { self }
/// # }
/// #
/// let mut owner = Owner::new(SomeType());
/// owner.own(|value| {
/// value.method_which_requires_ownership();
/// SomeType() // now give back a value of the same type
/// });
/// ```
pub fn own<F: FnOnce(T) -> T>(&mut self, f: F) {
let old_value = unwrap(self.inner.take());
let new_value = f(old_value);
self.inner = Some(new_value);
}
/// Takes temporary ownership of the contained value by passing it to `f`.
/// The function must return a value of the same type (the same value, or a
/// new value to take its place).
///
/// Like `own`, but uses a tuple return type which allows specifying a value
/// to return from the call to `own_return` for convenience.
///
/// # Example
/// ```
/// # use merk::owner::Owner;
/// let mut owner = Owner::new(123);
/// let doubled = owner.own_return(|n| (n, n * 2));
/// ```
pub fn own_return<R, F>(&mut self, f: F) -> R
where
R: Sized,
F: FnOnce(T) -> (T, R)
{
let old_value = unwrap(self.inner.take());
let (new_value, return_value) = f(old_value);
self.inner = Some(new_value);
return_value
}
/// Sheds the `Owner` container and returns the value it contained.
pub fn into_inner(mut self) -> T {
unwrap(self.inner.take())
}
}
impl<T> Deref for Owner<T> {
type Target = T;
fn deref(&self) -> &T {
unwrap(self.inner.as_ref())
}
}
impl<T> DerefMut for Owner<T> {
fn deref_mut(&mut self) -> &mut T {
unwrap(self.inner.as_mut())
}
}
fn unwrap<T>(option: Option<T>) -> T {
match option {
Some(value) => value,
None => unreachable!("value should be Some")
}
}
// TODO: unit tests