go.mway.dev/x@v0.0.0-20240520034138-950aede9a3fb/env/var.go (about)

     1  // Copyright (c) 2023 Matt Way
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to
     5  // deal in the Software without restriction, including without limitation the
     6  // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
     7  // sell copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    18  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    19  // IN THE THE SOFTWARE.
    20  
    21  package env
    22  
    23  import (
    24  	"os"
    25  )
    26  
    27  var (
    28  	_osLookupEnv = os.LookupEnv
    29  	_osSetenv    = os.Setenv
    30  	_osGetenv    = os.Getenv
    31  	_osUnsetenv  = os.Unsetenv
    32  )
    33  
    34  // Var is a helper for managing environment variables.
    35  type Var struct {
    36  	key    string
    37  	value  string
    38  	orig   string
    39  	exists bool
    40  }
    41  
    42  // NewVar creates a new [Var] that manages an environment variable with the
    43  // given key.
    44  func NewVar(key string) *Var {
    45  	orig, exists := _osLookupEnv(key)
    46  	return &Var{
    47  		key:    key,
    48  		value:  orig,
    49  		orig:   orig,
    50  		exists: exists,
    51  	}
    52  }
    53  
    54  // Key returns the key (environment variable name) for v.
    55  func (v *Var) Key() string {
    56  	return v.key
    57  }
    58  
    59  // Value returns the current value of v.
    60  func (v *Var) Value() string {
    61  	return v.value
    62  }
    63  
    64  // Clone clones v.
    65  func (v *Var) Clone() *Var {
    66  	tmp := *v
    67  	return &tmp
    68  }
    69  
    70  // Set uses value as the current value of both v and its environment variable.
    71  func (v *Var) Set(value string) error {
    72  	if err := _osSetenv(v.key, value); err != nil {
    73  		return err
    74  	}
    75  	v.value = value
    76  	return nil
    77  }
    78  
    79  // MustSet calls v.Set and panics if it returns an error.
    80  func (v *Var) MustSet(value string) {
    81  	if err := v.Set(value); err != nil {
    82  		panic(err)
    83  	}
    84  }
    85  
    86  // Unset unsets v within the environment, if set.
    87  func (v *Var) Unset() error {
    88  	if err := _osUnsetenv(v.key); err != nil {
    89  		return err
    90  	}
    91  
    92  	v.value = ""
    93  	return nil
    94  }
    95  
    96  // MustUnset calls v.Unset and panics if it returns an error.
    97  func (v *Var) MustUnset() {
    98  	if err := v.Unset(); err != nil {
    99  		panic(err)
   100  	}
   101  }
   102  
   103  // Load loads the current environment value of v and stores it.
   104  func (v *Var) Load() {
   105  	v.value = _osGetenv(v.key)
   106  }
   107  
   108  // Restore restores v to its original state. If the variable managed by v did
   109  // not exist previously, it is unset; otherwise, the original value is set in
   110  // both v and the environment.
   111  func (v *Var) Restore() error {
   112  	if v.exists {
   113  		return v.Set(v.orig)
   114  	}
   115  
   116  	return v.Unset()
   117  }
   118  
   119  // MustRestore calls v.Restore and panics if it returns an error.
   120  func (v *Var) MustRestore() {
   121  	if err := v.Restore(); err != nil {
   122  		panic(err)
   123  	}
   124  }