Swag: Support custome type field

Created on 7 Jul 2018  路  19Comments  路  Source: swaggo/swag

for https://github.com/swaggo/swag/issues/158

Write development policy.

Most helpful comment

i'm planning for custom type solution with the following code.

package main

import (
    "errors"
    "fmt"
    "reflect"
    "time"
)

type Investment struct {
    Price  float64
    Str    *A
    Map    B
    Time   time.Time
    Rating int64
}

type A string
type B map[string]string

func main() {
    a := A("A")
    inv := Investment{Price: 534.432, Str: &a, Rating: 4, Map: map[string]string{}, Time: time.Now()}
    parseType(inv.Price, inv.Str, inv.Rating, inv.Map, inv.Time)
}

func parseType(values ...interface{}) {
    for _, value := range values {
        rv := reflect.ValueOf(value)
        typeName, err := parseKind(rv.Kind())
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        typeName, err = getPrimitiveType(value)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        typeName, err = getPointerPrimitiveType(value)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        fmt.Println("--------------------")
    }
}

func getPrimitiveType(v interface{}) (string, error) {
    return parseKind(reflect.ValueOf(v).Kind())
}

func getPointerPrimitiveType(v interface{}) (string, error) {
    return parseKind(reflect.Indirect(reflect.ValueOf(v)).Kind())
}

var ErrUnrecognizedType = errors.New("unrecognized type")

func parseKind(kind reflect.Kind) (string, error) {
    switch kind {
    case reflect.Bool:
        return "Bool", nil
    case reflect.Int:
        return "Int", nil
    case reflect.Int8:
        return "Int8", nil
    case reflect.Int16:
        return "Int16", nil
    case reflect.Int32:
        return "Int32", nil
    case reflect.Int64:
        return "Int64", nil
    case reflect.Uint:
        return "Uint", nil
    case reflect.Uint8:
        return "Uint8", nil
    case reflect.Uint16:
        return "Uint16", nil
    case reflect.Uint32:
        return "Uint32", nil
    case reflect.Uint64:
        return "Uint64", nil
    case reflect.Uintptr:
        return "Uintptr", nil
    case reflect.Float32:
        return "Float32", nil
    case reflect.Float64:
        return "Float64", nil
    case reflect.Complex64:
        return "Complex64", nil
    case reflect.Complex128:
        return "Complex128", nil
    case reflect.Array:
        return "Array", nil
    case reflect.Chan:
        return "Chan", nil
    case reflect.Func:
        return "Func", nil
    case reflect.Interface:
        return "Interface", nil
    case reflect.Map:
        return "Map", nil
    case reflect.Ptr:
        return "Ptr", nil
    case reflect.Slice:
        return "Slice", nil
    case reflect.String:
        return "String", nil
    case reflect.Struct:
        return "Struct", nil
    case reflect.UnsafePointer:
        return "UnsafePointer", nil
    default:
        return "Unrecoginized", ErrUnrecognizedType
    }
}

All 19 comments

1. Add test for getPropertyName

https://github.com/swaggo/swag/blob/015cc4041d62df0b61cb051d96a3820dd9fb0d65/property.go#L42

2. Add cmd option for customeType

$ swag init --customeType userDifine.so

.so is plugin prepared by the standard package of go.
example

How to customeType.

  1. Define type map.
var customeTypeMap = map[string]string{
    "customeField": "string",
    "customeField2": "number",
}

var customePkgAndTypeMap = map[string]string{
    "pkg.customeField": "string",
    "pkg2.customeField": "number",
}
  1. Generate .so and do swag init
$ go build -buildmode=plugin -o typeDefine.so typeDefine.go
$ swag init --customeType userDifine.so

This approach was useless. I added only the test for property.

I want to resolve the cross package before doing this. It is bottleneck.

In order to process cross packages, it is necessary to resolve all type information first. In other words, it is completely different from the existing approach. I will consider whether I can do it or not.

-buildmode=plugin not supported on darwin/amd64

-buildmode=plugin not supported on darwin/amd64

Oh

i'm planning for custom type solution with the following code.

package main

import (
    "errors"
    "fmt"
    "reflect"
    "time"
)

