You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.2 KiB

  1. // Copyright (C) MongoDB, Inc. 2017-present.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"); you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
  6. package bsonrw
  7. import (
  8. "fmt"
  9. )
  10. type mode int
  11. const (
  12. _ mode = iota
  13. mTopLevel
  14. mDocument
  15. mArray
  16. mValue
  17. mElement
  18. mCodeWithScope
  19. mSpacer
  20. )
  21. func (m mode) String() string {
  22. var str string
  23. switch m {
  24. case mTopLevel:
  25. str = "TopLevel"
  26. case mDocument:
  27. str = "DocumentMode"
  28. case mArray:
  29. str = "ArrayMode"
  30. case mValue:
  31. str = "ValueMode"
  32. case mElement:
  33. str = "ElementMode"
  34. case mCodeWithScope:
  35. str = "CodeWithScopeMode"
  36. case mSpacer:
  37. str = "CodeWithScopeSpacerFrame"
  38. default:
  39. str = "UnknownMode"
  40. }
  41. return str
  42. }
  43. func (m mode) TypeString() string {
  44. var str string
  45. switch m {
  46. case mTopLevel:
  47. str = "TopLevel"
  48. case mDocument:
  49. str = "Document"
  50. case mArray:
  51. str = "Array"
  52. case mValue:
  53. str = "Value"
  54. case mElement:
  55. str = "Element"
  56. case mCodeWithScope:
  57. str = "CodeWithScope"
  58. case mSpacer:
  59. str = "CodeWithScopeSpacer"
  60. default:
  61. str = "Unknown"
  62. }
  63. return str
  64. }
  65. // TransitionError is an error returned when an invalid progressing a
  66. // ValueReader or ValueWriter state machine occurs.
  67. // If read is false, the error is for writing
  68. type TransitionError struct {
  69. name string
  70. parent mode
  71. current mode
  72. destination mode
  73. modes []mode
  74. action string
  75. }
  76. func (te TransitionError) Error() string {
  77. errString := fmt.Sprintf("%s can only %s", te.name, te.action)
  78. if te.destination != mode(0) {
  79. errString = fmt.Sprintf("%s a %s", errString, te.destination.TypeString())
  80. }
  81. errString = fmt.Sprintf("%s while positioned on a", errString)
  82. for ind, m := range te.modes {
  83. if ind != 0 && len(te.modes) > 2 {
  84. errString = fmt.Sprintf("%s,", errString)
  85. }
  86. if ind == len(te.modes)-1 && len(te.modes) > 1 {
  87. errString = fmt.Sprintf("%s or", errString)
  88. }
  89. errString = fmt.Sprintf("%s %s", errString, m.TypeString())
  90. }
  91. errString = fmt.Sprintf("%s but is positioned on a %s", errString, te.current.TypeString())
  92. if te.parent != mode(0) {
  93. errString = fmt.Sprintf("%s with parent %s", errString, te.parent.TypeString())
  94. }
  95. return errString
  96. }