github.com/wangyougui/gf/v2@v2.6.5/net/goai/goai_response_ref.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/wangyougui/gf.
     6  
     7  package goai
     8  
     9  import (
    10  	"reflect"
    11  
    12  	"github.com/wangyougui/gf/v2/internal/json"
    13  	"github.com/wangyougui/gf/v2/os/gstructs"
    14  	"github.com/wangyougui/gf/v2/text/gstr"
    15  )
    16  
    17  type ResponseRef struct {
    18  	Ref   string
    19  	Value *Response
    20  }
    21  
    22  // Responses is specified by OpenAPI/Swagger 3.0 standard.
    23  type Responses map[string]ResponseRef
    24  
    25  func (r ResponseRef) MarshalJSON() ([]byte, error) {
    26  	if r.Ref != "" {
    27  		return formatRefToBytes(r.Ref), nil
    28  	}
    29  	return json.Marshal(r.Value)
    30  }
    31  
    32  type getResponseSchemaRefInput struct {
    33  	BusinessStructName      string      // The business struct name.
    34  	CommonResponseObject    interface{} // Common response object.
    35  	CommonResponseDataField string      // Common response data field.
    36  }
    37  
    38  func (oai *OpenApiV3) getResponseSchemaRef(in getResponseSchemaRefInput) (*SchemaRef, error) {
    39  	if in.CommonResponseObject == nil {
    40  		return &SchemaRef{
    41  			Ref: in.BusinessStructName,
    42  		}, nil
    43  	}
    44  
    45  	var (
    46  		dataFieldsPartsArray       = gstr.Split(in.CommonResponseDataField, ".")
    47  		bizResponseStructSchemaRef = oai.Components.Schemas.Get(in.BusinessStructName)
    48  		schema, err                = oai.structToSchema(in.CommonResponseObject)
    49  	)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	if in.CommonResponseDataField == "" && bizResponseStructSchemaRef != nil {
    54  		// Normal response.
    55  		bizResponseStructSchemaRef.Value.Properties.Iterator(func(key string, ref SchemaRef) bool {
    56  			schema.Properties.Set(key, ref)
    57  			return true
    58  		})
    59  	} else {
    60  		// Common response.
    61  		structFields, _ := gstructs.Fields(gstructs.FieldsInput{
    62  			Pointer:         in.CommonResponseObject,
    63  			RecursiveOption: gstructs.RecursiveOptionEmbeddedNoTag,
    64  		})
    65  		for _, structField := range structFields {
    66  			var fieldName = structField.Name()
    67  			if jsonName := structField.TagJsonName(); jsonName != "" {
    68  				fieldName = jsonName
    69  			}
    70  			switch len(dataFieldsPartsArray) {
    71  			case 1:
    72  				if structField.Name() == dataFieldsPartsArray[0] {
    73  					if err = oai.tagMapToSchema(structField.TagMap(), bizResponseStructSchemaRef.Value); err != nil {
    74  						return nil, err
    75  					}
    76  					schema.Properties.Set(fieldName, *bizResponseStructSchemaRef)
    77  					break
    78  				}
    79  			default:
    80  				// Recursively creating common response object schema.
    81  				if structField.Name() == dataFieldsPartsArray[0] {
    82  					var structFieldInstance = reflect.New(structField.Type().Type).Elem()
    83  					schemaRef, err := oai.getResponseSchemaRef(getResponseSchemaRefInput{
    84  						BusinessStructName:      in.BusinessStructName,
    85  						CommonResponseObject:    structFieldInstance,
    86  						CommonResponseDataField: gstr.Join(dataFieldsPartsArray[1:], "."),
    87  					})
    88  					if err != nil {
    89  						return nil, err
    90  					}
    91  					schema.Properties.Set(fieldName, *schemaRef)
    92  					break
    93  				}
    94  			}
    95  		}
    96  	}
    97  
    98  	return &SchemaRef{
    99  		Value: schema,
   100  	}, nil
   101  }