mode.go raw

   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  
   7  package bsonrw
   8  
   9  import (
  10  	"fmt"
  11  )
  12  
  13  type mode int
  14  
  15  const (
  16  	_ mode = iota
  17  	mTopLevel
  18  	mDocument
  19  	mArray
  20  	mValue
  21  	mElement
  22  	mCodeWithScope
  23  	mSpacer
  24  )
  25  
  26  func (m mode) String() string {
  27  	var str string
  28  
  29  	switch m {
  30  	case mTopLevel:
  31  		str = "TopLevel"
  32  	case mDocument:
  33  		str = "DocumentMode"
  34  	case mArray:
  35  		str = "ArrayMode"
  36  	case mValue:
  37  		str = "ValueMode"
  38  	case mElement:
  39  		str = "ElementMode"
  40  	case mCodeWithScope:
  41  		str = "CodeWithScopeMode"
  42  	case mSpacer:
  43  		str = "CodeWithScopeSpacerFrame"
  44  	default:
  45  		str = "UnknownMode"
  46  	}
  47  
  48  	return str
  49  }
  50  
  51  func (m mode) TypeString() string {
  52  	var str string
  53  
  54  	switch m {
  55  	case mTopLevel:
  56  		str = "TopLevel"
  57  	case mDocument:
  58  		str = "Document"
  59  	case mArray:
  60  		str = "Array"
  61  	case mValue:
  62  		str = "Value"
  63  	case mElement:
  64  		str = "Element"
  65  	case mCodeWithScope:
  66  		str = "CodeWithScope"
  67  	case mSpacer:
  68  		str = "CodeWithScopeSpacer"
  69  	default:
  70  		str = "Unknown"
  71  	}
  72  
  73  	return str
  74  }
  75  
  76  // TransitionError is an error returned when an invalid progressing a
  77  // ValueReader or ValueWriter state machine occurs.
  78  // If read is false, the error is for writing
  79  type TransitionError struct {
  80  	name        string
  81  	parent      mode
  82  	current     mode
  83  	destination mode
  84  	modes       []mode
  85  	action      string
  86  }
  87  
  88  func (te TransitionError) Error() string {
  89  	errString := fmt.Sprintf("%s can only %s", te.name, te.action)
  90  	if te.destination != mode(0) {
  91  		errString = fmt.Sprintf("%s a %s", errString, te.destination.TypeString())
  92  	}
  93  	errString = fmt.Sprintf("%s while positioned on a", errString)
  94  	for ind, m := range te.modes {
  95  		if ind != 0 && len(te.modes) > 2 {
  96  			errString = fmt.Sprintf("%s,", errString)
  97  		}
  98  		if ind == len(te.modes)-1 && len(te.modes) > 1 {
  99  			errString = fmt.Sprintf("%s or", errString)
 100  		}
 101  		errString = fmt.Sprintf("%s %s", errString, m.TypeString())
 102  	}
 103  	errString = fmt.Sprintf("%s but is positioned on a %s", errString, te.current.TypeString())
 104  	if te.parent != mode(0) {
 105  		errString = fmt.Sprintf("%s with parent %s", errString, te.parent.TypeString())
 106  	}
 107  	return errString
 108  }
 109