demo_go_structs.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. package zygo
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. //go:generate msgp
  7. //msgp:ignore Plane Wings Snoopy Hornet Hellcat SetOfPlanes
  8. // the pointer wasn't getting followed.
  9. type NestOuter struct {
  10. Inner *NestInner `msg:"inner" json:"inner" zid:"0"`
  11. }
  12. type NestInner struct {
  13. Hello string `msg:"hello" json:"hello" zid:"0"`
  14. }
  15. type Event struct {
  16. Id int `json:"id" msg:"id"`
  17. User Person `json:"user" msg:"user"`
  18. Flight string `json:"flight" msg:"flight"`
  19. Pilot []string `json:"pilot" msg:"pilot"`
  20. Cancelled bool `json:"cancelled" msg:"cancelled"`
  21. }
  22. type Person struct {
  23. First string `json:"first" msg:"first"`
  24. Last string `json:"last" msg:"last"`
  25. }
  26. func (ev *Event) DisplayEvent(from string) {
  27. fmt.Printf("%s %#v", from, ev)
  28. }
  29. type Wings struct {
  30. SpanCm int
  31. }
  32. type SetOfPlanes struct {
  33. Flyers []Flyer `json:"flyers" msg:"flyers"`
  34. }
  35. // the interface Flyer confounds the msgp msgpack code generator,
  36. // so put the msgp:ignore Plane above
  37. type Plane struct {
  38. Wings
  39. ID int `json:"id" msg:"id"`
  40. Speed int `json:"speed" msg:"speed"`
  41. Chld Flyer `json:"chld" msg:"chld"`
  42. Friends []Flyer `json:"friends"`
  43. }
  44. type Snoopy struct {
  45. Plane `json:"plane" msg:"plane"`
  46. Cry string `json:"cry" msg:"cry"`
  47. Pack []int `json:"pack"`
  48. Carrying []Flyer `json:"carrying"`
  49. }
  50. type Hornet struct {
  51. Plane `json:"plane" msg:"plane"`
  52. Mass float64
  53. Nickname string
  54. }
  55. type Hellcat struct {
  56. Plane `json:"plane" msg:"plane"`
  57. }
  58. func (p *Snoopy) Fly(w *Weather) (s string, err error) {
  59. w.Type = "VERY " + w.Type // side-effect, for demo purposes
  60. s = fmt.Sprintf("Snoopy sees weather '%s', cries '%s'", w.Type, p.Cry)
  61. fmt.Println(s)
  62. for _, flyer := range p.Friends {
  63. flyer.Fly(w)
  64. }
  65. return
  66. }
  67. func (p *Snoopy) GetCry() string {
  68. return p.Cry
  69. }
  70. func (p *Snoopy) EchoWeather(w *Weather) *Weather {
  71. return w
  72. }
  73. func (p *Snoopy) Sideeffect() {
  74. fmt.Printf("Sideeffect() called! p = %p\n", p)
  75. }
  76. func (b *Hornet) Fly(w *Weather) (s string, err error) {
  77. fmt.Printf("Hornet.Fly() called. I see weather %v\n", w.Type)
  78. return
  79. }
  80. func (b *Hellcat) Fly(w *Weather) (s string, err error) {
  81. fmt.Printf("Hellcat.Fly() called. I see weather %v\n", w.Type)
  82. return
  83. }
  84. type Flyer interface {
  85. Fly(w *Weather) (s string, err error)
  86. }
  87. type Weather struct {
  88. Time time.Time `json:"time" msg:"time"`
  89. Size int64 `json:"size" msg:"size"`
  90. Type string `json:"type" msg:"type"`
  91. Details []byte `json:"details" msg:"details"`
  92. }
  93. func (w *Weather) IsSunny() bool {
  94. return w.Type == "sunny"
  95. }
  96. func (env *Zlisp) ImportDemoData() {
  97. env.AddFunction("nestouter", DemoNestInnerOuterFunction)
  98. env.AddFunction("nestinner", DemoNestInnerOuterFunction)
  99. rt := &RegisteredType{GenDefMap: true, Factory: func(env *Zlisp, h *SexpHash) (interface{}, error) {
  100. return &NestOuter{}, nil
  101. }}
  102. GoStructRegistry.RegisterUserdef(rt, true, "nestouter", "NestOuter")
  103. rt = &RegisteredType{GenDefMap: true, Factory: func(env *Zlisp, h *SexpHash) (interface{}, error) {
  104. return &NestInner{}, nil
  105. }}
  106. GoStructRegistry.RegisterUserdef(rt, true, "nestinner", "NestInner")
  107. }
  108. // constructor
  109. func DemoNestInnerOuterFunction(env *Zlisp, name string, args []Sexp) (Sexp, error) {
  110. n := len(args)
  111. switch n {
  112. case 0:
  113. return SexpNull, WrongNargs
  114. default:
  115. // many parameters, treat as key:value pairs in the hash/record.
  116. return ConstructorFunction("msgmap")(env, "msgmap", append([]Sexp{&SexpStr{S: name}}, MakeList(args)))
  117. }
  118. }