Home > database >  Check if any variable conforms any interface using generics in Go
Check if any variable conforms any interface using generics in Go

Time:04-03

I am writing an API using go-fiber, and I want to check, if passed JSON conforms an interface that I want to see. So I decided to use 1.18's feature - generics. Here is what I did, but it does not work due to type problem.

func checkDataConformsInterface[I any](format I, c *fiber.Ctx) (I, error) {
    if err := c.BodyParser(&format); err != nil {
        return nil, err
    }

    return c.JSON(format), nil
}

The errors say

src/endpoints/v1/tasks.go:36:10: cannot use nil as I value in return statement
src/endpoints/v1/tasks.go:39:9: cannot use c.JSON(format) (value of type error) as type I in return statement

And I want to call the function like this:

type CreateTaskDF struct {
    Target string `json:"target"`
    Deepness int `json:"deepness"`
}

func CreateTask(c *fiber.Ctx) error {
    data, err := checkDataConformsInterface[CreateTaskDF](&CreateTaskDF{}, c)
    if err != nil {
        log.Fatal(err)
    }
    // work with data here
    ...

How should I convert the return value in the function to make it work? Thanks!

CodePudding user response:

So I came up with the following solution

func checkDataConformsInterface[I any](format *I, c *fiber.Ctx) error {
    if err := c.BodyParser(&format); err != nil {
        return err
    }
    err := c.JSON(format)
    if err != nil {
        return err
    }

    return nil
}

which can be called like

func CreateTask(c *fiber.Ctx) error {
    parsedData := CreateTaskDF{}
    err := checkDataConformsInterface[CreateTaskDF](&parsedData, c)
    if err != nil {
        c.SendStatus(400)
        return c.SendString("Wrong data")
    }

Please, point me the problems if any

CodePudding user response:

It probably could work like this(if you do not consider any lib-based payload validators, which exist in almost every golang routing lib or web framework). So, to just validate your data you can use this:

func checkDataConformsInterface[I any](format I, c *fiber.Ctx) bool {
    if err := c.BodyParser(&format); err != nil {
        return false
    }
    return true
}
  • Related