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

Comments

Projects
None yet
4 participants
@byrnedo
Copy link

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Author

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

This comment has been minimized.

Copy link
Member

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

This comment has been minimized.

Copy link
Author

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

@gopherbot gopherbot added the Proposal label Mar 15, 2018

@andybons

This comment has been minimized.

Copy link
Member

commented Mar 15, 2018

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.

@gopherbot

This comment has been minimized.

Copy link

commented Apr 15, 2018

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.)

@gopherbot gopherbot closed this Apr 15, 2018

@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.
You can’t perform that action at this time.