Skip to content

Commit

Permalink
feat: add LazyCell::try_borrow_with
Browse files Browse the repository at this point in the history
  • Loading branch information
matklad authored and indiv0 committed Nov 24, 2017
1 parent b04ef03 commit bffa402
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ impl<T> LazyCell<T> {
/// Put a value into this cell.
///
/// This function will return `Err(value)` is the cell is already full.
pub fn fill(&self, t: T) -> Result<(), T> {
pub fn fill(&self, value: T) -> Result<(), T> {
let mut slot = unsafe { &mut *self.inner.get() };
if slot.is_some() {
return Err(t);
return Err(value);
}
*slot = Some(t);
*slot = Some(value);

Ok(())
}
Expand Down Expand Up @@ -109,6 +109,18 @@ impl<T> LazyCell<T> {
slot.as_ref().unwrap()
}

/// Same as `borrow_with`, but allows the initializing function to fail.
pub fn try_borrow_with<E, F>(&self, f: F) -> Result<&T, E>
where F: FnOnce() -> Result<T, E>
{
let mut slot = unsafe { &mut *self.inner.get() };
if !slot.is_some() {
*slot = Some(f()?);
}

Ok(slot.as_ref().unwrap())
}

/// Consumes this `LazyCell`, returning the underlying value.
pub fn into_inner(self) -> Option<T> {
unsafe { self.inner.into_inner() }
Expand Down Expand Up @@ -284,6 +296,28 @@ mod tests {
assert_eq!(&1, value);
}

#[test]
fn test_try_borrow_with_ok() {
let lazycell = LazyCell::new();
let result = lazycell.try_borrow_with::<(), _>(|| Ok(1));
assert_eq!(result, Ok(&1));
}

#[test]
fn test_try_borrow_with_err() {
let lazycell = LazyCell::<()>::new();
let result = lazycell.try_borrow_with(|| Err(1));
assert_eq!(result, Err(1));
}

#[test]
fn test_try_borrow_with_already_filled() {
let lazycell = LazyCell::new();
lazycell.fill(1).unwrap();
let result = lazycell.try_borrow_with::<(), _>(|| unreachable!());
assert_eq!(result, Ok(&1));
}

#[test]
fn test_into_inner() {
let lazycell = LazyCell::new();
Expand Down

0 comments on commit bffa402

Please sign in to comment.