walk.go 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (c) 2018 Ernest Micklei
  2. //
  3. // MIT License
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining
  6. // a copy of this software and associated documentation files (the
  7. // "Software"), to deal in the Software without restriction, including
  8. // without limitation the rights to use, copy, modify, merge, publish,
  9. // distribute, sublicense, and/or sell copies of the Software, and to
  10. // permit persons to whom the Software is furnished to do so, subject to
  11. // the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be
  14. // included in all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  20. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  21. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  22. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. package proto
  24. // Handler is a type of function that accepts a Visitee.
  25. type Handler func(v Visitee)
  26. // Walk recursively pays a visit to all Visitees of a Proto and calls each handler with it.
  27. func Walk(proto *Proto, handlers ...Handler) {
  28. walk(proto, handlers...)
  29. }
  30. func walk(container elementContainer, handlers ...Handler) {
  31. for _, eachElement := range container.elements() {
  32. for _, eachFilter := range handlers {
  33. eachFilter(eachElement)
  34. }
  35. if next, ok := eachElement.(elementContainer); ok {
  36. walk(next, handlers...)
  37. }
  38. }
  39. }
  40. // WithMessage returns a Handler that will call the apply function when the Visitee is a Message.
  41. func WithMessage(apply func(*Message)) Handler {
  42. return func(v Visitee) {
  43. if s, ok := v.(*Message); ok {
  44. apply(s)
  45. }
  46. }
  47. }
  48. // WithOption returns a Handler that will call the apply function when the Visitee is a Option.
  49. func WithOption(apply func(*Option)) Handler {
  50. return func(v Visitee) {
  51. if s, ok := v.(*Option); ok {
  52. apply(s)
  53. }
  54. }
  55. }
  56. // WithEnum returns a Handler that will call the apply function when the Visitee is a Enum.
  57. func WithEnum(apply func(*Enum)) Handler {
  58. return func(v Visitee) {
  59. if s, ok := v.(*Enum); ok {
  60. apply(s)
  61. }
  62. }
  63. }
  64. // WithOneof returns a Handler that will call the apply function when the Visitee is a Oneof.
  65. func WithOneof(apply func(*Oneof)) Handler {
  66. return func(v Visitee) {
  67. if s, ok := v.(*Oneof); ok {
  68. apply(s)
  69. }
  70. }
  71. }
  72. // WithService returns a Handler that will call the apply function when the Visitee is a Service.
  73. func WithService(apply func(*Service)) Handler {
  74. return func(v Visitee) {
  75. if s, ok := v.(*Service); ok {
  76. apply(s)
  77. }
  78. }
  79. }
  80. // WithRPC returns a Handler that will call the apply function when the Visitee is a RPC.
  81. func WithRPC(apply func(*RPC)) Handler {
  82. return func(v Visitee) {
  83. if s, ok := v.(*RPC); ok {
  84. apply(s)
  85. }
  86. }
  87. }