processOutputType validates the output type, extracts possible responses and defines them on the operation op.
(outputType reflect.Type, op *Operation, registry Registry)
| 1505 | // processOutputType validates the output type, extracts possible responses and |
| 1506 | // defines them on the operation op. |
| 1507 | func processOutputType(outputType reflect.Type, op *Operation, registry Registry) (*findResult[*headerInfo], int, int, bool) { |
| 1508 | outStatusIndex := -1 |
| 1509 | if f, ok := outputType.FieldByName("Status"); ok { |
| 1510 | outStatusIndex = f.Index[0] |
| 1511 | if f.Type.Kind() != reflect.Int { |
| 1512 | panic("status field must be an int") |
| 1513 | } |
| 1514 | // TODO: enum tag? |
| 1515 | // TODO: register each of the possible responses with the right model |
| 1516 | // and headers down below. |
| 1517 | } |
| 1518 | outBodyIndex := -1 |
| 1519 | outBodyFunc := false |
| 1520 | if f, ok := outputType.FieldByName("Body"); ok { |
| 1521 | outBodyIndex = f.Index[0] |
| 1522 | if f.Type.Kind() == reflect.Func { |
| 1523 | outBodyFunc = true |
| 1524 | |
| 1525 | if f.Type != bodyCallbackType { |
| 1526 | panic("body field must be a function with signature func(huma.Context)") |
| 1527 | } |
| 1528 | } |
| 1529 | status := op.DefaultStatus |
| 1530 | if status == 0 { |
| 1531 | status = http.StatusOK |
| 1532 | } |
| 1533 | statusStr := strconv.Itoa(status) |
| 1534 | if op.Responses[statusStr] == nil { |
| 1535 | op.Responses[statusStr] = &Response{} |
| 1536 | } |
| 1537 | if op.Responses[statusStr].Description == "" { |
| 1538 | op.Responses[statusStr].Description = http.StatusText(status) |
| 1539 | } |
| 1540 | if op.Responses[statusStr].Headers == nil { |
| 1541 | op.Responses[statusStr].Headers = map[string]*Param{} |
| 1542 | } |
| 1543 | if !outBodyFunc { |
| 1544 | hint := getHint(outputType, f.Name, op.OperationID+"Response") |
| 1545 | if nameHint := f.Tag.Get("nameHint"); nameHint != "" { |
| 1546 | hint = nameHint |
| 1547 | } |
| 1548 | outSchema := SchemaFromField(registry, f, hint) |
| 1549 | if op.Responses[statusStr].Content == nil { |
| 1550 | op.Responses[statusStr].Content = map[string]*MediaType{} |
| 1551 | } |
| 1552 | // Check if the field's type implements ContentTypeFilter |
| 1553 | contentType := "application/json" |
| 1554 | if reflect.PointerTo(f.Type).Implements(contentTypeFilterType) { |
| 1555 | instance := reflect.New(f.Type).Interface().(ContentTypeFilter) |
| 1556 | contentType = instance.ContentType(contentType) |
| 1557 | } |
| 1558 | if len(op.Responses[statusStr].Content) == 0 { |
| 1559 | op.Responses[statusStr].Content[contentType] = &MediaType{} |
| 1560 | } |
| 1561 | if op.Responses[statusStr].Content[contentType] != nil && op.Responses[statusStr].Content[contentType].Schema == nil { |
| 1562 | op.Responses[statusStr].Content[contentType].Schema = outSchema |
| 1563 | } |
| 1564 | } |
no test coverage detected
searching dependent graphs…