Passed
Push — main ( a989b9...26a57f )
by Igor
160:00 queued 126:09
created

validation.ArrayIndexElement.String   A

Complexity

Conditions 1

Size

Total Lines 2
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
dl 0
loc 2
ccs 1
cts 1
cp 1
crap 1
rs 10
c 0
b 0
f 0
nop 0
1
package validation
2
3
import (
4
	"encoding/json"
5
	"fmt"
6
	"strconv"
7
)
8
9
// PropertyPathElement is a part of the PropertyPath.
10
type PropertyPathElement interface {
11
	// IsIndex can be used to determine whether an element is a string (property name) or
12
	// an index array.
13
	IsIndex() bool
14
	fmt.Stringer
15
}
16
17
// PropertyNameElement holds up property name value under PropertyPath.
18
type PropertyNameElement string
19
20
// IsIndex on PropertyNameElement always returns false.
21
func (p PropertyNameElement) IsIndex() bool {
22 1
	return false
23
}
24
25
// String returns property name as is.
26
func (p PropertyNameElement) String() string {
27 1
	return string(p)
28
}
29
30
// ArrayIndexElement holds up array index value under PropertyPath.
31
type ArrayIndexElement int
32
33
// IsIndex on ArrayIndexElement always returns true.
34
func (a ArrayIndexElement) IsIndex() bool {
35 1
	return true
36
}
37
38
// String returns array index values converted into a string.
39
func (a ArrayIndexElement) String() string {
40 1
	return strconv.Itoa(int(a))
41
}
42
43
// PropertyPath is generated by the validator and indicates how it reached the invalid value
44
// from the root element. Property path is denoted by dots, while array access
45
// is denoted by square brackets. For example, "book.keywords[0]" means that the violation
46
// occurred on the first element of array "keywords" in the "book" object.
47
//
48
// Internally PropertyPath is a linked list. You can create a new path using WithProperty
49
// or WithIndex methods. PropertyPath should always be used as a pointer value.
50
// Nil value is a valid value that means that the property path is empty.
51
type PropertyPath struct {
52
	parent *PropertyPath
53
	value  PropertyPathElement
54
}
55
56
// NewPropertyPath creates a PropertyPath from the list of elements. If the list is empty nil will be returned.
57
// Nil value is a valid value that means that the property path is empty.
58
func NewPropertyPath(elements ...PropertyPathElement) *PropertyPath {
59 1
	var path *PropertyPath
60 1
	for _, element := range elements {
61 1
		path = &PropertyPath{parent: path, value: element}
62
	}
63 1
	return path
64
}
65
66
// WithProperty returns new PropertyPath with appended PropertyNameElement to the end of the list.
67
func (path *PropertyPath) WithProperty(name string) *PropertyPath {
68 1
	return &PropertyPath{
69
		parent: path,
70
		value:  PropertyNameElement(name),
71
	}
72
}
73
74
// WithIndex returns new PropertyPath with appended ArrayIndexElement to the end of the list.
75
func (path *PropertyPath) WithIndex(index int) *PropertyPath {
76 1
	return &PropertyPath{
77
		parent: path,
78
		value:  ArrayIndexElement(index),
79
	}
80
}
81
82
// String is used to format property path to a string.
83
func (path *PropertyPath) String() string {
84 1
	s := ""
85 1
	element := path
86 1
	for element != nil {
87 1
		if element.value.IsIndex() {
88 1
			s = "[" + element.value.String() + "]" + s
89
		} else {
90 1
			s = element.value.String() + s
91 1
			if element.parent != nil {
92 1
				s = "." + s
93
			}
94
		}
95 1
		element = element.parent
96
	}
97
98 1
	return s
99
}
100
101
// MarshalJSON will marshal property path value to a JSON string.
102
func (path *PropertyPath) MarshalJSON() ([]byte, error) {
103 1
	return json.Marshal(path.String())
104
}
105