|
| 1 | +// Copyright The OpenTelemetry Authors |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +// maybe provides utilities for representing data may or may not exist at |
| 5 | +// runtime in a safe way. |
| 6 | +// |
| 7 | +// A typical approach to this are pointers, but they suffer from two issues: |
| 8 | +// - Unsafety: permitting nil pointers must require careful checking on each use, |
| 9 | +// which is easily forgotten |
| 10 | +// - Blindness: nil itself does cannot differentiate between "set to nil" and |
| 11 | +// "not set all", leading to unexepcted edge cases |
| 12 | +// |
| 13 | +// The [Ptr] type of this package provides a safe alternative with a clear |
| 14 | +// distinction between "not set" and "set to nil". |
| 15 | +package maybe // import "github.com/open-telemetry/opentelemetry-collector-contrib/processor/deltatocumulativeprocessor/internal/maybe" |
| 16 | + |
| 17 | +// Ptr references some value of type T that is not guaranteed to exist. |
| 18 | +// Callers must use [Ptr.Try] to access the underlying value, checking the |
| 19 | +// ok return value too. |
| 20 | +// This provides a clear distinction between "not set" and "set to nil". |
| 21 | +// |
| 22 | +// Use [Some] and [None] to create Ptrs. |
| 23 | +type Ptr[T any] struct { |
| 24 | + to *T |
| 25 | + ok bool |
| 26 | +} |
| 27 | + |
| 28 | +// None returns a Ptr that represents "not-set". |
| 29 | +// This is equal to a zero-value Ptr. |
| 30 | +func None[T any]() Ptr[T] { |
| 31 | + return Ptr[T]{to: nil, ok: false} |
| 32 | +} |
| 33 | + |
| 34 | +// Some returns a pointer to the passed T. |
| 35 | +// |
| 36 | +// The ptr argument may be nil, in which case this represents "explicitly set to |
| 37 | +// nil". |
| 38 | +func Some[T any](ptr *T) Ptr[T] { |
| 39 | + return Ptr[T]{to: ptr, ok: true} |
| 40 | +} |
| 41 | + |
| 42 | +// Try attempts to de-reference the Ptr, giving one of three results: |
| 43 | +// |
| 44 | +// - nil, false: not-set |
| 45 | +// - nil, true: explicitly set to nil |
| 46 | +// - non-nil, true: set to some value |
| 47 | +// |
| 48 | +// This provides extra safety over bare pointers, because callers are forced by |
| 49 | +// the compiler to either check or explicitly ignore the ok value. |
| 50 | +func (ptr Ptr[T]) Try() (_ *T, ok bool) { |
| 51 | + return ptr.to, ptr.ok |
| 52 | +} |
0 commit comments