Skip to content

Commit bffa402

Browse files
matkladindiv0
authored andcommitted
feat: add LazyCell::try_borrow_with
1 parent b04ef03 commit bffa402

File tree

1 file changed

+37
-3
lines changed

1 file changed

+37
-3
lines changed

src/lib.rs

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ impl<T> LazyCell<T> {
6262
/// Put a value into this cell.
6363
///
6464
/// This function will return `Err(value)` is the cell is already full.
65-
pub fn fill(&self, t: T) -> Result<(), T> {
65+
pub fn fill(&self, value: T) -> Result<(), T> {
6666
let mut slot = unsafe { &mut *self.inner.get() };
6767
if slot.is_some() {
68-
return Err(t);
68+
return Err(value);
6969
}
70-
*slot = Some(t);
70+
*slot = Some(value);
7171

7272
Ok(())
7373
}
@@ -109,6 +109,18 @@ impl<T> LazyCell<T> {
109109
slot.as_ref().unwrap()
110110
}
111111

112+
/// Same as `borrow_with`, but allows the initializing function to fail.
113+
pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
114+
where F: FnOnce() -> Result<T, E>
115+
{
116+
let mut slot = unsafe { &mut *self.inner.get() };
117+
if !slot.is_some() {
118+
*slot = Some(f()?);
119+
}
120+
121+
Ok(slot.as_ref().unwrap())
122+
}
123+
112124
/// Consumes this `LazyCell`, returning the underlying value.
113125
pub fn into_inner(self) -> Option<T> {
114126
unsafe { self.inner.into_inner() }
@@ -284,6 +296,28 @@ mod tests {
284296
assert_eq!(&1, value);
285297
}
286298

299+
#[test]
300+
fn test_try_borrow_with_ok() {
301+
let lazycell = LazyCell::new();
302+
let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
303+
assert_eq!(result, Ok(&1));
304+
}
305+
306+
#[test]
307+
fn test_try_borrow_with_err() {
308+
let lazycell = LazyCell::<()>::new();
309+
let result = lazycell.try_borrow_with(|| Err(1));
310+
assert_eq!(result, Err(1));
311+
}
312+
313+
#[test]
314+
fn test_try_borrow_with_already_filled() {
315+
let lazycell = LazyCell::new();
316+
lazycell.fill(1).unwrap();
317+
let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
318+
assert_eq!(result, Ok(&1));
319+
}
320+
287321
#[test]
288322
fn test_into_inner() {
289323
let lazycell = LazyCell::new();

0 commit comments

Comments
 (0)