diff options
| author | Grégoire Duchêne <gduchene@awhk.org> | 2025-05-25 09:51:27 +0100 |
|---|---|---|
| committer | Grégoire Duchêne <gduchene@awhk.org> | 2025-05-25 09:51:27 +0100 |
| commit | 30dd5b9f30912dbcc9c993ed0270be184d75df61 (patch) | |
| tree | e02fb682c3c4b366eb2fed2091243d0938568908 /promise.go | |
| parent | bca1b0ccdece7b992cc88712aca36a9a127b1381 (diff) | |
Diffstat (limited to 'promise.go')
| -rw-r--r-- | promise.go | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/promise.go b/promise.go new file mode 100644 index 0000000..29bd703 --- /dev/null +++ b/promise.go @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: © 2024 Grégoire Duchêne <gduchene@awhk.org> +// SPDX-License-Identifier: ISC + +package core + +import ( + "errors" + "sync/atomic" +) + +var ErrPromiseFulfilled = errors.New("promise fulfilled already") + +type Promise[T any] struct { + value chan T + error chan error + closed int32 + + _ NoCopy +} + +func NewPromise[T any]() *Promise[T] { + return &Promise[T]{value: make(chan T, 1), error: make(chan error, 1), closed: 0} +} + +func (p *Promise[T]) Err() <-chan error { return p.error } + +func (p *Promise[T]) FailWith(err error) error { + if !atomic.CompareAndSwapInt32(&p.closed, 0, 1) { + return ErrPromiseFulfilled + } + p.error <- err + close(p.error) + return nil +} + +func (p *Promise[T]) SucceedWith(value T) error { + if !atomic.CompareAndSwapInt32(&p.closed, 0, 1) { + return ErrPromiseFulfilled + } + p.value <- value + close(p.value) + return nil +} + +func (p *Promise[T]) Value() <-chan T { return p.value } |
