array.go (2318B)
1 package query 2 3 import ( 4 "fmt" 5 "net/url" 6 ) 7 8 // Array represents the encoding of Query lists and sets. A Query array is a 9 // representation of a list of values of a fixed type. A serialized array might 10 // look like the following: 11 // 12 // ListName.member.1=foo 13 // &ListName.member.2=bar 14 // &Listname.member.3=baz 15 type Array struct { 16 // The query values to add the array to. 17 values url.Values 18 // The array's prefix, which includes the names of all parent structures 19 // and ends with the name of the list. For example, the prefix might be 20 // "ParentStructure.ListName". This prefix will be used to form the full 21 // keys for each element in the list. For example, an entry might have the 22 // key "ParentStructure.ListName.member.MemberName.1". 23 // 24 // While this is currently represented as a string that gets added to, it 25 // could also be represented as a stack that only gets condensed into a 26 // string when a finalized key is created. This could potentially reduce 27 // allocations. 28 prefix string 29 // Whether the list is flat or not. A list that is not flat will produce the 30 // following entry to the url.Values for a given entry: 31 // ListName.MemberName.1=value 32 // A list that is flat will produce the following: 33 // ListName.1=value 34 flat bool 35 // The location name of the member. In most cases this should be "member". 36 memberName string 37 // Elements are stored in values, so we keep track of the list size here. 38 size int32 39 // Empty lists are encoded as "<prefix>=", if we add a value later we will 40 // remove this encoding 41 emptyValue Value 42 } 43 44 func newArray(values url.Values, prefix string, flat bool, memberName string) *Array { 45 emptyValue := newValue(values, prefix, flat) 46 emptyValue.String("") 47 48 return &Array{ 49 values: values, 50 prefix: prefix, 51 flat: flat, 52 memberName: memberName, 53 emptyValue: emptyValue, 54 } 55 } 56 57 // Value adds a new element to the Query Array. Returns a Value type used to 58 // encode the array element. 59 func (a *Array) Value() Value { 60 if a.size == 0 { 61 delete(a.values, a.emptyValue.key) 62 } 63 64 // Query lists start a 1, so adjust the size first 65 a.size++ 66 prefix := a.prefix 67 if !a.flat { 68 prefix = fmt.Sprintf("%s.%s", prefix, a.memberName) 69 } 70 // Lists can't have flat members 71 return newValue(a.values, fmt.Sprintf("%s.%d", prefix, a.size), false) 72 }