Setting Types
Every setting has a type, which determines which values it can hold. Each setting type has a string representation, which is used to describe the type in the HTTP API.
Note
Internally, all setting values are JSON values. However, it is up to user libraries to interpret these values into their local environment’s proper types (for example, a setting of type Flag is stored internally as a JSON array, but in python may be interpreted as a frozen set).
Primitive Types: int, float, str, bool
Settings of these types can hold any value of the appropriate type.
int: an integerfloat: a floating point numberstr: a stringbool: a boolean
Primitive From a Closed List: Enum[…]
Setting values of type Enum[...] can only hold one value from the list of allowed values.
For example, a setting of type Enum["red","green","blue"] can only hold the values "red", "green", or
"blue".
The values inside the list must be primitive, but they do not need to all be the same type. Therefore the type
Enum[0, 1, "other", false] is valid, but Enum[0, 1, [0,1]] is not.
Note
Both the Enum and the Flag types are order-invariant, meaning that Enum[0,1,2] is equal to Enum[2,1,0].
However, for convenience, the order of the values in the list is always returned in alphabetical order.
PUT /api/v1/settings/declare
{
"name": "my_setting",
"type": "Enum[false, \"maybe\", true]",
...
}
200 {...}
GET /api/v1/settings/my_setting
200 {
"type": "Enum[\"maybe\",false,true]",
...
}
Subset of a Closed List: Flag[…]
Setting values of type Flag[...] can hold a list of values that are in the list of allowed values. In effect, they
hold a subset of the allowed values. For example, a setting of type Flag["red", "green", "blue"] may be set to any
of these values:
"red", "green", "blue"
"green", "blue"
"red", "blue"
"red", "green"
"blue"
"green"
"red"
()(an empty subset)
The values inside the list must be primitive, but they do not need to all be the same type. Therefore the type
Flag[0, 1, "other", false] is valid, but Flag[0, 1, [0,1]] is not.
Note
Generic Sequence: Sequence<…>
Setting values of type Sequence<T> can hold an array of values of the specified type. For example, a setting
of type Sequence<int> can hold any array of integers.
Sequences can be of any type, even of other sequences. For example, a setting of type
Sequence<Sequence<Enum["red", "green", "blue"]>> can hold any array of arrays of the values "red", "green",
or "blue" (so an example value might be [["red", "blue", "green"], ["red", "red"], [], ["green"]]).
Generic Mappings: Mappings<…>
Setting values of type Mappings<T> can hold a dictionary that maps strings to values of the specified type.
For example, a setting of type Mappings<int> can hold any dictionary mapping strings to integers.
Mappings can be of any type, even of other mappings. For example, a setting of type Mapping<Mapping<int>> can
hold any dictionary mapping strings to dictionaries that map strings to integers.
Type Order
Setting types have a partial ordering over them. This when we want to safely change a setting’s type. We say that type A is a supertype of type B if every value that can be stored in type B can also be stored in type A. This will help us when declaring settings.
Examples:
floatis a supertype ofintSequence<float>is a supertype ofSequence<int>Enum[0,1,2]is a supertype ofEnum[0,1]
This is a non-strict partial order (reflexive, antisymmetric and transitive).
Note
This definition applies to the conceptual values of the setting types, not it’s internal JSON representation.
For example, a setting of type Sequence<int> is not supertype of Flags[0, 1, 2], even though the Flags
will always be represented as an array of ints internally. This also means that Enum[true, false, "other"] is
not a supertype of bool.