1// Copyright The OpenTelemetry Authors 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 codes // import "go.opentelemetry.io/otel/codes" 16 17import ( 18 "encoding/json" 19 "fmt" 20 "strconv" 21) 22 23const ( 24 // Unset is the default status code. 25 Unset Code = 0 26 // Error indicates the operation contains an error. 27 Error Code = 1 28 // Ok indicates operation has been validated by an Application developers 29 // or Operator to have completed successfully, or contain no error. 30 Ok Code = 2 31 32 maxCode = 3 33) 34 35// Code is an 32-bit representation of a status state. 36type Code uint32 37 38var codeToStr = map[Code]string{ 39 Unset: "Unset", 40 Error: "Error", 41 Ok: "Ok", 42} 43 44var strToCode = map[string]Code{ 45 `"Unset"`: Unset, 46 `"Error"`: Error, 47 `"Ok"`: Ok, 48} 49 50// String returns the Code as a string. 51func (c Code) String() string { 52 return codeToStr[c] 53} 54 55// UnmarshalJSON unmarshals b into the Code. 56// 57// This is based on the functionality in the gRPC codes package: 58// https://github.com/grpc/grpc-go/blob/bb64fee312b46ebee26be43364a7a966033521b1/codes/codes.go#L218-L244 59func (c *Code) UnmarshalJSON(b []byte) error { 60 // From json.Unmarshaler: By convention, to approximate the behavior of 61 // Unmarshal itself, Unmarshalers implement UnmarshalJSON([]byte("null")) as 62 // a no-op. 63 if string(b) == "null" { 64 return nil 65 } 66 if c == nil { 67 return fmt.Errorf("nil receiver passed to UnmarshalJSON") 68 } 69 70 var x interface{} 71 if err := json.Unmarshal(b, &x); err != nil { 72 return err 73 } 74 switch x.(type) { 75 case string: 76 if jc, ok := strToCode[string(b)]; ok { 77 *c = jc 78 return nil 79 } 80 return fmt.Errorf("invalid code: %q", string(b)) 81 case float64: 82 if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { 83 if ci >= maxCode { 84 return fmt.Errorf("invalid code: %q", ci) 85 } 86 87 *c = Code(ci) 88 return nil 89 } 90 return fmt.Errorf("invalid code: %q", string(b)) 91 default: 92 return fmt.Errorf("invalid code: %q", string(b)) 93 } 94} 95 96// MarshalJSON returns c as the JSON encoding of c. 97func (c *Code) MarshalJSON() ([]byte, error) { 98 if c == nil { 99 return []byte("null"), nil 100 } 101 str, ok := codeToStr[*c] 102 if !ok { 103 return nil, fmt.Errorf("invalid code: %d", *c) 104 } 105 return []byte(fmt.Sprintf("%q", str)), nil 106} 107