help.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package sexp
  2. func DontPanic(f func() error) (err error) {
  3. defer func() {
  4. if e := recover(); e != nil {
  5. if ue, ok := e.(*UnmarshalError); ok {
  6. err = ue
  7. return
  8. }
  9. panic(e)
  10. }
  11. }()
  12. return f()
  13. }
  14. // A simple helper structure inspired by the simplejson-go API. Use Help
  15. // function to actually acquire it from the given *Node.
  16. type Helper struct {
  17. node *Node
  18. err *UnmarshalError
  19. }
  20. func Help(node *Node) Helper {
  21. if node == nil {
  22. err := NewUnmarshalError(nil, nil, "nil node")
  23. return Helper{nil, err}
  24. }
  25. return Helper{node, nil}
  26. }
  27. func (h Helper) IsValid() bool {
  28. return h.node != nil
  29. }
  30. func (h Helper) Next() Helper {
  31. if h.node == nil {
  32. return h
  33. }
  34. if h.node.Next == nil {
  35. err := NewUnmarshalError(h.node, nil,
  36. "a sibling of the node was requested, but it has none")
  37. return Helper{nil, err}
  38. }
  39. return Helper{h.node.Next, nil}
  40. }
  41. func (h Helper) Child(n int) Helper {
  42. if h.node == nil {
  43. return h
  44. }
  45. c := h.node.Children
  46. if c == nil {
  47. err := NewUnmarshalError(h.node, nil,
  48. "cannot retrieve %d%s child node, node is not a list",
  49. n+1, number_suffix(n+1))
  50. return Helper{nil, err}
  51. }
  52. for i := 0; i < n; i++ {
  53. c = c.Next
  54. if c == nil {
  55. err := NewUnmarshalError(h.node, nil,
  56. "cannot retrieve %d%s child node, %s",
  57. n+1, number_suffix(n+1),
  58. the_list_has_n_children(h.node.NumChildren()))
  59. return Helper{nil, err}
  60. }
  61. }
  62. return Helper{c, nil}
  63. }
  64. func (h Helper) IsList() bool {
  65. if h.node == nil {
  66. return false
  67. }
  68. return h.node.IsList()
  69. }
  70. func (h Helper) IsScalar() bool {
  71. if h.node == nil {
  72. return false
  73. }
  74. return h.node.IsScalar()
  75. }
  76. func (h Helper) Bool() (bool, error) {
  77. if h.node == nil {
  78. return false, h.err
  79. }
  80. var v bool
  81. err := h.node.Unmarshal(&v)
  82. if err != nil {
  83. return false, err
  84. }
  85. return v, nil
  86. }
  87. func (h Helper) Int() (int, error) {
  88. if h.node == nil {
  89. return 0, h.err
  90. }
  91. var v int
  92. err := h.node.Unmarshal(&v)
  93. if err != nil {
  94. return 0, err
  95. }
  96. return v, nil
  97. }
  98. func (h Helper) Float64() (float64, error) {
  99. if h.node == nil {
  100. return 0, h.err
  101. }
  102. var v float64
  103. err := h.node.Unmarshal(&v)
  104. if err != nil {
  105. return 0, err
  106. }
  107. return v, nil
  108. }
  109. func (h Helper) String() (string, error) {
  110. if h.node == nil {
  111. return "", h.err
  112. }
  113. var v string
  114. err := h.node.Unmarshal(&v)
  115. if err != nil {
  116. return "", err
  117. }
  118. return v, nil
  119. }
  120. func (h Helper) Node() (*Node, error) {
  121. if h.node == nil {
  122. return nil, h.err
  123. }
  124. return h.node, nil
  125. }
  126. func (h Helper) MustBool() bool {
  127. v, err := h.Bool()
  128. if err != nil {
  129. panic(err)
  130. }
  131. return v
  132. }
  133. func (h Helper) MustInt() int {
  134. v, err := h.Int()
  135. if err != nil {
  136. panic(err)
  137. }
  138. return v
  139. }
  140. func (h Helper) MustFloat64() float64 {
  141. v, err := h.Float64()
  142. if err != nil {
  143. panic(err)
  144. }
  145. return v
  146. }
  147. func (h Helper) MustString() string {
  148. v, err := h.String()
  149. if err != nil {
  150. panic(err)
  151. }
  152. return v
  153. }
  154. func (h Helper) MustNode() *Node {
  155. v, err := h.Node()
  156. if err != nil {
  157. panic(err)
  158. }
  159. return v
  160. }