Search

Dark theme | Light theme

July 11, 2022

DataWeave Delight: Using Literal Types

DataWeave has a nice language feature called literal types. Literal types are types with a single predefined values and can be defined using a String, Number or Boolean value. So the value of a literal type is a fixed value. We can combine multiple literal types into a new type using a union type to define an enumaration in DataWeave. The enumaration can only be one of the literal types used to define it.
Together with overloaded functions literal types are very useful. We can define a function where one of the input arguments is a literal type to define specific behaviour based on the literal type. Then we can overload the function for other literal types with different behaviour. DataWeave will make sure the correct function is called based on the value of the input argument and how it matches to the literal type value.

In the following example we define four new literal types (North, East, South, West), use a union type to define the enumaration Compass and the overloaded function direction:

Source

%dw 2.0

import capitalize from dw::core::Strings

// String based literal types with one value.
type North = "north"
type East = "east"
type South = "south"
type West = "west"

// Using union types we can use several literal
// types to define a new type like an enumeration.
type Compass = North | East | South | West

// Simple function that will be invoked if the input
// argument is either "north" or "south".
fun direction(direction: North | South): String = 
    "You are walking to " ++ 
    // We can still use String functions, 
    // because the base literal type is String.
    capitalize(direction) ++ 
    " pole."

// Overloaded function to "catch" the other values
// for the literal type Compass: "east" and "west".    
fun direction(direction: Compass): String = "Where are you going?"

// Simple data structure with String values.
var data = { up: "NORTH", right: "EAST", down: "SOUTH", left: "WEST" }

output application/json
---
{
    north: direction("north"),
    east: direction("east"),

    // We can coerce a String value into a literal type.
    south: direction(lower(data.down) as Compass),
    west: direction(lower(data.left) as Compass)
}

Output

{
    "north": "You are walking to North pole.",
    "east": "Where are you going?",
    "south": "You are walking to South pole.",
    "west": "Where are you going?"
}

In the following example we use Number and Boolean literal types. Instead of defining them explicitly as types we use the literal type in the function definitions directly:

Source

%dw 2.0

// Overloaded functions with literal types defined 
// directly at the argument level of the function.
// Here we use a Number literal type.
fun displayItems(items: 0) = "You have no items"
fun displayItems(items: 1) = "You have 1 item"
fun displayItems(items: Number) = "You have " ++ items ++ " items"

// Also Boolean literal types are supported.
// We can combine default argument values
// and overloaded functions.
fun message(value: String, debug: true) = "value - " ++ message(value)
fun message(value: String, debug: Boolean = false) = value

output application/json
---
{
    items0: displayItems(0),
    items1: displayItems(1),
    items10: displayItems(10),

    message: message("DataWeave literal types"),
    messageWithDebug: message("DataWeave literal types", true)
}

Output

{
    "items0": "You have no items",
    "items1": "You have 1 item",
    "items10": "You have 10 items",
    "message": "DataWeave literal types",
    "messageWithDebug": "value - DataWeave literal types"
}   

Written with DataWeave 2.4.