type Investment struct {
    Price  float64
    Str    *A
    Map    B
    Time   time.Time
    Rating int64
}

type A string
type B map[string]string

func main() {
    a := A("A")
    inv := Investment{Price: 534.432, Str: &a, Rating: 4, Map: map[string]string{}, Time: time.Now()}
    parseType(inv.Price, inv.Str, inv.Rating, inv.Map, inv.Time)
}

func parseType(values ...interface{}) {
    for _, value := range values {
        rv := reflect.ValueOf(value)
        typeName, err := parseKind(rv.Kind())
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        typeName, err = getPrimitiveType(value)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        typeName, err = getPointerPrimitiveType(value)
        if err != nil {
            fmt.Println(err)
        }
        fmt.Printf("Type: %s and Kind %s\n", rv.Type(), typeName)
        fmt.Println("--------------------")
    }
}

func getPrimitiveType(v interface{}) (string, error) {
    return parseKind(reflect.ValueOf(v).Kind())
}

func getPointerPrimitiveType(v interface{}) (string, error) {
    return parseKind(reflect.Indirect(reflect.ValueOf(v)).Kind())
}

var ErrUnrecognizedType = errors.New("unrecognized type")

func parseKind(kind reflect.Kind) (string, error) {
    switch kind {
    case reflect.Bool:
        return "Bool", nil
    case reflect.Int:
        return "Int", nil
    case reflect.Int8:
        return "Int8", nil
    case reflect.Int16:
        return "Int16", nil
    case reflect.Int32:
        return "Int32", nil
    case reflect.Int64:
        return "Int64", nil
    case reflect.Uint:
        return "Uint", nil
    case reflect.Uint8:
        return "Uint8", nil
    case reflect.Uint16:
        return "Uint16", nil
    case reflect.Uint32:
        return "Uint32", nil
    case reflect.Uint64:
        return "Uint64", nil
    case reflect.Uintptr:
        return "Uintptr", nil
    case reflect.Float32:
        return "Float32", nil
    case reflect.Float64:
        return "Float64", nil
    case reflect.Complex64:
        return "Complex64", nil
    case reflect.Complex128:
        return "Complex128", nil
    case reflect.Array:
        return "Array", nil
    case reflect.Chan:
        return "Chan", nil
    case reflect.Func:
        return "Func", nil
    case reflect.Interface:
        return "Interface", nil
    case reflect.Map:
        return "Map", nil
    case reflect.Ptr:
        return "Ptr", nil
    case reflect.Slice:
        return "Slice", nil
    case reflect.String:
        return "String", nil
    case reflect.Struct:
        return "Struct", nil
    case reflect.UnsafePointer:
        return "UnsafePointer", nil
    default:
        return "Unrecoginized", ErrUnrecognizedType
    }
}

Any updates on this? Can i help?

I can't take the free time now. Do you try done for this issue?

I am gonna try to take a stab on it. I'll let you know once i start working on it

@pei0804 For your solution above? how were you planning to grab the values and use reflect ?

What do you think about this https://github.com/abdulito/swag/commit/b957efa1582f7d09f4baf20679d2cc008857da28
?

This deals with custom type fields that are based off of primitive types

@pei0804 please see above

Actually made some updates to allow an Array of custom types

https://github.com/swaggo/swag/compare/master...abdulito:custom-primitive-types?expand=1

So this covers two cases:

type Account struct {
    ID AccountID
    Names []AccountName
}

type AccountID string
type AccountName string

I saw it now.
Sound good.

I also want some tests.
You can add it near here.
https://github.com/swaggo/swag/blob/c62a15db840809c8003bbd37f76966a5782282dc/testdata/pet/web/handler.go#L20

And please PR this wonderful code.

I added the tests somewhere else but let me know if you want me to move it to where you pointed me at.

@abdulito fixed this case!

198

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dz0ny picture dz0ny  路  5Comments

welenlin picture welenlin  路  3Comments

hoangtuan151 picture hoangtuan151  路  4Comments

wingsofovnia picture wingsofovnia  路  3Comments

piwan picture piwan  路  6Comments