Skip to content

Instantly share code, notes, and snippets.

@odeke-em
Created May 19, 2017 20:12
Show Gist options
  • Save odeke-em/22a6b3d86b0ba7c4639949b28c27a5a1 to your computer and use it in GitHub Desktop.
Save odeke-em/22a6b3d86b0ba7c4639949b28c27a5a1 to your computer and use it in GitHub Desktop.
Numeric bool: serialized as int <--> used in code like a boolean
package main
import (
"encoding/json"
"fmt"
"log"
"strconv"
"strings"
)
type NumericBool bool
var _ json.Marshaler = (*NumericBool)(nil)
var _ json.Unmarshaler = (*NumericBool)(nil)
func (nb *NumericBool) UnmarshalJSON(blob []byte) error {
if len(blob) < 1 {
*nb = false
return nil
}
s := string(blob)
if strings.ContainsAny(s, "tf") {
// Try first parsing an integer.
pBool, err := strconv.ParseBool(s)
if err == nil {
*nb = NumericBool(pBool)
return nil
}
}
pInt, err := strconv.ParseInt(s, 10, 32)
if err != nil {
*nb = pInt != 0
return nil
}
return err
}
var (
oneAsJSON, _ = json.Marshal(1)
zeroAsJSON, _ = json.Marshal(0)
)
func (nb *NumericBool) MarshalJSON() ([]byte, error) {
if nb == nil || *nb == false {
return zeroAsJSON, nil
}
return oneAsJSON, nil
}
func main() {
// Then to test it
type Request struct {
Private NumericBool `json:"private"`
}
req := &Request{Private: true}
blob, _ := json.Marshal(req)
fmt.Printf("Marshaled: %s\n", blob)
var r1 Request
if err := json.Unmarshal(blob, &r1); err != nil {
log.Fatal(err)
}
fmt.Printf("Unmarshaled: %#v\n", r1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment