Skip to content

Instantly share code, notes, and snippets.

@enahs
Last active January 4, 2022 23:52
Show Gist options
  • Select an option

  • Save enahs/11bf7628c97809d6d9bcc95437d2b18c to your computer and use it in GitHub Desktop.

Select an option

Save enahs/11bf7628c97809d6d9bcc95437d2b18c to your computer and use it in GitHub Desktop.

Revisions

  1. enahs revised this gist Jan 4, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion nullstring.go
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,7 @@ import (
    )

    // make a json'able null string
    // - respects omitempty
    // - doesn't respect omitempty
    // - null ~> null, valid = false
    // - "" ~> "" , valid = true
    // - "val" = "val", valid = true
  2. enahs revised this gist Jan 4, 2022. No changes.
  3. enahs created this gist Jan 4, 2022.
    113 changes: 113 additions & 0 deletions nullstring.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,113 @@
    package main

    import (
    "database/sql"
    "encoding/json"
    "fmt"
    )

    // make a json'able null string
    // - respects omitempty
    // - null ~> null, valid = false
    // - "" ~> "" , valid = true
    // - "val" = "val", valid = true

    const Null = "null"

    type NullString struct {
    sql.NullString
    }

    func NewNullString(s *string) NullString {
    var str string
    if s == nil {
    str = Null
    } else {
    str = *s
    }
    return NullString{
    sql.NullString{
    String: str,
    Valid: s != nil,
    },
    }

    }

    func (ns NullString) MarshalJSON() ([]byte, error) {

    var value string
    if ns.Valid == true {
    value = fmt.Sprintf("\"%s\"", ns.String)
    } else {
    value = Null
    }

    return []byte(value), nil
    }

    func (ns *NullString) UnmarshalJSON(b []byte) error {
    var s *string
    if err := json.Unmarshal(b, &s); err != nil {
    return err
    }
    if s == nil {
    ns.String = Null
    ns.Valid = false
    } else {
    ns.String = *s
    ns.Valid = true
    }
    return nil
    }

    type T struct {
    Reg string `json:"reg"`
    Nullish NullString `json:"nullish"`
    OmitReg string `json:"omitreg,omitempty"`
    OmitNullish NullString `json:"omitnull,omitempty"`
    expectedValue string `json:"-"`
    }

    func main() {
    emptyStr := ""
    fullStr := "yadda yadda"
    var PtrToStr *string
    testers := []T{
    // empty string
    T{
    Reg: emptyStr,
    Nullish: NewNullString(&emptyStr),
    OmitReg: emptyStr,
    OmitNullish: NewNullString(&emptyStr),
    expectedValue: `{"reg":"","nullish":"","omitnull":""}`,
    },
    // regular string
    T{
    Reg: fullStr,
    Nullish: NewNullString(&fullStr),
    OmitReg: fullStr,
    OmitNullish: NewNullString(&fullStr),
    expectedValue: `{"reg":"yadda yadda","nullish":"yadda yadda","omitreg":"yadda yadda","omitnull":"yadda yadda"}`,
    },
    // pointer to string that is null
    T{
    Reg: Null,
    Nullish: NewNullString(PtrToStr),
    OmitReg: Null,
    OmitNullish: NewNullString(PtrToStr),
    expectedValue: `{"reg":"null","nullish":null,"omitreg":"null","omitnull":null}`,
    },
    }
    for _, t := range testers {
    b, _ := json.Marshal(t)
    fmt.Println(string(b))
    newT := T{}
    err := json.Unmarshal([]byte(t.expectedValue), &newT)
    if err != nil {
    fmt.Println("error", err)
    }
    fmt.Printf("thing:\n%#v\n", newT)
    }

    }