Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: encoding/json: simpler way to decode any basic type into string #24406

Closed
byrnedo opened this issue Mar 15, 2018 · 7 comments
Closed
Labels
FrozenDueToAge Proposal WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Milestone

Comments

@byrnedo
Copy link

byrnedo commented Mar 15, 2018

There are a few options for 'forcing' the decoded type of a field into a string:

I believe it would be very useful to have a way of decoding the following into strings:

  • int*
  • boolean
  • maybe more?

Perhaps a force flag?

type Test struct {
    MyField string `json:",force"`
}

What version of Go are you using (go version)?

go1.9 linux/amd64

Does this issue reproduce with the latest release?

yes

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/donal/.gvm/pkgsets/go1.9/global"
GORACE=""
GOROOT="/home/donal/.gvm/gos/go1.9"
GOTOOLDIR="/home/donal/.gvm/gos/go1.9/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build625506250=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

@mvdan
Copy link
Member

mvdan commented Mar 15, 2018

Use interface{} type and do assertion later

Could you clarify why this is not an acceptable option? It seems to me like the cleanest and easiest.

@mvdan mvdan changed the title Simpler way to json decode any basic type into string encoding/json: simpler way to decode any basic type into string Mar 15, 2018
@mvdan
Copy link
Member

mvdan commented Mar 15, 2018

Also, why is converting all basic types into string useful? If we were to add that feature into the JSON package, it would be natural to also expect it to magically convert strings to ints, ints to floats, string to bool... It sounds to me like this would add a lot of glue code to the json package.

@byrnedo
Copy link
Author

byrnedo commented Mar 15, 2018

@mvdan I definitely don't think it would be good to do all that magical conversion. I'm coming from the point of view that the data is human readable text to begin with.

My scenario is a 3rd party api that sends fields that are supposed to be strings as both quoted and unquoted.
{"foo": 234} or {"foo": "234"}

I feel it takes a lot of boilerplate to populate a struct with plain string fields since I'll have to have 2 versions of every response format they send, one with interfaces or a custom type for internal unmarshalling, and one with normal primitive strings.

Edit:

I suppose if I could do a type conversion between both structs it wouldn't be too bad but that doesn't seem to work, unless I'm missing something? : https://goplay.space/#uOIJgVeLbp2

@mvdan
Copy link
Member

mvdan commented Mar 15, 2018

Ah, I see that you're after the original bytes, not the values converted to strings.

Seems to me like https://golang.org/pkg/encoding/json/#RawMessage would fit the job nicely. It wouldn't limit the accepted values to just basic types - for example, it would also allow objects - but you can likely add your own restrictions by disallowing a leading { byte and so on.

@byrnedo
Copy link
Author

byrnedo commented Mar 15, 2018

Yeah, RawMessage could work, I'm still back to a lot of boilerplate to convert that into a 'convenient' struct format, a la:

type Inconvenient struct {
    Foo json.RawMessage
    Bar json.RawMessage
}

type Convenient struct {
    Foo string
    Bar string
    ....
}
...
inconvenient := &Inconvenient{}

<some unmarshal or decode here>

c := &Convenient{
    Foo: string(inconvenient.Foo),
    Bar: string(inconvenient.Bar),
...
}

Edit:
I suppose I could generate some 'Inconvenient' structs using templating for this case. Still, since the underlying fields can be easily expressed as text if feels like a lot of hoops just to get the data as string.

@andybons andybons changed the title encoding/json: simpler way to decode any basic type into string proposal: encoding/json: simpler way to decode any basic type into string Mar 15, 2018
@gopherbot gopherbot added this to the Proposal milestone Mar 15, 2018
@andybons
Copy link
Member

It seems like you’ve landed on a solution (albeit one with more boilerplate than you’d prefer). That said, if you’d like to continue with this request, we would need more motivating examples and a concrete proposal.

Let us know if you have any questions. Thanks.

@andybons andybons added the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Mar 15, 2018
@gopherbot
Copy link

Timed out in state WaitingForInfo. Closing.

(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)

@golang golang locked and limited conversation to collaborators Apr 15, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge Proposal WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided.
Projects
None yet
Development

No branches or pull requests

4 participants