1// Copyright 2023 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package optional 16 17// ShallowOptional is an optional type that can be constructed from a pointer. 18// It will not copy the pointer, and its size is the same size as a single pointer. 19// It can be used to prevent a downstream consumer from modifying the value through 20// the pointer, but is not suitable for an Optional type with stronger value semantics 21// like you would expect from C++ or Rust Optionals. 22type ShallowOptional[T any] struct { 23 inner *T 24} 25 26// NewShallowOptional creates a new ShallowOptional from a pointer. 27// The pointer will not be copied, the object could be changed by the calling 28// code after the optional was created. 29func NewShallowOptional[T any](inner *T) ShallowOptional[T] { 30 return ShallowOptional[T]{inner: inner} 31} 32 33// IsPresent returns true if the optional contains a value 34func (o *ShallowOptional[T]) IsPresent() bool { 35 return o.inner != nil 36} 37 38// IsEmpty returns true if the optional does not have a value 39func (o *ShallowOptional[T]) IsEmpty() bool { 40 return o.inner == nil 41} 42 43// Get() returns the value inside the optional. It panics if IsEmpty() returns true 44func (o *ShallowOptional[T]) Get() T { 45 if o.inner == nil { 46 panic("tried to get an empty optional") 47 } 48 return *o.inner 49} 50 51// GetOrDefault() returns the value inside the optional if IsPresent() returns true, 52// or the provided value otherwise. 53func (o *ShallowOptional[T]) GetOrDefault(other T) T { 54 if o.inner == nil { 55 return other 56 } 57 return *o.inner 58} 59