How to Marshal and Unmarshal a color palette to JSON in Go?
I want to store a custom color palette inside a JSON file, but the palette has the type color.Color
(that is an interface and not a concrete type). When I marshal the palette I get something like this:
[{"R":0,"G":0,"B":0,"A":255},{"R":0,"G":0,"B":51,"A":255}...]
The problem is, when I unmarshal that JSON the type color.Color
does not work, because Go cannot create a concrete type underneath that interface.
I have simplified my code to following example:
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
https://play.golang.org/p/QYIpJ7L1ete
Is there a simple solution or do I have to transform color.Color
to color.RGBA
?
json go
add a comment |
I want to store a custom color palette inside a JSON file, but the palette has the type color.Color
(that is an interface and not a concrete type). When I marshal the palette I get something like this:
[{"R":0,"G":0,"B":0,"A":255},{"R":0,"G":0,"B":51,"A":255}...]
The problem is, when I unmarshal that JSON the type color.Color
does not work, because Go cannot create a concrete type underneath that interface.
I have simplified my code to following example:
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
https://play.golang.org/p/QYIpJ7L1ete
Is there a simple solution or do I have to transform color.Color
to color.RGBA
?
json go
You can implement(*myT) UnmarshalJSON(b byte) error
, but you still have to decide whatcolor.Color
implementation you are going to unmarshal to.
– Tim Cooper
Nov 21 '18 at 20:00
That being said, if you are dealing with RGBA components, I would start usingcolor.RGBA
instead ofcolor.Color
.
– Tim Cooper
Nov 21 '18 at 20:01
add a comment |
I want to store a custom color palette inside a JSON file, but the palette has the type color.Color
(that is an interface and not a concrete type). When I marshal the palette I get something like this:
[{"R":0,"G":0,"B":0,"A":255},{"R":0,"G":0,"B":51,"A":255}...]
The problem is, when I unmarshal that JSON the type color.Color
does not work, because Go cannot create a concrete type underneath that interface.
I have simplified my code to following example:
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
https://play.golang.org/p/QYIpJ7L1ete
Is there a simple solution or do I have to transform color.Color
to color.RGBA
?
json go
I want to store a custom color palette inside a JSON file, but the palette has the type color.Color
(that is an interface and not a concrete type). When I marshal the palette I get something like this:
[{"R":0,"G":0,"B":0,"A":255},{"R":0,"G":0,"B":51,"A":255}...]
The problem is, when I unmarshal that JSON the type color.Color
does not work, because Go cannot create a concrete type underneath that interface.
I have simplified my code to following example:
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
https://play.golang.org/p/QYIpJ7L1ete
Is there a simple solution or do I have to transform color.Color
to color.RGBA
?
json go
json go
edited Nov 28 '18 at 15:48
Flimzy
37.9k96497
37.9k96497
asked Nov 21 '18 at 19:42
apxpapxp
1,8823920
1,8823920
You can implement(*myT) UnmarshalJSON(b byte) error
, but you still have to decide whatcolor.Color
implementation you are going to unmarshal to.
– Tim Cooper
Nov 21 '18 at 20:00
That being said, if you are dealing with RGBA components, I would start usingcolor.RGBA
instead ofcolor.Color
.
– Tim Cooper
Nov 21 '18 at 20:01
add a comment |
You can implement(*myT) UnmarshalJSON(b byte) error
, but you still have to decide whatcolor.Color
implementation you are going to unmarshal to.
– Tim Cooper
Nov 21 '18 at 20:00
That being said, if you are dealing with RGBA components, I would start usingcolor.RGBA
instead ofcolor.Color
.
– Tim Cooper
Nov 21 '18 at 20:01
You can implement
(*myT) UnmarshalJSON(b byte) error
, but you still have to decide what color.Color
implementation you are going to unmarshal to.– Tim Cooper
Nov 21 '18 at 20:00
You can implement
(*myT) UnmarshalJSON(b byte) error
, but you still have to decide what color.Color
implementation you are going to unmarshal to.– Tim Cooper
Nov 21 '18 at 20:00
That being said, if you are dealing with RGBA components, I would start using
color.RGBA
instead of color.Color
.– Tim Cooper
Nov 21 '18 at 20:01
That being said, if you are dealing with RGBA components, I would start using
color.RGBA
instead of color.Color
.– Tim Cooper
Nov 21 '18 at 20:01
add a comment |
1 Answer
1
active
oldest
votes
I would follow Tim's advice and start using color.RGBA, but if you're interested in how to implement custom UnmarshalJSON functions for your custom types I've outline the code below and here: https://play.golang.org/p/8p5a09993GV
Basically you use the UnmarshalJSON func as a middle layer to decode to the "correct" RGBA type and then do some type conversion fu to get it to become the interface you want on your custom myT type.
Again, it might be easier to use color.RGBA instead of color.Color in the overall implementation, but this is HOW you would convert it if you wanted to.
Here is a good gist that goes into the basics:
https://gist.github.com/mdwhatcott/8dd2eef0042f7f1c0cd8
A gopher academy blog post that really does some fun stuff:
https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
And a good explanation on why a struct
does not 1/1 match a interface
it might implement:
golang: slice of struct != slice of interface it implements?
package main
import (
"encoding/json"
"fmt"
"image/color"
"image/color/palette"
)
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
fmt.Println(string(t2))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
func (myt *myT) UnmarshalJSON(b byte) error {
var tempJson struct {
P color.RGBA
}
// Unmarshal to our temp struct
err := json.Unmarshal(b, &tempJson)
if err != nil {
return err
}
// convert our new friends O(n) to the interface type
newColors := make(color.Color, len(tempJson.P))
for i, v := range tempJson.P {
newColors[i] = color.Color(v)
}
myt.P = newColors
return nil
}
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419447%2fhow-to-marshal-and-unmarshal-a-color-palette-to-json-in-go%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I would follow Tim's advice and start using color.RGBA, but if you're interested in how to implement custom UnmarshalJSON functions for your custom types I've outline the code below and here: https://play.golang.org/p/8p5a09993GV
Basically you use the UnmarshalJSON func as a middle layer to decode to the "correct" RGBA type and then do some type conversion fu to get it to become the interface you want on your custom myT type.
Again, it might be easier to use color.RGBA instead of color.Color in the overall implementation, but this is HOW you would convert it if you wanted to.
Here is a good gist that goes into the basics:
https://gist.github.com/mdwhatcott/8dd2eef0042f7f1c0cd8
A gopher academy blog post that really does some fun stuff:
https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
And a good explanation on why a struct
does not 1/1 match a interface
it might implement:
golang: slice of struct != slice of interface it implements?
package main
import (
"encoding/json"
"fmt"
"image/color"
"image/color/palette"
)
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
fmt.Println(string(t2))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
func (myt *myT) UnmarshalJSON(b byte) error {
var tempJson struct {
P color.RGBA
}
// Unmarshal to our temp struct
err := json.Unmarshal(b, &tempJson)
if err != nil {
return err
}
// convert our new friends O(n) to the interface type
newColors := make(color.Color, len(tempJson.P))
for i, v := range tempJson.P {
newColors[i] = color.Color(v)
}
myt.P = newColors
return nil
}
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
add a comment |
I would follow Tim's advice and start using color.RGBA, but if you're interested in how to implement custom UnmarshalJSON functions for your custom types I've outline the code below and here: https://play.golang.org/p/8p5a09993GV
Basically you use the UnmarshalJSON func as a middle layer to decode to the "correct" RGBA type and then do some type conversion fu to get it to become the interface you want on your custom myT type.
Again, it might be easier to use color.RGBA instead of color.Color in the overall implementation, but this is HOW you would convert it if you wanted to.
Here is a good gist that goes into the basics:
https://gist.github.com/mdwhatcott/8dd2eef0042f7f1c0cd8
A gopher academy blog post that really does some fun stuff:
https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
And a good explanation on why a struct
does not 1/1 match a interface
it might implement:
golang: slice of struct != slice of interface it implements?
package main
import (
"encoding/json"
"fmt"
"image/color"
"image/color/palette"
)
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
fmt.Println(string(t2))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
func (myt *myT) UnmarshalJSON(b byte) error {
var tempJson struct {
P color.RGBA
}
// Unmarshal to our temp struct
err := json.Unmarshal(b, &tempJson)
if err != nil {
return err
}
// convert our new friends O(n) to the interface type
newColors := make(color.Color, len(tempJson.P))
for i, v := range tempJson.P {
newColors[i] = color.Color(v)
}
myt.P = newColors
return nil
}
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
add a comment |
I would follow Tim's advice and start using color.RGBA, but if you're interested in how to implement custom UnmarshalJSON functions for your custom types I've outline the code below and here: https://play.golang.org/p/8p5a09993GV
Basically you use the UnmarshalJSON func as a middle layer to decode to the "correct" RGBA type and then do some type conversion fu to get it to become the interface you want on your custom myT type.
Again, it might be easier to use color.RGBA instead of color.Color in the overall implementation, but this is HOW you would convert it if you wanted to.
Here is a good gist that goes into the basics:
https://gist.github.com/mdwhatcott/8dd2eef0042f7f1c0cd8
A gopher academy blog post that really does some fun stuff:
https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
And a good explanation on why a struct
does not 1/1 match a interface
it might implement:
golang: slice of struct != slice of interface it implements?
package main
import (
"encoding/json"
"fmt"
"image/color"
"image/color/palette"
)
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
fmt.Println(string(t2))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
func (myt *myT) UnmarshalJSON(b byte) error {
var tempJson struct {
P color.RGBA
}
// Unmarshal to our temp struct
err := json.Unmarshal(b, &tempJson)
if err != nil {
return err
}
// convert our new friends O(n) to the interface type
newColors := make(color.Color, len(tempJson.P))
for i, v := range tempJson.P {
newColors[i] = color.Color(v)
}
myt.P = newColors
return nil
}
I would follow Tim's advice and start using color.RGBA, but if you're interested in how to implement custom UnmarshalJSON functions for your custom types I've outline the code below and here: https://play.golang.org/p/8p5a09993GV
Basically you use the UnmarshalJSON func as a middle layer to decode to the "correct" RGBA type and then do some type conversion fu to get it to become the interface you want on your custom myT type.
Again, it might be easier to use color.RGBA instead of color.Color in the overall implementation, but this is HOW you would convert it if you wanted to.
Here is a good gist that goes into the basics:
https://gist.github.com/mdwhatcott/8dd2eef0042f7f1c0cd8
A gopher academy blog post that really does some fun stuff:
https://blog.gopheracademy.com/advent-2016/advanced-encoding-decoding/
And a good explanation on why a struct
does not 1/1 match a interface
it might implement:
golang: slice of struct != slice of interface it implements?
package main
import (
"encoding/json"
"fmt"
"image/color"
"image/color/palette"
)
type myT struct {
P color.Color
}
func main() {
t := myT{palette.WebSafe}
b, err := json.Marshal(t)
e("json.Marshal", err)
t2 := myT{}
err = json.Unmarshal(b, &t2)
e("json.Unmarshal", err)
fmt.Println(string(b))
fmt.Println(string(t2))
}
func e(s string, err error) {
if err != nil {
fmt.Println(s, err)
}
}
func (myt *myT) UnmarshalJSON(b byte) error {
var tempJson struct {
P color.RGBA
}
// Unmarshal to our temp struct
err := json.Unmarshal(b, &tempJson)
if err != nil {
return err
}
// convert our new friends O(n) to the interface type
newColors := make(color.Color, len(tempJson.P))
for i, v := range tempJson.P {
newColors[i] = color.Color(v)
}
myt.P = newColors
return nil
}
answered Nov 21 '18 at 20:24
Christopher PhillipsChristopher Phillips
11615
11615
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
add a comment |
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
Very good explanation. So you got an upvote from me.
– apxp
Nov 22 '18 at 6:54
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419447%2fhow-to-marshal-and-unmarshal-a-color-palette-to-json-in-go%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You can implement
(*myT) UnmarshalJSON(b byte) error
, but you still have to decide whatcolor.Color
implementation you are going to unmarshal to.– Tim Cooper
Nov 21 '18 at 20:00
That being said, if you are dealing with RGBA components, I would start using
color.RGBA
instead ofcolor.Color
.– Tim Cooper
Nov 21 '18 at 20:01