]>
Commit | Line | Data |
---|---|---|
e9174d1e SL |
1 | // Copyright 2015 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | use std::fmt; | |
12 | use std::cell::Cell; | |
13 | ||
14 | /// A write-once variable. When constructed, it is empty, and | |
15 | /// can only be set once. | |
16 | /// | |
17 | /// Ivars ensure that data that can only be initialised once. A full | |
18 | /// implementation is used for concurrency and blocks on a read of an | |
19 | /// unfulfilled value. This implementation is more minimal and panics | |
20 | /// if you attempt to read the value before it has been set. It is also | |
21 | /// not `Sync`, but may be extended in the future to be usable as a true | |
22 | /// concurrency type. | |
23 | /// | |
24 | /// The `T: Copy` bound is not strictly needed, but it is required by | |
25 | /// Cell (so removing it would require using UnsafeCell), and it | |
26 | /// suffices for the current purposes. | |
27 | #[derive(PartialEq)] | |
28 | pub struct Ivar<T: Copy> { | |
54a0048b | 29 | data: Cell<Option<T>>, |
e9174d1e SL |
30 | } |
31 | ||
32 | impl<T: Copy> Ivar<T> { | |
33 | pub fn new() -> Ivar<T> { | |
54a0048b | 34 | Ivar { data: Cell::new(None) } |
e9174d1e SL |
35 | } |
36 | ||
37 | pub fn get(&self) -> Option<T> { | |
38 | self.data.get() | |
39 | } | |
40 | ||
41 | pub fn fulfill(&self, value: T) { | |
54a0048b | 42 | assert!(self.data.get().is_none(), "Value already set!"); |
e9174d1e SL |
43 | self.data.set(Some(value)); |
44 | } | |
45 | ||
46 | pub fn is_fulfilled(&self) -> bool { | |
47 | self.data.get().is_some() | |
48 | } | |
49 | ||
50 | pub fn unwrap(&self) -> T { | |
51 | self.get().unwrap() | |
52 | } | |
53 | } | |
54 | ||
54a0048b | 55 | impl<T: Copy + fmt::Debug> fmt::Debug for Ivar<T> { |
e9174d1e SL |
56 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
57 | match self.get() { | |
58 | Some(val) => write!(f, "Ivar({:?})", val), | |
54a0048b | 59 | None => f.write_str("Ivar(<unfulfilled>)"), |
e9174d1e SL |
60 | } |
61 | } | |
62 | } | |
63 | ||
64 | impl<T: Copy> Clone for Ivar<T> { | |
65 | fn clone(&self) -> Ivar<T> { | |
66 | match self.get() { | |
67 | Some(val) => Ivar { data: Cell::new(Some(val)) }, | |
54a0048b | 68 | None => Ivar::new(), |
e9174d1e SL |
69 | } |
70 | } | |
71 | } |