1package query
2
3import (
4	"fmt"
5	"net/url"
6)
7
8// Object represents the encoding of Query structures and unions. A Query
9// object is a representation of a mapping of string keys to arbitrary
10// values where there is a fixed set of keys whose values each have their
11// own known type. A serialized object might look like the following:
12//
13//     ObjectName.Foo=value
14//     &ObjectName.Bar=5
15type Object struct {
16	// The query values to add the object to.
17	values url.Values
18	// The object's prefix, which includes the names of all parent structures
19	// and ends with the name of the object. For example, the prefix might be
20	// "ParentStructure.ObjectName". This prefix will be used to form the full
21	// keys for each member of the object. For example, a member might have the
22	// key "ParentStructure.ObjectName.MemberName".
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}
30
31func newObject(values url.Values, prefix string) *Object {
32	return &Object{
33		values: values,
34		prefix: prefix,
35	}
36}
37
38// Key adds the given named key to the Query object.
39// Returns a Value encoder that should be used to encode a Query value type.
40func (o *Object) Key(name string) Value {
41	return o.key(name, false)
42}
43
44// FlatKey adds the given named key to the Query object.
45// Returns a Value encoder that should be used to encode a Query value type. The
46// value will be flattened if it is a map or array.
47func (o *Object) FlatKey(name string) Value {
48	return o.key(name, true)
49}
50
51func (o *Object) key(name string, flatValue bool) Value {
52	if o.prefix != "" {
53		return newValue(o.values, fmt.Sprintf("%s.%s", o.prefix, name), flatValue)
54	}
55	return newValue(o.values, name, flatValue)
56}
57