= The STRUCT keyword

.Syntax
----
STRUCT <name> <field> <value> [<flags>]
----

.Description
The `STRUCT` keyword defines a child structure of a previous `struct`,
which is keyed by a particular xref:dictionary/member.adoc[MEMBER].

Many protocols are defined as a _header_ which contains information
about the protocol, and a _data_ portion which contains data carried
by that _header_.  The _header_ usually includes a _type_ field, which
defines how the _data_ portion is interpreted.  The `STRUCT` keyword
allows the server to automatically decode these protocols, and all of
their contents.

<name>:: The name of the attribute.  The name can contain alphanumeric
characters, `-`, and `_`.  The name should be short and descriptive.
+
As the names are hierarchical, the name is scoped to its parent.  So
the name `Counter` can mean different things, depending on its
context.

<field>:: The name of a previous xref:dictionary/member.adoc[MEMBER]
which has been marked up with the word `key` in the `flags` field. 
+
In most cases, the _<field>_ reference is simply the name of a field
in the attribute of type `struct` which was defined immediately before
this definition.
+
The _<field>_ reference can also be an OID-style name, as in
`Client-Id.Type`.  The name is always looked up in the current dictionary.
References cannot be to fields in other dictionaries.

<value>:: When the _<field>_ has this value, the data is interpreted
as this `struct`.  Numbers can be specified as decimal (`19`), or as
hex (`0xffee`).

<flags>:: Can only be `length=uint8` or `length=uint16`.  When
encoding or decoding the structure, it is prefixed by a `uint8` or `uint16` field
containing the length of the structure.

Common flags and meanings
[options="header"]
[cols="30%,70%"]
|=====
| Name             | Description
| `length=uint8`   | When encoding or decoding the structure, it is prefixed by a `uint8` field containing the length of the structure.
| `length=uint16`  | When encoding or decoding the structure, it is prefixed by a `uint16` field containing the length of the structure.
| `offset=<number>` | When encoding or decoding the structure, add `number` to the value in the `length` field.
|=====


The following example shows how one structure can include another one.  In this example, the `Information` structure has two fields: `Type` and `Other`.  It has two possible sub-structures which can appear after the `Other` field.  Which sub-structure to be decoded is defined by the `key` field: `Type`.

.Example of a Key field
----
ATTRIBUTE Information 1 struct
MEMBER Type uint8 key
MEMBER Other uint32

STRUCT Foo Type 1
MEMBER Bar uint16
MEMBER Baz uint16

STRUCT Blag Type 2
MEMBER Whoops uint32
MEMBER Stuff uint8
----

== Caveats

Variable-sized fields such as `tlv`, `struct`, `string`, or `octets` can only be placed at the end of the `struct`.

// Copyright (C) 2023 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
