Values
Every value in CASC has a type the parser knows. Numbers, durations, sizes, dates and addresses arrive typed — nothing has to be parsed a second time by the application.
At a glance
| Type | Examples |
|---|---|
| nil, boolean | nil true false |
| integer | -17 1_000_000 0xDEAD_BEEF 0o755 0b1101 |
| float | 3.1415 5e+22 -2E-2 inf -inf |
| atom | info :info enabled? :nil |
| string | "escaped\n" 'literal' """multi-line""" |
| date, time | 1979-05-27 07:32:00 1979-05-27T07:32:00Z |
| IP address | 127.0.0.1 10.0.0.0/8 ::1 fe80::1/64 |
| duration | 500ms 1h30m 1.5h 2d |
| byte size | 512MiB 1.5GiB 10GB |
| list | [1, 2, 3] ["a" "b"] |
| tuple | (52.52, 13.405) |
Nil and booleans
nil, true and false are keywords. There is no null, yes or on: those are ordinary atoms.
flags = [nil, true, false, null, yes]
%{"flags" => [nil, true, false, :null, :yes]}Numbers
Integers take an optional sign and may be written in hexadecimal (0x), octal (0o) or binary (0b). Floats need digits on both sides of the point or an exponent; 1e3 is a float. _ separates digit groups anywhere. inf, +inf and -inf are the infinities.
n = [-17, +99, 0xDEAD_BEEF, 0o755, 0b1101, 1_000_000, 3.1415, 5e+22, -2E-2, inf, -inf]
%{"n" => [-17, 99, 3735928559, 493, 13, 1000000, 3.1415, 5.0e22, -0.02,
:infinity, :neg_infinity]}Atoms
A bare word in value position is an atom — a symbolic name, the way log levels and modes are usually written. A leading : is optional, and required to turn a reserved word into an atom.
levels = [info, :info, enabled?, ready!, handle-otp, :nil]
%{"levels" => [:info, :info, :enabled?, :ready!, :"handle-otp", nil]}Strings
Three forms, for three jobs:
"double"— escapes\n \r \t \" \\ \uXXXX, and interpolation of@{},${},%{},!{}and!tag(…).'single'— literal: no escapes, no interpolation. Good for patterns and anything full of backslashes."""triple"""— multi-line. The newline after the opening quotes is dropped and the common indentation removed, so the text can be indented with the file.
@who = "world"
greeting = "hello, @{who}\n"
pattern = '^\d+ @{not interpolated}$'
motd = """
Welcome to the service.
Status: operational
"""%{"greeting" => "hello, world\n",
"pattern" => "^\\d+ @{not interpolated}$",
"motd" => "Welcome to the service.\n Status: operational\n"}Dates and times
Unquoted ISO 8601: a date, a time with seconds (fractions allowed), or both joined by T. A date-time with Z or an offset is an instant, normalised to UTC; without one it is a local date-time.
at = [1979-05-27T07:32:00Z, 1979-05-27T07:32:00.999+02:00, 1979-05-27T07:32:00, 1979-05-27, 07:32:00.5]
%{"at" => [~U[1979-05-27 07:32:00Z], ~U[1979-05-27 05:32:00.999Z],
~N[1979-05-27 07:32:00], ~D[1979-05-27], ~T[07:32:00.5]]}IP addresses
IPv4 and IPv6 addresses are values, unquoted, each with an optional /prefix for a network. An octet above 255 is a load error, not a string.
allow = [127.0.0.1, 10.0.0.0/8, ::1/128, fe80::1]
Durations
A number followed directly by a unit: ns, us (or µs), ms, s, m, h, d. Units combine from largest to smallest, each once, with whole numbers; a single unit may have a fraction.
timeout = 500ms window = 1h30m same = 1.5h retention = 2d
%{"timeout" => {:duration, 500000000},
"window" => {:duration, 5400000000000},
"same" => {:duration, 5400000000000},
"retention" => {:duration, 172800000000000}}30m1h (ascending), 1h1h (repeated) and 1.5h30m (a fraction in a compound) are load errors.
Byte sizes
Decimal units B kB MB GB TB PB count in thousands, binary units KiB MiB GiB TiB PiB in 1024s. Units are case-insensitive; fractions are allowed.
sizes = [512MiB, 1.5GiB, 10GB, 1kib]
%{"sizes" => [{:bytes, 536870912}, {:bytes, 1610612736},
{:bytes, 10000000000}, {:bytes, 1024}]}Lists and tuples
A list […] holds any values; commas, spaces and newlines all separate elements, in any mix. A tuple (…) is a fixed group — a coordinate, a pair — and is always replaced as a whole, never merged.
hosts = [ "a.internal" "b.internal", "c.internal" ] office = (52.5200, 13.4050) matrix = [[1, 2], (3, 4)]
%{"hosts" => ["a.internal", "b.internal", "c.internal"],
"office" => {52.52, 13.405},
"matrix" => [[1, 2], {3, 4}]}