nikicc
nikicc

Reputation: 638

Recursive type conversion between two Go structs with parallel structure

Short Question:

Is it possible to do type conversion in Go between two different structs, if both of those structs contain fields that are also struct (different types, but compatible)? See Example 2 below for what I'd like to achieve.

I suspect this is not possible since the types of A and B are not identical any more, but am wondering if this could somehow be achieved with type conversion?

Background:

I'm working on a REST API (let's call it X) that is mostly a tiny wrapper around another REST API (Y). One of the endpoints I'm building in X, I'm mostly just exposing the response from Y, but I do need to rename the JSON field names. If the response from Y is one-level (i.e. without nested structs) I can do the renaming by type conversion as shown in Example 1. However, if the response from Y contains nested structs, the type conversion does not seem to work any more, assuming we want to rename fields on both levels (i.e. on the parent and the child). See Example 2.

For example, I'd like to map the JSON from Y:

{
    "Num": 1,
    "Child": {
        "Num": 2
    }

}

to a response in X:

{
    "NumB": 1,
    "Child": {
        "NumB": 2
    }

}

I know there are also other ways on how the JSON field names could be renamed, but I'm just wondering it something like this could be achieved with type conversion.

Example 1 (conversion passes without issues):

package main

import "fmt"

func main() {
    type A struct {
        Num int
    }

    type B struct {
        Num int `json:"NumB"`
    }

    a := A{1}
    b := B(a) // works

    fmt.Println(b)
}

Example 2 (does not compile):

package main

import "fmt"

func main() {
    type AC struct {
        Num int
    }

    type A struct {
        Num   int
        Child AC
    }

    type BC struct {
        Num int `json:"NumB"`
    }

    type B struct {
        Num   int `json:"NumB"`
        Child BC  `json:"Child"`
    }

    a := A{1, AC{2}}
    b := B(a) // does not work

    fmt.Println(b)
}

I get the following error:

./main.go:25:8: cannot convert a (type A) to type B

Upvotes: 0

Views: 657

Answers (1)

nikicc
nikicc

Reputation: 638

According to @JimB comment: such conversions are not supported by the language (as least not in Go 1.15).

Some of the alternatives for mapping such structs:

Upvotes: 0

Related Questions