github.com/jasonfriedland/openapi2proto@v0.2.1/openapi/schema.go (about)

     1  package openapi
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  
     7  	"github.com/pkg/errors"
     8  )
     9  
    10  // Using reflect is reaaaaaal slow, so we should really be generating
    11  // code, but I'm going to punt it for now
    12  var schemaProxyType reflect.Type
    13  
    14  func init() {
    15  	rt := reflect.TypeOf(Schema{})
    16  	var fields []reflect.StructField
    17  	for i := 0; i < rt.NumField(); i++ {
    18  		ft := rt.Field(i)
    19  		if ft.PkgPath != "" {
    20  			continue
    21  		}
    22  		fields = append(fields, ft)
    23  	}
    24  
    25  	schemaProxyType = reflect.StructOf(fields)
    26  }
    27  
    28  // UnmarshalJSON decodes JSON data into a Schema
    29  func (s *Schema) UnmarshalJSON(data []byte) error {
    30  	var b bool
    31  	if err := json.Unmarshal(data, &b); err == nil {
    32  		if b {
    33  			*s = Schema{}
    34  		} else {
    35  			*s = Schema{isNil: true}
    36  		}
    37  		return nil
    38  	}
    39  
    40  	nv := reflect.New(schemaProxyType)
    41  
    42  	if err := json.Unmarshal(data, nv.Interface()); err != nil {
    43  		return errors.Wrap(err, `failed to unmarshal JSON`)
    44  	}
    45  
    46  	nv = nv.Elem()
    47  	sv := reflect.ValueOf(s).Elem()
    48  	for i := 0; i < nv.NumField(); i++ {
    49  		ft := nv.Type().Field(i)
    50  		fv := nv.Field(i)
    51  		sv.FieldByName(ft.Name).Set(fv)
    52  	}
    53  
    54  	return nil
    55  }
    56  
    57  // IsNil returns true if it's nil schema (e.g.: `additionalProperties: false`)
    58  func (s Schema) IsNil() bool {
    59  	return s.isNil
    60  }
    61  
    62  // UnmarshalJSON decodes JSON data into a SchemaType
    63  func (s *SchemaType) UnmarshalJSON(data []byte) error {
    64  	var str string
    65  	if err := json.Unmarshal(data, &str); err == nil {
    66  		*s = []string{str}
    67  		return nil
    68  	}
    69  
    70  	var l []string
    71  	if err := json.Unmarshal(data, &l); err == nil {
    72  		*s = l
    73  		return nil
    74  	}
    75  
    76  	return errors.Errorf(`invalid type '%s'`, data)
    77  }
    78  
    79  // UnmarshalYAML decodes YAML data into a SchemaType
    80  func (s *SchemaType) UnmarshalYAML(unmarshal func(interface{}) error) error {
    81  	var str string
    82  	if err := unmarshal(&str); err == nil {
    83  		if str == "" {
    84  			*s = []string(nil)
    85  		} else {
    86  			*s = []string{str}
    87  		}
    88  		return nil
    89  	}
    90  
    91  	var l []string
    92  	if err := unmarshal(&l); err == nil {
    93  		*s = l
    94  		return nil
    95  	}
    96  
    97  	return errors.New(`invalid type for schema type`)
    98  }
    99  
   100  // Empty returns true if there was no type specified
   101  func (s *SchemaType) Empty() bool {
   102  	return len(*s) == 0
   103  }
   104  
   105  // Contains returns true if the specified type is listed within
   106  // the list of schema types
   107  func (s *SchemaType) Contains(t string) bool {
   108  	for _, v := range *s {
   109  		if v == t {
   110  			return true
   111  		}
   112  	}
   113  	return false
   114  }
   115  
   116  // Len returns the number of types listed under this SchemaType
   117  func (s *SchemaType) Len() int {
   118  	return len(*s)
   119  }
   120  
   121  // First returns the first type listed under this SchemaType
   122  func (s *SchemaType) First() string {
   123  	if !s.Empty() {
   124  		return (*s)[0]
   125  	}
   126  	return ""
   127  }
   128