package org.zalando.riptide.capture;
import javax.annotation.Nullable;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
final class DefaultCapture<T> implements Capture<T> {
/**
* A reference holding the captured value. It can represent three different states:
* <ol>
* <li>{@code null}: not captured</li>
* <li>{@code Optional.empty()}: captured null</li>
* <li>{@code Optional.of(..)}: captured non-null</li>
* </ol>
*/
private final AtomicReference<Optional<T>> reference = new AtomicReference<>();
@Override
public void tryAccept(@Nullable final T input) {
reference.compareAndSet(null, Optional.ofNullable(input));
}
@Override
public T apply(final Void result) {
final Optional<T> value = reference.get();
checkPresent(value);
return value.orElse(null);
}
private void checkPresent(@Nullable final Optional<T> value) {
if (value == null) {
throw new NoSuchElementException("No value present");
}
}
}