How to Marshal and Unmarshal a color palette to JSON in Go?












0















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?










share|improve this question

























  • 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
















0















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?










share|improve this question

























  • 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














0












0








0








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?










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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



















  • 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

















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












1 Answer
1






active

oldest

votes


















1














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
}





share|improve this answer
























  • Very good explanation. So you got an upvote from me.

    – apxp
    Nov 22 '18 at 6:54











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
});


}
});














draft saved

draft discarded


















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









1














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
}





share|improve this answer
























  • Very good explanation. So you got an upvote from me.

    – apxp
    Nov 22 '18 at 6:54
















1














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
}





share|improve this answer
























  • Very good explanation. So you got an upvote from me.

    – apxp
    Nov 22 '18 at 6:54














1












1








1







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
}





share|improve this answer













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
}






share|improve this answer












share|improve this answer



share|improve this answer










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



















  • 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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

Create new schema in PostgreSQL using DBeaver

Deepest pit of an array with Javascript: test on Codility

Fotorealismo