From 30dd5b9f30912dbcc9c993ed0270be184d75df61 Mon Sep 17 00:00:00 2001 From: Grégoire Duchêne Date: Sun, 25 May 2025 09:51:27 +0100 Subject: Introduce a Promise type --- promise.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 promise.go (limited to 'promise.go') 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 +// 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 } -- cgit v1.2.3-70-g09d2