github.com/opencontainers/runtime-tools@v0.9.0/error/error.go (about)

     1  // Package error implements generic tooling for tracking RFC 2119
     2  // violations and linking back to the appropriate specification section.
     3  package error
     4  
     5  import (
     6  	"fmt"
     7  	"strings"
     8  )
     9  
    10  // Level represents the RFC 2119 compliance levels
    11  type Level int
    12  
    13  const (
    14  	// MAY-level
    15  
    16  	// May represents 'MAY' in RFC 2119.
    17  	May Level = iota
    18  	// Optional represents 'OPTIONAL' in RFC 2119.
    19  	Optional
    20  
    21  	// SHOULD-level
    22  
    23  	// Should represents 'SHOULD' in RFC 2119.
    24  	Should
    25  	// ShouldNot represents 'SHOULD NOT' in RFC 2119.
    26  	ShouldNot
    27  	// Recommended represents 'RECOMMENDED' in RFC 2119.
    28  	Recommended
    29  	// NotRecommended represents 'NOT RECOMMENDED' in RFC 2119.
    30  	NotRecommended
    31  
    32  	// MUST-level
    33  
    34  	// Must represents 'MUST' in RFC 2119
    35  	Must
    36  	// MustNot represents 'MUST NOT' in RFC 2119.
    37  	MustNot
    38  	// Shall represents 'SHALL' in RFC 2119.
    39  	Shall
    40  	// ShallNot represents 'SHALL NOT' in RFC 2119.
    41  	ShallNot
    42  	// Required represents 'REQUIRED' in RFC 2119.
    43  	Required
    44  )
    45  
    46  // Error represents an error with compliance level and specification reference.
    47  type Error struct {
    48  	// Level represents the RFC 2119 compliance level.
    49  	Level Level
    50  
    51  	// Reference is a URL for the violated specification requirement.
    52  	Reference string
    53  
    54  	// Err holds additional details about the violation.
    55  	Err error
    56  }
    57  
    58  // ParseLevel takes a string level and returns the RFC 2119 compliance level constant.
    59  func ParseLevel(level string) (Level, error) {
    60  	switch strings.ToUpper(level) {
    61  	case "MAY":
    62  		fallthrough
    63  	case "OPTIONAL":
    64  		return May, nil
    65  	case "SHOULD":
    66  		fallthrough
    67  	case "SHOULDNOT":
    68  		fallthrough
    69  	case "RECOMMENDED":
    70  		fallthrough
    71  	case "NOTRECOMMENDED":
    72  		return Should, nil
    73  	case "MUST":
    74  		fallthrough
    75  	case "MUSTNOT":
    76  		fallthrough
    77  	case "SHALL":
    78  		fallthrough
    79  	case "SHALLNOT":
    80  		fallthrough
    81  	case "REQUIRED":
    82  		return Must, nil
    83  	}
    84  
    85  	var l Level
    86  	return l, fmt.Errorf("%q is not a valid compliance level", level)
    87  }
    88  
    89  // String takes a RFC 2119 compliance level constant and returns a string representation.
    90  func (level Level) String() string {
    91  	switch level {
    92  	case May:
    93  		return "MAY"
    94  	case Optional:
    95  		return "OPTIONAL"
    96  	case Should:
    97  		return "SHOULD"
    98  	case ShouldNot:
    99  		return "SHOULD NOT"
   100  	case Recommended:
   101  		return "RECOMMENDED"
   102  	case NotRecommended:
   103  		return "NOT RECOMMENDED"
   104  	case Must:
   105  		return "MUST"
   106  	case MustNot:
   107  		return "MUST NOT"
   108  	case Shall:
   109  		return "SHALL"
   110  	case ShallNot:
   111  		return "SHALL NOT"
   112  	case Required:
   113  		return "REQUIRED"
   114  	}
   115  
   116  	panic(fmt.Sprintf("%d is not a valid compliance level", level))
   117  }
   118  
   119  // Error returns the error message with specification reference.
   120  func (err *Error) Error() string {
   121  	return fmt.Sprintf("%s\nRefer to: %s", err.Err.Error(), err.Reference)
   122  }