/interface_marshalling.go Secret
Created
March 21, 2021 07:18
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Copyright (c) 2021, Alfonso de la Rocha | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. */ | |
package main | |
import ( | |
"fmt" | |
"encoding/json" | |
) | |
// Object Structs | |
type Node interface{ | |
Print() | |
} | |
type Pair struct { | |
Key Node `json:"key"` | |
Value Node `json:"value"` | |
} | |
type Pairs []Pair | |
type String struct { | |
Value string | |
} | |
type Int struct { | |
Value int | |
} | |
func (s String) Print(){ | |
fmt.Println(s.Value) | |
} | |
// MarshalType to strongly type json | |
type MarshalType int | |
const ( | |
StringType = iota | |
IntType | |
) | |
func (i Int) Print(){ | |
fmt.Println(i.Value) | |
} | |
// Custom Marshal Functions | |
func (s String) MarshalJSON() (bdata []byte, e error) { | |
// Temporal type to avoid recursion | |
type tmp String | |
ts := tmp(s) | |
c := struct { | |
Type MarshalType `json:"type"` | |
Value tmp `json:"value"` | |
}{Type: StringType, Value: ts} | |
return json.Marshal(&c) | |
} | |
func (i Int) MarshalJSON() (bdata []byte, e error) { | |
// Temporal type to avoid recursion | |
type tmp Int | |
ts := tmp(i) | |
c := struct { | |
Type MarshalType `json:"type"` | |
Value tmp `json:"value"` | |
}{Type: IntType, Value: ts} | |
return json.Marshal(&c) | |
} | |
// Unmarshaling Pair types | |
func UnmarshalType(tp MarshalType, b []byte) (Node, error) { | |
switch tp { | |
case StringType: | |
var n String | |
err := json.Unmarshal(b, &n) | |
if err != nil { | |
return nil, err | |
} | |
return n, nil | |
case IntType: | |
var n Int | |
err := json.Unmarshal(b, &n) | |
if err != nil { | |
return nil, err | |
} | |
return n, nil | |
} | |
return nil, fmt.Errorf("Wrong type") | |
} | |
// Custom unmarshal for pairs | |
func (p *Pair) UnmarshalJSON(b []byte) error { | |
var objMap map[string]map[string]*json.RawMessage | |
err := json.Unmarshal(b, &objMap) | |
if err != nil { | |
return err | |
} | |
var kType, vType int | |
json.Unmarshal(*objMap["key"]["type"], &kType) | |
json.Unmarshal(*objMap["value"]["type"], &vType) | |
p.Key, err = UnmarshalType(MarshalType(kType), *objMap["key"]["value"]) | |
if err != nil { | |
return err | |
} | |
p.Value, err = UnmarshalType(MarshalType(vType), *objMap["value"]["value"]) | |
if err != nil { | |
return err | |
} | |
return nil | |
} | |
func main() { | |
// Marshaling a struct | |
fmt.Println("== Marshalling struct ==") | |
p := Pair{Key: String{"someKey"}, Value: Int{1}} | |
// Marshal | |
byteData, err := json.Marshal(p) | |
checkErr(err) | |
fmt.Println("Marshalled:", string(byteData)) | |
// Unmarshal into Pair struct | |
pout := Pair{} | |
err = json.Unmarshal(byteData, &pout) | |
fmt.Println("Unmarshalled:", pout) | |
// Marshaling a list of Pairs | |
fmt.Println("== Marshalling pairs ==") | |
p1 := Pair{Key: String{"someKey"}, Value: Int{1}} | |
p2 := Pair{Key: String{"otherKey"}, Value: Int{2}} | |
pl := Pairs{p1, p2} | |
byteData, err = json.Marshal(pl) | |
checkErr(err) | |
fmt.Println("Marshalled:", string(byteData)) | |
// Unmarshalling into the right type | |
plout := Pairs{} | |
err = json.Unmarshal(byteData, &plout) | |
fmt.Println("Unmarshalled:", plout) | |
} | |
func checkErr(err error){ | |
if err != nil{ | |
panic(err) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment