User Tools

Site Tools


ct.go
/*
 * Copyright 2020 Oleg Borodin  <borodin@unix7.org>
 */
 
 
package main
 
import (
    "fmt"
    "encoding/json"
    "errors"
)
 
type Bool bool
 
func (this Bool) MarshalJSON() ([]byte, error) {
    json, err := json.Marshal(bool(this))
    return json, err
}
 
func (this *Bool) UnmarshalJSON(data []byte) error {
    var err error
 
   var ref interface{}
    err = json.Unmarshal(data, &ref)
 
    if err != nil {
        *this = false
        return nil
    }
 
    switch v := ref.(type) {
        case nil:
            *this = false
            return nil
        case string:
            var res string
            err := json.Unmarshal(data, &res)
            if err != nil {
                *this = false
                return err
            }
            switch res {
                case "true", "1":
                    *this = true
                case "false", "0", "-1":
                    *this = false
                default:
                    *this = false
            }
            return nil
        case int:
            *this = false
            return nil
        case float64:
            *this = false
            return nil
        case bool:
            var res bool
            err := json.Unmarshal(data, &res)
            *this = Bool(res)
            return err
        default:
            return errors.New(fmt.Sprintf("i don't know about type %T", v))
    }
    return nil
}
 
type String string
 
func (this String) MarshalJSON() ([]byte, error) {
    json, err := json.Marshal(string(this))
    return json, err
}
 
func (this *String) UnmarshalJSON(data []byte) error {
    var err error
 
    var ref interface{}
    err = json.Unmarshal(data, &ref)
    if err != nil {
        *this = String(string(data))
        return nil
    }
 
    switch v := ref.(type) {
        case nil:
            *this = String("null")
            return nil
        case string:
            var res string
            err = json.Unmarshal(data, &res)
            *this = String(res)
            return err
        case int:
            *this = String(string(data))
            return nil
        case float64:
            *this = String(string(data))
            return nil
        case bool:
            *this = String(string(data))
            return nil
 
        default:
            return errors.New(fmt.Sprintf("i don't know about type %T", v))
    }
    return nil
}
 
type Person struct {
    FirstName   String      `json:"firstName"`
    LastName    String      `json:"lastName"`
    Alive       Bool        `json:"alive"`
}
 
func main() {
 
    var p1 Person = Person{
            FirstName: "qwerty",
            LastName:  "12345",
    }
    jsonData, err := json.Marshal(&p1)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(string(jsonData))
 
    var p3 Person
 
    jsonData = []byte(`{ "firstName": "John", "lastName": null, "alive": 1234 }`)
 
    err = json.Unmarshal(jsonData, &p3)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(p3.FirstName, p3.LastName, p3.Alive)
 
    jsonData = []byte(`{ "firstName": "John", "lastName": true, "alive": "true" }`)
 
    err = json.Unmarshal(jsonData, &p3)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(p3.FirstName, p3.LastName, p3.Alive)
 
    jsonData = []byte(`{ "firstName": "John", "lastName": 45.67E-1, "alive": "12345" }`)
 
    err = json.Unmarshal(jsonData, &p3)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(p3.FirstName, p3.LastName, p3.Alive)
}
$ go run ex.go
{"firstName":"qwerty","lastName":"12345","alive":false}
John null false
John true true
John 45.67E-1 false