opt.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // +build none
  2. package optional
  3. import (
  4. "fmt"
  5. "github.com/mailru/easyjson/jlexer"
  6. "github.com/mailru/easyjson/jwriter"
  7. )
  8. // template type Optional(A)
  9. type A int
  10. // A 'gotemplate'-based type for providing optional semantics without using pointers.
  11. type Optional struct {
  12. V A
  13. Defined bool
  14. }
  15. // Creates an optional type with a given value.
  16. func OOptional(v A) Optional {
  17. return Optional{V: v, Defined: true}
  18. }
  19. // Get returns the value or given default in the case the value is undefined.
  20. func (v Optional) Get(deflt A) A {
  21. if !v.Defined {
  22. return deflt
  23. }
  24. return v.V
  25. }
  26. // MarshalEasyJSON does JSON marshaling using easyjson interface.
  27. func (v Optional) MarshalEasyJSON(w *jwriter.Writer) {
  28. if v.Defined {
  29. w.Optional(v.V)
  30. } else {
  31. w.RawString("null")
  32. }
  33. }
  34. // UnmarshalEasyJSON does JSON unmarshaling using easyjson interface.
  35. func (v *Optional) UnmarshalEasyJSON(l *jlexer.Lexer) {
  36. if l.IsNull() {
  37. l.Skip()
  38. *v = Optional{}
  39. } else {
  40. v.V = l.Optional()
  41. v.Defined = true
  42. }
  43. }
  44. // MarshalJSON implements a standard json marshaler interface.
  45. func (v Optional) MarshalJSON() ([]byte, error) {
  46. w := jwriter.Writer{}
  47. v.MarshalEasyJSON(&w)
  48. return w.Buffer.BuildBytes(), w.Error
  49. }
  50. // UnmarshalJSON implements a standard json unmarshaler interface.
  51. func (v *Optional) UnmarshalJSON(data []byte) error {
  52. l := jlexer.Lexer{Data: data}
  53. v.UnmarshalEasyJSON(&l)
  54. return l.Error()
  55. }
  56. // IsDefined returns whether the value is defined, a function is required so that it can
  57. // be used in an interface.
  58. func (v Optional) IsDefined() bool {
  59. return v.Defined
  60. }
  61. // String implements a stringer interface using fmt.Sprint for the value.
  62. func (v Optional) String() string {
  63. if !v.Defined {
  64. return "<undefined>"
  65. }
  66. return fmt.Sprint(v.V)
  67. }