github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/errs/errs.go (about)

     1  // Package errs declares error types used as exception causes.
     2  package errs
     3  
     4  import (
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/markusbkk/elvish/pkg/parse"
     9  )
    10  
    11  // OutOfRange encodes an error where a value is out of its valid range.
    12  type OutOfRange struct {
    13  	What      string
    14  	ValidLow  string
    15  	ValidHigh string
    16  	Actual    string
    17  }
    18  
    19  // Error implements the error interface.
    20  func (e OutOfRange) Error() string {
    21  	if e.ValidHigh < e.ValidLow {
    22  		return fmt.Sprintf(
    23  			"out of range: %v has no valid value, but is %v", e.What, e.Actual)
    24  	}
    25  	return fmt.Sprintf(
    26  		"out of range: %s must be from %s to %s, but is %s",
    27  		e.What, e.ValidLow, e.ValidHigh, e.Actual)
    28  }
    29  
    30  // BadValue encodes an error where the value does not meet a requirement. For
    31  // out-of-range errors, use OutOfRange.
    32  type BadValue struct {
    33  	What   string
    34  	Valid  string
    35  	Actual string
    36  }
    37  
    38  // Error implements the error interface.
    39  func (e BadValue) Error() string {
    40  	return fmt.Sprintf(
    41  		"bad value: %v must be %v, but is %v", e.What, e.Valid, e.Actual)
    42  }
    43  
    44  // ArityMismatch encodes an error where the expected number of values is out of
    45  // the valid range.
    46  type ArityMismatch struct {
    47  	What      string
    48  	ValidLow  int
    49  	ValidHigh int
    50  	Actual    int
    51  }
    52  
    53  func (e ArityMismatch) Error() string {
    54  	switch {
    55  	case e.ValidHigh == e.ValidLow:
    56  		return fmt.Sprintf("arity mismatch: %v must be %v, but is %v",
    57  			e.What, nValues(e.ValidLow), nValues(e.Actual))
    58  	case e.ValidHigh == -1:
    59  		return fmt.Sprintf("arity mismatch: %v must be %v or more values, but is %v",
    60  			e.What, e.ValidLow, nValues(e.Actual))
    61  	default:
    62  		return fmt.Sprintf("arity mismatch: %v must be %v to %v values, but is %v",
    63  			e.What, e.ValidLow, e.ValidHigh, nValues(e.Actual))
    64  	}
    65  }
    66  
    67  func nValues(n int) string {
    68  	if n == 1 {
    69  		return "1 value"
    70  	}
    71  	return strconv.Itoa(n) + " values"
    72  }
    73  
    74  // SetReadOnlyVar is returned by the Set method of a read-only variable.
    75  type SetReadOnlyVar struct {
    76  	// Name of the read-only variable. This field is initially empty, and
    77  	// populated later when context information is available.
    78  	VarName string
    79  }
    80  
    81  // Error implements the error interface.
    82  func (e SetReadOnlyVar) Error() string {
    83  	return fmt.Sprintf(
    84  		"cannot set read-only variable $%s", parse.QuoteVariableName(e.VarName))
    85  }
    86  
    87  // ReaderGone is raised by the writer in a pipeline when the reader end has
    88  // terminated. It could be raised directly by builtin commands, or when an
    89  // external command gets terminated by SIGPIPE after Elvish detects the read end
    90  // of the pipe has exited earlier.
    91  type ReaderGone struct {
    92  }
    93  
    94  // Error implements the error interface.
    95  func (e ReaderGone) Error() string {
    96  	return "reader gone"
    97  }