trait = "is-discrete"
doc = """
The is-discrete trait is used for hardware that has a countable number of discrete positions, each with a unique identifier.
This trait requires the has-position trait, and discrete hardware must support all of the 'normal' methods such as set_position and get_destination.
Hardware with this trait simply offer an additional identifier mapping on top of the existing position and destination behavior.
A convinience method 'set_identifier' allows clients to provide identifiers instead of raw positions, if desired.
"""
requires = ["has-position"]

[config]
[config.identifiers]
doc = "Position identifiers"
type = {"type" = "map", "values" = "double"}
default = {}

[state]

[state.position_identifier]
doc = "Current position identifier."
type = ["null", "string"]
default = "__null__"

[messages]

[messages.get_position_identifiers]
doc = "Get position identifiers. Identifiers may not change at runtime."
response.type = "map"
response.values = "double"

[messages.set_identifier]
doc = "Set using an identifier. Returns new destination."
request = [
  {"name"="identifier", "type"="string"}
]
response = "double"

[messages.get_identifier]
doc = "Get current identifier string. Current identifier may be None."
response = ["null", "string"]

[fields]

[fields.position_identifier]
type = "record"
name = "field"
fields = {"getter"="get_identifier", "setter"="set_identifier", "dynamic"=true, "kind"="hinted", "type"="string"}

[fields.position_identifiers]
type = "record"
name = "field"
fields = {"getter"="get_position_identifiers", "dynamic"=false, "kind"="normal", "type"={"type"="map", "values"="double"}}
