39 lines
865 B
Go
39 lines
865 B
Go
package dto
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
)
|
|
|
|
// ID accepts legacy JSON integers and decimal strings. Its wire representation
|
|
// is always a string so a browser can round-trip all uint64 values exactly.
|
|
type ID uint64
|
|
|
|
func (id ID) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(strconv.FormatUint(uint64(id), 10))
|
|
}
|
|
|
|
func (id *ID) UnmarshalJSON(raw []byte) error {
|
|
text := string(raw)
|
|
if len(raw) > 0 && raw[0] == '"' {
|
|
if err := json.Unmarshal(raw, &text); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if text == "" {
|
|
return fmt.Errorf("ID must be a decimal integer")
|
|
}
|
|
for _, digit := range text {
|
|
if digit < '0' || digit > '9' {
|
|
return fmt.Errorf("ID must be a decimal integer")
|
|
}
|
|
}
|
|
value, err := strconv.ParseUint(text, 10, 64)
|
|
if err != nil {
|
|
return fmt.Errorf("ID is outside the uint64 range")
|
|
}
|
|
*id = ID(value)
|
|
return nil
|
|
}
|