Маршал / Унмаршал int тип - PullRequest
0 голосов
/ 05 мая 2018

Я использую тип int для представления перечисления. Я хочу преобразовать его в строку, когда я упорядочиваю его в JSON, AFAIK, я должен реализовать UnmarshalJSON и MarshalJSON, но он жалуется:

ошибка маршала: json: ошибка вызова MarshalJSON для типа main.trxStatus: недопустимый символ 'b' ищет начало ожидаемое значение конца ввода JSON

при сортировке. Затем я добавляю кавычки в строку с маршалом:

func (s trxStatus) MarshalJSON() ([]byte, error) {
    return []byte("\"" + s.String() + "\""), nil
}

Marshal работает сейчас, но не может Unmarshal из потока маршаллированных байтов правильно.

package main

import (
    "encoding/json"
    "fmt"
)

type trxStatus int

type test struct {
    S trxStatus
    A string
}

const (
    buySubmitted trxStatus = iota
    buyFilled
    sellSubmiited
    sellFilled
    finished
)

var ss = [...]string{"buySubmitted", "buyFilled", "sellSubmiited", "sellFilled", "Finished"}

func (s *trxStatus) UnmarshalJSON(bytes []byte) error {
    status := string(bytes)
    // unknown
    for i, v := range ss {
        if v == status {
            tttt := trxStatus(i)
            *s = tttt
            break
        }
    }
    return nil
}

func (s trxStatus) MarshalJSON() ([]byte, error) {
    return []byte(s.String()), nil
}

func (s trxStatus) String() string {

    if s < buySubmitted || s > finished {
        return "Unknown"
    }

    return ss[s]
}

func main() {
    s := test{S: buyFilled, A: "hello"}
    j, err := json.Marshal(s)
    if err != nil {
        fmt.Printf("marshal error: %v", err)
    }
    var tt test
    fmt.Println(json.Unmarshal(j, &tt))
    fmt.Println(tt)
}

1 Ответ

0 голосов
/ 05 мая 2018

При написании пользовательских реализаций Marshaler и Unmarshaler обязательно включайте или обрезайте окружающие двойные кавычки строк json.

func (s *trxStatus) UnmarshalJSON(bytes []byte) error {
    status := string(bytes)
    if n := len(status); n > 1 && status[0] == '"' && status[n-1] == '"' {
        status = status[1:n-1] // trim surrounding quotes
    }
    // unknown
    for i, v := range ss {
        if v == status {
            tttt := trxStatus(i)
            *s = tttt
            break
        }
    }
    return nil
}

func (s trxStatus) MarshalJSON() ([]byte, error) {
    return []byte(`"` + s.String() + `"`), nil
}
...