github.com/Schaudge/grailbase@v0.0.0-20240223061707-44c758a471c0/must/must.go (about)

     1  // Copyright 2019 GRAIL, Inc. All rights reserved.
     2  // Use of this source code is governed by the Apache 2.0
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package must provides a handful of functions to express fatal
     6  // assertions in Go programs. It is meant to alleviate cumbersome
     7  // error handling and reporting when the only course of action is to
     8  // fail the program. Package must is intended to be used by top-level
     9  // binaries (i.e., in main packages); it should rarely be used
    10  // elsewhere.
    11  package must
    12  
    13  import (
    14  	"fmt"
    15  
    16  	"github.com/Schaudge/grailbase/log"
    17  )
    18  
    19  // Func is the function called to report an error and interrupt execution. Func
    20  // is typically set to a function that logs the message and halts execution,
    21  // e.g. by panicking. It should be set before any potential calls to functions
    22  // in the must package. Func is passed the call depth of the caller of the must
    23  // function, e.g. the caller of Nil. This can be used to annotate messages.
    24  //
    25  // The default implementation logs the message with
    26  // github.com/Schaudge/grailbase/log at the Error level and then panics.
    27  var Func func(int, ...interface{}) = func(depth int, v ...interface{}) {
    28  	s := fmt.Sprint(v...)
    29  	// Nothing to do if output fails.
    30  	_ = log.Output(depth+1, log.Error, s)
    31  	panic(s)
    32  }
    33  
    34  // Nil asserts that v is nil; v is typically a value of type error.
    35  // If v is not nil, Nil formats a message in hte manner of fmt.Sprint
    36  // and calls must.Func. Nil also suffixes the message with the
    37  // fmt.Sprint-formatted value of v.
    38  func Nil(v interface{}, args ...interface{}) {
    39  	if v == nil {
    40  		return
    41  	}
    42  	if len(args) == 0 {
    43  		Func(2, v)
    44  		return
    45  	}
    46  	Func(2, fmt.Sprint(args...), ": ", v)
    47  }
    48  
    49  // Nilf asserts that v is nil; v is typically a value of type error.
    50  // If v is not nil, Nilf formats a message in hte manner of
    51  // fmt.Sprintf and calls must.Func. Nilf also suffixes the message
    52  // with the fmt.Sprint-formatted value of v.
    53  func Nilf(v interface{}, format string, args ...interface{}) {
    54  	if v == nil {
    55  		return
    56  	}
    57  	Func(2, fmt.Sprintf(format, args...), ": ", v)
    58  }
    59  
    60  // True is a no-op if the value b is true. If it is false, True
    61  // formats a message in the manner of fmt.Sprint and calls Func.
    62  func True(b bool, v ...interface{}) {
    63  	if b {
    64  		return
    65  	}
    66  	if len(v) == 0 {
    67  		Func(2, "must: assertion failed")
    68  		return
    69  	}
    70  	Func(2, v...)
    71  }
    72  
    73  // Truef is a no-op if the value b is true. If it is false, True
    74  // formats a message in the manner of fmt.Sprintf and calls Func.
    75  func Truef(x bool, format string, v ...interface{}) {
    76  	if x {
    77  		return
    78  	}
    79  	Func(2, fmt.Sprintf(format, v...))
    80  }
    81  
    82  // Never asserts that it is never called. If it is, it formats a message
    83  // in the manner of fmt.Sprint and calls Func.
    84  func Never(v ...interface{}) {
    85  	Func(2, v...)
    86  }
    87  
    88  // Neverf asserts that it is never called. If it is, it formats a message
    89  // in the manner of fmt.Sprintf and calls Func.
    90  func Neverf(format string, v ...interface{}) {
    91  	Func(2, fmt.Sprintf(format, v...))
    92  }