# Common Expression Language (CEL) Guide

> Octelium documentation. Canonical page: <https://octelium.com/docs/octelium/latest/management/guide/cel>.

Octelium *conditions* are based on the Common Expression Language (CEL). CEL expressions are used to easily write dynamic, context aware and performant one-liner conditions that evaluate a boolean value used to match a rule without having to actually have to learn a new programming language.

## Numbers

```bash
2 > 1
```

```bash
3 > 2 && 2 > 1
```

```bash
3 > 2 || 4 < 3
```

```bash
size([1,2,3]) == 3
```

```bash
[1,2,3].size() == 3
```

```bash
1 in [2,1,3]
```

```bash
((25 < 50) ? 'yes' : 'no') == 'yes'
```

```bash
int(3.14) == 3
```

```bash
uint(3.14) == 3u
```

```bash
int("3") == 3
```

## Strings

Strings have their own methods and functions. Here are some examples:

```bash
"group-1".startsWith("group")
```

```bash
"other-group".endsWith("group")
```

```bash
"one-more-group".contains("more")
```

```bash
"group-1" in ["group-1", "group-2", "group-3"]
```

```bash
"pet".size() == 3
```

```bash
["group-1", "group-3"].hasAny(["group-1", "group-2"])
```

```bash
["group-1", "group-2", "group-3"].hasAll(["group-1", "group-3"])
```

```bash
"City".toLower() == "city"
```

```bash
"City".toUpper() == "CITY"
```

```bash
"some_val".split("_")[0] == "some"
```

```bash
["hello", "mellow"].join() == "hellomellow"
```

```bash
"  \ttrim\n    ".trim() == "trim"
```

```bash
"tacocat".substring(4) == "cat"
```

```bash
"gums".reverse() == "smug"
```

```bash
"hello hello".replace("he", "we") == "wello wello"
```

```bash
"cairo".matches('^[a-z]{5}$')
```

```bash
"%s %s".format(["hello", "world"]) == "hello world"
```

```bash
'hello mellow'.indexOf('ello') == 1
```

```bash
'hello mellow'.lastIndexOf('ello') == 7
```

```bash
int("123") == 123
```

```bash
string(123) == "123"
```

```bash
string(3.14) == "3.14"
```

```bash
string(true) == "true"
```

```bash
bool("true")
```

```bash
'a' < 'b'
```

## Lists

Lists have their own methods that provides you with some important utilities. Here are some examples:

```bash
[1,2,3,4].min() == 1
```

```bash
[1,2,3,4].max() == 4
```

```bash
[1,2,3].all(i, i > 0)
```

```bash
["group-1", "group-2"].all(x, x.startsWith("group"))
```

```bash
["london", "paris", "berlin"].filter(x, x.contains("in"))[0] == "berlin"
```

```bash
["london", "paris"].exists(x, x.endsWith("is"))
```

```bash
[10, -10, 100].exists_one(x, x < 0)
```

```bash
[1,2,3].map(x, x*2)[2] == 6
```

## Maps

```bash
{'a': 10, 'b': 5, 'c': 20}.size() == 3
```

```bash
{'a': 1, 'b': 2, 'c': 3}.exists(key, key == 'b')
```

```bash
has({'a': 1, 'b':2}.a)
```

```bash
'key1' in {'key1': 'value1', 'key2': 'value2'}
```

```bash
{'id': 123, 'age': 42}['age'] == 42
```

## Math

```bash
math.least([2,1,3]) == 1
```

```bash
math.greatest([2,1,3]) == 3
```

```bash
math.abs(-1) == 1
```

## Time

Octelium provides you with the function `now()` to use the current timestamp. Also, the `timestamp()` function converts a RFC3339 time format to a timestamp. Moreover, you can use the `duration()` function to compare time durations. Here are some examples:

```bash
now() > timestamp(ctx.user.metadata.createdAt)
```

```bash
(now() - timestamp(ctx.user.metadata.createdAt)) > duration("12h")
```

```bash
duration('1h') == duration('60m')
```

```bash
duration("1.5h") - duration("-1.5h") == duration("3h")
```

```bash
timestamp('2024-04-21T12:00:00Z') <= timestamp('2025-02-26T12:00:00Z')
```

```bash
time.isWeekday(timestamp("2023-10-18T12:00:00Z"))
```

```bash
time.isWeekdayInTZ(timestamp("2023-10-22T23:00:00Z"), "Asia/Tokyo")
```

```bash
time.isWeekend(timestamp("2023-10-21T12:00:00Z"))
```

```bash
time.isWeekendInTZ(timestamp("2023-10-20T23:00:00Z"), "Asia/Tokyo")
```

## JSON

You can parse/unmarshal a JSON string as a map and use it in your logic. Here is an example:

```bash
json.parse('{"key1": "val1"}')["key1"] == "val1"
```

You can also marshal a JSON object to a string as follows:

```bash
json.marshal(json.parse('{"key1": "val1"}')) == '{"key1": "val1"}'
```

## Net

Octelium CEL engine supports a few network-specific functions as follows:

```bash
net.isIP("192.168.1.1")
```

```bash
net.isIPv4("10.0.0.1")
```

```bash
net.isIPv6("2001:db8::1")
```

```bash
net.isPrivateIP("10.5.0.1")
```

```bash
net.isIPInRange("192.168.1.50", "192.168.1.0/24")
```
