Created
May 7, 2020 07:28
-
-
Save 17twenty/5d535d02b2c1f59934c5b332d9251d61 to your computer and use it in GitHub Desktop.
Custom marshal/unmarshal leveraging Scan/Value() for JSON and Database usage
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
package main | |
import ( | |
"database/sql/driver" | |
"encoding/json" | |
"fmt" | |
"strings" | |
) | |
type paymentOption int64 | |
const ( | |
// PaymentOptionUnknown is an invalid type | |
PaymentOptionUnknown paymentOption = iota | |
// PaymentOptionCard means a card payment was made | |
PaymentOptionCard | |
// PaymentOptionInstalments means an instalment plan was used | |
PaymentOptionInstalments | |
) | |
// Begin cancer | |
func (x paymentOption) String() string { | |
return map[paymentOption]string{ | |
PaymentOptionUnknown: "PaymentOptionUnknown", | |
PaymentOptionCard: "PaymentOptionCard", | |
PaymentOptionInstalments: "PaymentOptionInstalments", | |
}[x] | |
} | |
// Scan ... | |
func (x *paymentOption) Scan(value interface{}) error { | |
db := value.([]uint8) | |
// An attempt to fetch a map value with a key that is not present in | |
// the map will return the zero value for the type of the entries in the map i.e. | |
// the unknown option | |
*x = map[string]paymentOption{ | |
"PaymentOptionUnknown": PaymentOptionUnknown, | |
"PaymentOptionCard": PaymentOptionCard, | |
"PaymentOptionInstalments": PaymentOptionInstalments, | |
}[string(db)] | |
return nil | |
} | |
// Value ... | |
func (x paymentOption) Value() (driver.Value, error) { | |
return x.String(), nil | |
} | |
// MarshalJSON Converts to Byte array | |
func (x paymentOption) MarshalJSON() ([]byte, error) { | |
return json.Marshal(strings.ToLower(strings.ReplaceAll(x.String(), "PaymentOption", ""))) | |
} | |
// UnmarshalJSON Converts from byte array | |
func (x *paymentOption) UnmarshalJSON(b []byte) error { | |
var j string | |
if err := json.Unmarshal(b, &j); err != nil { | |
return err | |
} | |
// Cancer hacks | |
return x.Scan([]uint8((fmt.Sprintf("PaymentOption%s", strings.Title(j))))) | |
} | |
// end cancer | |
type Test struct { | |
Bar []paymentOption `json:"bar"` | |
} | |
func main() { | |
data := []byte(`{"bar": ["instalments","card"]}`) | |
var test Test | |
var err error | |
json.Unmarshal(data, &test) | |
fmt.Printf("After unmarshal: %#v %s\n", test, test) | |
test.Bar = []paymentOption{PaymentOptionInstalments} | |
data, err = json.Marshal(test) | |
fmt.Println(">",err) | |
fmt.Printf("After marshal: %#v %s\n", string(data), data) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment