github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/apijson/tag.go (about)

     1  package apijson
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  )
     7  
     8  const apiStructTag = "api"
     9  const jsonStructTag = "json"
    10  const formatStructTag = "format"
    11  const defaultStructTag = "default"
    12  
    13  type parsedStructTag struct {
    14  	name         string
    15  	required     bool
    16  	extras       bool
    17  	metadata     bool
    18  	inline       bool
    19  	defaultValue any
    20  }
    21  
    22  func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) {
    23  	raw, ok := field.Tag.Lookup(jsonStructTag)
    24  	if !ok {
    25  		return tag, ok
    26  	}
    27  	parts := strings.Split(raw, ",")
    28  	if len(parts) == 0 {
    29  		return tag, false
    30  	}
    31  	tag.name = parts[0]
    32  	for _, part := range parts[1:] {
    33  		switch part {
    34  		case "required":
    35  			tag.required = true
    36  		case "extras":
    37  			tag.extras = true
    38  		case "metadata":
    39  			tag.metadata = true
    40  		case "inline":
    41  			tag.inline = true
    42  		}
    43  	}
    44  
    45  	// the `api` struct tag is only used alongside `json` for custom behaviour
    46  	parseApiStructTag(field, &tag)
    47  	parseDefaultStructTag(field, &tag)
    48  	return tag, ok
    49  }
    50  
    51  func parseDefaultStructTag(field reflect.StructField, tag *parsedStructTag) {
    52  	if field.Type.Kind() != reflect.String {
    53  		// Only strings are currently supported
    54  		return
    55  	}
    56  
    57  	raw, ok := field.Tag.Lookup(defaultStructTag)
    58  	if !ok {
    59  		return
    60  	}
    61  	tag.defaultValue = raw
    62  }
    63  
    64  func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) {
    65  	raw, ok := field.Tag.Lookup(apiStructTag)
    66  	if !ok {
    67  		return
    68  	}
    69  	parts := strings.Split(raw, ",")
    70  	for _, part := range parts {
    71  		switch part {
    72  		case "extrafields":
    73  			tag.extras = true
    74  		case "required":
    75  			tag.required = true
    76  		case "metadata":
    77  			tag.metadata = true
    78  		}
    79  	}
    80  }
    81  
    82  func parseFormatStructTag(field reflect.StructField) (format string, ok bool) {
    83  	format, ok = field.Tag.Lookup(formatStructTag)
    84  	return format, ok
    85  }