Skip to main content

OneOfs and Enumerations

A variety of enumerated constants are provided within the data model. For example, the OperStatus enumeration has named constants: UP, DOWN, TESTING, UNKNOWN, DORMANT, NOT_PRESENT, LOWER_LAYER_DOWN. These can be referenced using the enumeration name followed by the constant name. For example: OperStatus.UP or OperStatus.NOT_PRESENT.

Likewise, the data model contains several OneOf (also known as disjoint sum or tagged union) data types. A OneOf data type is essentially a tagged union of different types. It consists of several different possible types of values, distinguished by tags. For example, the data model defines a SubInterfaceVlan type with two different possible types of instances: VLAN_ID(v) (where v is a VlanID) and QINQ_ID(s) (where s is a string in a particular format).

Writing OneOf values is similar to writing enumerated values. The following are legal examples:

  • SubInterfaceVlan.VLAN_ID(123)
  • SubInterfaceVlan.QINQ_ID("1.2")

This is similar to enumerated contants, except that for enumerated constants there is no value in parentheses.

Consuming OneOf values, including enumerations is done via case-analysis using a when expression. The general form of a when expression is:

when expression is pattern1 -> expression1; pattern2 -> expression2; ...; patternN -> expressionN

Here, expression is the expression to be analyzed and must have a OneOf type (e.g. a variable holding an enum value). After the is keyword, there are any number of cases listed, where each case consists of a pattern, such as pattern1 and a case expression, such as expression1. The -> characters separate the pattern and the case expression, and must be present. The ; character separates consecutive cases, and must be present. The patterns pattern1, pattern2, ... patternN are matched against the expression in sequence. When one matches, the case expression for that pattern is used as the overall value of the when expression. There are three forms of patterns:

  • Con: matches values of the specific OneOf constructor Con. For example, VLAN_ID (one of the two possible SubInterfaceVlan constructors as shown above).
  • Con(var): matches values of the specific OneOf constructor Con. For example, VLAN_ID(vlanId). Also binds the value contained in the OneOf constructor to the variable var specified in the pattern. The case expression for this pattern is then evaluated with var in scope. This pattern form is only permitted when the OneOf constructor Con has a data value associated with it (e.g. this cannot be used to match against an enum value).
  • otherwise: matches any value. Can only appear as the final item in the list of cases. Useful when many of the cases compute the same result.

Here are some examples to illustrate when expressions, assuming that v is a variable in scope that has type SubInterfaceVlan:

  • when v is QINQ_ID(s) -> s + "!"; VLAN_ID -> "def"
    Performs case analysis on v, splitting into two different cases. The first case tries to match QINQ_ID values and if successful binds the value contained inside the QINQ_ID value as s and then returns s appended with an exclamation mark. The second case handles the VLAN_ID case, ignoring the data inside the VLAN_ID constructor ( unlike the first case).
  • when v is QINQ_ID -> "abc"; otherwise -> "def"
    Matches QINQ_ID values, ignoring the value inside the QINQ_ID constructor. The second case uses an otherwise pattern, to match the remaining values.