Operators and functions to use in Cedar

This topic describes the built-in operators and functions that you can use to build your expressions using the Cedar policy language.

Topics on this page

Overview of operators

The operators use the following syntax structures:

  • Unary operators – A unary operator takes one operand. Place the operand after the operator.

    <operator> operand
      
    // Uses the logical NOT operator and evaluates to the 
    // inverse of the value of the Boolean operand
    ! a
    
  • Binary operators – A binary operator takes two operands. Place one operand before the operator and one after. Some binary operators are commutative. See the description of each operator to understand where operand order matters.

    firstOperand <operator> secondOperand
      
    // Evaluates to true if both operands have the same type and value
    a == b
      
    // Evaluates to true if the first operand is within the 
    // hierarchy of the second operand
    c in d
    

Functions use the following syntax:

  • Functions can support zero or more operands. Append the function name to the end of the entity name, separating them with a . (period) character. Place any operands in parentheses after the function name, separating them with commas.

    entity.function(firstOperand, secondOperand, …)
      
    // Evaluates to true if the any of the set member 
    // elements b, c, or d is an element of set a
    a.containsAny([b, c, d])
    

String operators and functions

Use these operators and functions to compare strings or convert them to other types.

like (string matching with wildcard)

Usage: <string> like <string with wildcards>

Binary operator that evaluates to true if the string in the left operand matches the pattern string in the right operand. The pattern string can include one or more asterisks (*) as wildcard characters that match 0 or more of any character.

To match a literal asterisk character, use the escaped \* sequence in the pattern string.

Consider a query with the following context:

"context": {
    "location": "s3://bucketA/redTeam/some/thing/*"
}

In that scenario, the following expression returns true.

context.location like "s3:*"         //true

More Examples:

"eggs" like "ham*"                                             //false
"eggs" like "*ham"                                             //false
"eggs" like "*ham*"                                            //false
"ham and eggs" like "ham*"                                     //true
"ham and eggs" like "*ham"                                     //false
"ham and eggs" like "*ham*"                                    //true
"ham and eggs" like "*h*a*m*"                                  //true
"eggs and ham" like "ham*"                                     //false
"eggs and ham" like "*ham"                                     //true
"eggs, ham, and spinach" like "ham*"                           //false
"eggs, ham, and spinach" like "*ham"                           //false
"eggs, ham, and spinach" like "*ham*"                          //true
"Gotham" like "ham*"                                           //false
"Gotham" like "*ham"                                           //true
"ham" like "ham"                                               //true
"ham" like "ham*"                                              //true
"ham" like "*ham"                                              //true
"ham" like "*h*a*m*"                                           //true
"ham and ham" like "ham*"                                      //true
"ham and ham" like "*ham"                                      //true
"ham" like "*ham and eggs*"                                    //false
"\\afterslash" like "\\*"                                      //true
"string\\with\\backslashes" like "string\\with\\backslashes"   //true
"string\\with\\backslashes" like "string*with*backslashes"     //true
"string*with*stars" like "string\*with\*stars"                 //true

decimal() (parse string and convert to decimal)

Usage: decimal(<string>)

Function that parses the string and tries to convert it to type decimal. If the string doesn’t represent a valid decimal value, it generates an error.

To be interpreted successfully as a decimal value, the string must contain a decimal separator (.) and at least one digit before and at least one digit after the separator. There can be no more than 4 digits after the separator. The value must be within the valid range of the decimal type, from -922337203685477.5808 to 922337203685477.5807.

Examples:

decimal("1.0")
decimal("-1.0")
decimal("123.456")
decimal("0.1234")
decimal("-0.0123")
decimal("55.1")
decimal("00.000")
decimal("1234")                  //error
decimal("1.0.")                  //error
decimal("1.")                    //error
decimal(".1")                    //error
decimal("1.a")                   //error
decimal("-.")                    //error
decimal("1000000000000000.0")    //overflow
decimal("922337203685477.5808")  //overflow
decimal("0.12345")               //error
decimal("0.00000")               //error

ip() (parse string and convert to ipaddr)

Usage: ip(<string>)

Function that parses the string and attempts to convert it to type ipaddr. If the string doesn’t represent a valid IP address or range, then it generates an error.

ip("127.0.0.1")
ip("::1")
ip("127.0.0.1/24")
ip("ffee::/64")
ip("ff00::2")
ip("::2")

ip("380.0.0.1")                     //error – invalid IPv4 address
ip("ab.ab.ab.ab")                   //error – invalid IPv4 address
ip("127.0.0.1/8/24")                //error – invalid CIDR notation
ip("fee::/64::1")                   //error – invalid IPv6 address
ip("fzz::1")                        //error – invalid character in address
ip([127,0,0,1])                     //error – invalid type 
"127.0.0.1".ip()                    //error – invalid call style

ip("127.0.0.1") == ip("127.0.0.1")            //true
ip("192.168.0.1") == ip("8.8.8.8")            //false
ip("192.168.0.1/24") == ip("8.8.8.8/8")       //false
ip("192.168.0.1/24") == ip("192.168.0.8/24")  //true
ip("127.0.0.1") == ip("::1")                  //false – different IP versions
ip("127.0.0.1") == "127.0.0.1"                //false – different types
ip("::1") == 1                                //false – different types
ip("127.0.0.1") == ip("192.168.0.1/24")       //false - address compared to range
ip("127.0.0.1") < ip("10.0.0.10")             //error – invalid data types for < operator

Comparison operators and functions

Use these operators to compare two values as an expression. An expression that uses one of these operators evaluates to a Boolean true or false. You can then combine multiple expressions using the logical operators.

== (equality)

Usage: <any type> == <any type>

Binary operator that compares two operands of any type and evaluates to true only if they are exactly the same type and the same value. If the operands are of different types, the result is always false.

Examples:

1 == 1                          //true
5 == "5"                        //false
"something" == "something"      //true
"Something" == "something"      //false
[1, -33, 707] == [1, -33]       //false
[1, 2, 40] == [1, 2, 40]        //true
[1, 2, 40] == [1, 40, 2]        //true
[1, -2, 40] == [1, 40]          //false
[1, 1, 1, 2, 40] == [40, 1, 2]  //true
[1, 1, 2, 1, 40, 2, 1, 2, 40, 1]== [1, 40, 1, 2]   //true
true == true                    //true
context.device_properties == {"os ":"Windows ", "version":11} 
                                //true if context.device_properties represents a Windows 11 computer
A == A                          //true even if A is an entity that doesn't exist
User::"alice" == User::"bob"    //false -- two different objects of same type
User::"alice" == Admin::"alice" //false -- objects of two different types
"alice" == User::"alice         //false -- string versus entity

!= (inequality)

Usage: <any type> != <any type>

Binary operator that compares two operands of any type and evaluates to true if the operands have different values or are of different types. You can use != only in when and unless clauses.

Example:

forbid (principal, action, resource)
when{
    resource.tag != "public"
};

< (long integer ‘less than’)

Usage: <long> < <long>

Binary operator that compares two long integer operands and evaluates to true if the left operand is numerically less than the right operand.

Examples:

3 < 303               //true
principal.age < 22    //true (assume principal.age is 21)
3 < "3"               //type error
false < true          //type error
"some" < "thing"      //type error
"" < "zzz"            //type error
"" < ""               //type error
[1, 2] < [47, 0]      //type error

.lessThan() (decimal ‘less than’)

Usage: <decimal>.lessThan(<decimal>)

Function that compares two decimal operands and evaluates to true if the left operand is numerically less than the right operand.

Examples:

decimal("1.23").lessThan(decimal("1.24"))     //true
decimal("1.23").lessThan(decimal("1.23"))     //false
decimal("123.45").lessThan(decimal("1.23"))   //false
decimal("-1.23").lessThan(decimal("1.23"))    //true
decimal("-1.23").lessThan(decimal("-1.24"))   //false

<= (long integer ‘less than or equal’)

Usage: <long> <= <long>

Binary operator that compares two long integer operands and evaluates to true if the left operand is numerically less than or equal to the right operand.

Examples:

3 <= 303               // true
principal.age <= 21    // true (assume principal.age is 21)
3 <= "3"               // type error
false <= true          // type error
"some" <= "thing"      // type error
"" <= "zzz"            // type error
"" <= ""               // type error
[1, 2] <= [47, 0]      // type error

.lessThanOrEqual() (decimal ‘less than or equal’)

Usage: <decimal>.lessThanOrEqual(<decimal>)

Function that compares two decimal operands and evaluates to true if the left operand is numerically less than or equal to the right operand.

Examples:

decimal("1.23").lessThanOrEqual(decimal("1.24"))    // true
decimal("1.23").lessThanOrEqual(decimal("1.23"))    // true
decimal("123.45").lessThanOrEqual(decimal("1.23"))  // false
decimal("-1.23").lessThanOrEqual(decimal("1.23"))   // true
decimal("-1.23").lessThanOrEqual(decimal("-1.24"))  // false

> (long integer ‘greater than’)

Usage: <long> > <long>

Binary operator that compares two long integer operands and evaluates to true if the left operand is numerically greater than the right operand.

Examples:

3 > 303                // false
principal.age > 22     // false (assume principal.age is 21)
3 <= "3"               // type error
false <= true          // type error
"some" <= "thing"      // type error
"" <= "zzz"            // type error
"" <= ""               // type error
[1, 2] <= [47, 0]      // type error

.greaterThan() (decimal ‘greater than’)

Usage: <decimal>.greaterThan(<decimal>)

Function that compares two decimal operands and evaluates to true if the left operand is numerically greater than the right operand.

Examples:

decimal("1.23").greaterThan(decimal("1.24"))    // false
decimal("1.23").greaterThan(decimal("1.23"))    // false
decimal("123.45").greaterThan(decimal("1.23"))  // true
decimal("-1.23").greaterThan(decimal("1.23"))   // false
decimal("-1.23").greaterThan(decimal("-1.24"))  // true

>= (Long integer ‘greater than or equals’)

Usage: <long> >= <long>

Binary operator that compares two long integer operands and evaluates to true if the left operand is numerically greater than or equal to the right operand.

Examples:

3 >= 303               //false
principal.age >= 21    //true (assume principal.age is 21)
3 >= "3"               //type error
false >= true          //type error
"some" >= "thing"      //type error
"" >= "zzz"            //type error
"" >= ""               //type error
[1, 2] >= [47, 0]      //type error

.greaterThanOrEqual() (decimal ‘greater than or equal’)

Usage: <decimal>.greaterThanOrEqual(<decimal>)

Function that compares two decimal operands and evaluates to true if the left operand is numerically greater than or equal to the right operand.

Examples:

decimal("1.23").greaterThanOrEqual(decimal("1.24"))    //false
decimal("1.23").greaterThanOrEqual(decimal("1.23"))    //true
decimal("123.45").greaterThanOrEqual(decimal("1.23"))  //true
decimal("-1.23").greaterThanOrEqual(decimal("1.23"))   //false
decimal("-1.23").greaterThanOrEqual(decimal("-1.24"))  //true

Logical operators

Use these operators on Boolean values or expressions.

&& (AND)

Usage: <Boolean> && <Boolean>

Binary operator that evaluates to true only if both arguments are true.

In the following policy, the when condition is true if both principal.numberOfLaptops < 5 and principal.jobLevel > 6 are true.

permit (principal, action == Action::"remoteAccess", resource)
when {
    principal.numberOfLaptops < 5 &&
    principal.jobLevel > 6
};

The && operator uses short circuit evaluation. If the first argument is false, then the expression immediately evaluates to false and the second argument isn’t evaluated. This approach is useful when the second argument might result in an error if evaluated. You can use the first argument to test that the second argument is a valid expression.

The following policy allows only if the principal has the attribute level and the level > 5.

permit (principal, action == Action:"read", resource)
when {
    principal has level &&
    principal.level > 5
};

The second comparison in this expression is valid only if the numberOfLaptops property for the principal entity has a value. If it doesn’t, the less than operator generates an error. The first expression uses the has operator to ensure that the principal entity does have such a property with a value. If that evaluates to false, then the second expression isn’t evaluated.

More Examples:

false && 3          //false
(false && 3) == 3   //false, short-circuiting
true && 3           //type error
3 && false          // type error

|| (OR)

Usage: <Boolean> || <Boolean>

Binary operator that evaluates to true if either one or both arguments are true.

This operator uses short circuit evaluation. If the first argument is true, then the expression immediately evaluates to true and the second argument isn’t evaluated. This approach is useful when the second argument might result in an error if evaluated. The first argument should be a test that can determine if the second argument is a valid expression. For example, consider the following expression. It evaluates to true if the principal can’t be confirmed to at least 21 years old and principal is either missing the age property or that property is set to a value less than 21.

!(principal has age) || principal.age < 21 

The second comparison in this expression is valid only if the age property for the principal entity is present. If it is missing, the less than operator generates an error. The first expression uses the has operator, inverted by the ! NOT operator, to flag that the principal entity is missing the age property. If that evaluates to true, there is no test of the second expression.

The following policy allows if either resource.owner == principal or resource.tag == "public" is true.

permit (principal, action == Action:"read", resource)
when {
    resource.owner == principal ||
    resource.tag == "public"
};

More Examples:

true || 3                  //true, short-circuiting
false || 3                 //type error
3 || true                  //type error
(true || 3) == 3           //false, short-circuiting
(true || 3 || true) == 3   //false, short-circuiting

! (NOT)

Usage: ! <Boolean>

Unary operator with only one argument. It inverts the value of the Boolean operand from true to false, or from false to true.

Example:

The following policy forbids if the principal does not belong to Group::”family”.

forbid (principal, action, resource)
when {
    !(principal in Group::"family")
};

You can rewrite the above policy using an unless clause as:

forbid (principal, action, resource)
unless {
  principal in Group::"family"
};

More Examples:

! true                                // false
! false                               // true
! 8                                   // type error
if !true then "hello" else "goodbye"  // "goodbye"

if (CONDITIONAL)

Usage: if <Boolean> then <T> else <U>

The if operator returns its evaluated second argument if the first argument evaluates to true, else it returns the evaluated third argument.

The if operator requires its first argument to be a boolean, i.e., to evaluate to either true or false. If it does not, the evaluator issues a type error. The second and third arguments can have any type; to be compatible with validation, both arguments must have the same type.

In the following policy, the when condition is true if both principal.numberOfLaptops < 5 and principal.jobLevel > 6 are true.

permit (principal, action == Action::"remoteAccess", resource)
when {
    if principal.numberOfLaptops < 5 then
      principal.jobLevel > 6
    else false
};

The if operator uses short circuit evaluation. When the first argument evaluates to true the third argument is never evaluated. When the first argument evaluates to false, the second argument is never evaluated.

The if operator is a strict generalization of the && and || operators. The expression e1 || e2 is equivalent to the expression if e1 then true else (if e2 then true else false). The expression e1 && e2 is equivalent to the expression if e1 then (if e2 then true else false) else false. Note that e1 || e2 is not equivalent to if e1 then true else e2, due to the possibility of type errors. To see why, consider that false || "foo" produces a type error, while if false then true else "foo" evaluates to "foo".

Note that if and when, though similar in normal English, play different roles in Cedar. The keyword when is part of the policy syntax which simply connects the policy scope to the policy’s condition(s). The keyword if is a part of an expression that can be contained in such a condition, and can be evaluated against a relevant authorization request.

More Examples:

if 1 == 1 then "ok" else "wrong"         //"ok"
if 1 == "foo" then User::"foo" else "ok" //"ok"
if 1 then "wrong" else "wrong"           //type error
if false then (1 && "hello") else "ok"   //"ok"
if true then (1 && "hello") else "ok"    //type error

Notice that the fourth example does not have a type error because it short-circuits evaluation of the second argument. The second example’s second and third arguments do not have the same type; this is fine for evaluation, but a policy with an expression like this will fail to validate.

Arithmetic operators

Use these operators to perform arithmetic operations on long integer values.

Notes
The arithmetic operators support only values of type Long. They don’t support values of type Decimal. There is no operator for arithmetic division.

If you exceed the range available for the Long data type by using any of the arithmetic operators, it results in an overflow error. A policy that results in an error is ignored, meaning that a Permit policy might unexpectedly fail to allow access, or a Forbid policy might unexpectedly fail to block access.

+ (Numeric addition)

Usage: <long> + <long>

Binary operator that adds the two long integer values and returns a long integer sum.

Example:

The following policy returns allow if the context budget minus the context downloaded is greater than 100.

permit (principal, action, resource)
when {
    context.budget - context.downloaded > 100
};

Other examples:

11 + 0                              // 11
-1 + 1                              // 0
9,223,372,036,854,775,807 + 1       //overflow
-9,223,372,036,854,775,808 - 1 + 3  //overflow
7 + "3"                             //type error
"lamp" + "la"                       //type error - no support for string concatenation

- (Numeric subtraction or negation)

Usage: <long> - <long>

As a binary operator with two operands, it subtracts the second long integer value from the first and returns a long integer difference.

Examples:

44 - 31                             // 13
5 - (-3)                            // 8
-9,223,372,036,854,775,808 - 1 + 3  // overflow

Usage: - <long>

As a unary operator with one operand, it returns the negative of the value.

Examples:

-3

* (Numeric multiplication)

Usage: <long> * <long>

Binary operator that multiplies two long integer values and returns a long integer product. One of the values must be an integer literal, the other value can be an integer literal or an expression that evaluates to an integer value.

There is no operator for arithmetic division.

Examples:

10 * 20                          // 200
resource.value * 10             // valid
2 * context.budget > 100         // valid
context.budget * context.limit   // not valid. One operand must be a constant
9223372036854775807 * 2          // overflow
5 * (-3)                         // -15
5 * 0                            // 0
"5" * 0                          // type error

Hierarchy and set membership operators and functions

Use these functions to test if entities are members of a hierarchy or a set.

in (Hierarchy membership)

Usage: <entity> in <entity>

Boolean operator that evaluates to true if the entity in the left operand is a descendant in the hierarchy under the entity in the right operand.

The in operator is transitive. If A is in B, and B is in C, then A is also in C. This approach allows you to model the concept of a multi-tier hierarchy, for example nesting folders in other folders.

The in operator is reflexive; If the right operand is a single entity, then the expression evaluates to true if the right entity is the same as the left entity. In other words, an entity is always in its own hierarchy. A is always in A.

Usage: <entity> in set(<entity>, <entity>, ...)

Examples:

For example, assume that the principal in a request is User::"12345"

principal in User::"12345"     // true - testing if a value is in itself always returns true
principal in [User::"12345"]   // true - testing if a value is in a set consisting of only itself always returns true
principal in Group::"67890"    // true if User::"12345" belongs to Group::"67890"
principal in [Group::"67890"]  // true if User::"12345" belongs to Group::"67890"

More examples:

Consider the following set of entities:

Example entities

User::"jane" in User::"jane"           // true - `in` is reflexive
User::"bob" in Group::"jane_friends"   // true - Group::"jane_friends" is an ancestor of User::"bob".
User::"john" in Group::"jane_friends"  // false - User::"john"'s only ancestor is Group"jane_coworkers".

If the right operand is a set of entities, then the expression is evaluated for each member in the set. For example, consider the following expression.

A in [ B, C, D ]

That expression is evaluated as component expressions joined by the logical OR operator, as shown in the following example.

A in B || A in C || A in D 

If any one or more of the component expressions evaluates to true, then the overall expression evaluates to true.

User::"bob" in [Group::"jane_friends"] // true
User::"alice" in [ 
    Group::"jane_family", 
    Group::"jane_friends "
]                                      // true - User::"Alice" is a member of Group::"jane_friends"
User::"alice" in [
    User::"bob", 
    User::"alice"
]                                      // true - User::"alice" in User::"alice"
User::"john" in [
    Group::"jane_family",
    Group::"jane_friends"
]                                      // false - User::"john" isn't a member of any entities in the set

The right operand of in can be any expression that returns a set of entity references, not just a set literal. For example, suppose the query context contains the following:

{
    "groups ": [Group::"jane_family", Group::"jane_friends "]
}

Then the following two expressions in a policy statement are equivalent:

User::"alice" in context.groups 
User::"alice" in [Group::"jane_family", Group::"jane_friends"]

However, the following expression raises a type error because “Team” is a string, not an entity reference.

User::"alice" in [User::"alice", Group::"jane_friends", "Team"]   // type error

Because the in operator is reflexive, A in A returns true even if the entity A does not exist. The evaluator treats entity references that are not in the hierarchy as a valid entity. For example:

Stranger::"jimmy" in Stranger::"jimmy"        // true by reflexivity.
Stranger::"jimmy" in Group::"jane_friends"    // false - Stranger::"jimmy" does not refer to an existing entity
Stranger::"jimmy" in [
    Group::"jane_family",
    Stranger::"jimmy"
]                                             // true - Stranger::"jimmy" in Stranger::"jimmy" is true

More Examples:

"some" in ["some", "thing"] //type error - these are strings, not entities. For strings, use `contains` for set membership.
"os" in {"os":"Windows "}   //type error - use `has` operator to check if a key exists

has (presence of attribute test)

Usage: <entity> has <attribute>

Boolean operator that evaluates to true if the left operand has a value defined for the specified attribute. Use this operator to check that a value is present before accessing that value. If you attempt to access a value that isn’t defined, then Cedar generates an error.

The following example expression first tests whether the entity A has a defined attribute B. Because the && operator uses shortcut logic, the second expression is evaluated and the attribute accessed only if the attribute is present.

A has B && A.B == 5

In the following example, assume that the request has the following context:

"context":{
    "role": ["admin", "user"],
    "addr": { "street": "main", "city": "DC"}
    "owner info": { "name": "Alice", "age": 18 }
}

The following condition checks if the context has an attribute role. If the attribute exists, then it checks if it is a set containing the string "admin" as an element.

context has role && context.role.contains("admin")       //true

The attribute name role can be written as an identifier (as in the previous example) or as a string literal. The following expression is equivalent to the previous one:

context has "role" && context.role.contains("admin")     //true

You must check for presence of optional attributes that are nested multiple layers one at a time. For example, to check for the presence of principal.custom.project, you must first check if principal has a custom attribute. You can then check to see if that custom attribute has a project attribute. To do this, you could use the following syntax.

principal has custom && principal.custom has project 

If the attribute name is not valid as an identifier, then the string literal syntax must be used for has and attribute values must be accessed with the [] operator instead of using dot syntax. For example, to check if context has an attribute called owner info (with an embedded space), then you could use the following syntax.

context has "owner info" && context["owner info"].name == "Alice"    //true

The following expression returns false because context doesn’t have an attribute tag.

context has tag      //false

The following expression returns a type error because the left-hand side of the has operator must be an entity or a record. In this example, because role is a set, Cedar generates a type error.

context.role has admin     //type error

The following expression returns false because the addr sub-record does not have an attribute country. The second expression is not evaluated.

context.addr has country && context.addr.country == "US "    //false

However, consider the case where context does not have the addr sub-record at all:

"context": {
    "role": ["admin", "user"]
}

In that case, then the previous expression that checks for context.addr has country raises a missing-attribute error on context.addr before the has operator is even evaluated, and the entire policy is skipped. If the addr sub-record is optional, you can avoid this error by checking whether addr is present before accessing it with the . operator:

context has addr && context.addr has country && context.addr.country == "US"  // false, with no error

.contains() (single element set membership test)

Usage: <set>.contains(<entity>)

Function that evaluates to true if the operand is a member of the receiver on the left side of the function. The receiver must be of type set.

Examples:

[1,2,3].contains(1)                             // true
[1,"something",2].contains(1)                   // true
[1,"something",2].contains("Something")         // false - string comparison is case-sensitive
["some", "useful", "tags"].contains("useful")   // true
[].contains(100)                                // false
context.role.contains("admin")                  // true if the set `role` contains the string "admin"
[User::"alice"].contains(principal)             // true if principal == User::"alice"
"ham and ham".contains("ham")                   // type error - 'contains' is not allowed on strings

.containsAll() (all element set membership test)

Usage: <set>.containsAll(<set>)

Function that evaluates to true if every member of the operand set is a member of the receiver set. Both the receiver and the operand must be of type set.

[1, -22, 34].containsAll([-22, 1])                           // true
[1, -22, 34].containsAll([-22])                              // true
[43, 34].containsAll([34, 43])                               // true
[1, -2, 34].containsAll([1, -22])                            // false
[1, 34].containsAll([1, 101, 34])                            // false
[false, 3, [47, 0], "some"].containsAll([3, "some"])         // true
[false, 3, [47, 0], {"2": "ham"}].containsAll([3, {"2": "ham"}])  // true
[2, 43].containsAll([])                                      // true
[].containsAll([2, 43])                                      // false
[false, 3, [47, 0], "thing"].containsAll("thing")            // type error - operand a string
"ham and eggs".containsAll("ham")                            // type error - prefix and operand are strings
{"2": "ham", "3": "eggs "}.containsAll({"2": "ham"})         // type error - prefix and operand are records

.containsAny() (any element set membership test)

Usage: <set>.containsAny(<set>)

Function that evaluates to true if any one or more members of the operand set is a member of the receiver set. Both the receiver and the operand must be of type set.

[1, -22, 34].containsAny([1, -22])                             // true
[1, -22].containsAny([1, -22, 34])                             // true
[-22].containsAny([1, -22, 34])                                // true
[1, 101].containsAny([1, -22, 34])                             // true
[1, 101].containsAny([-22, 34])                                // false
["alice","bob","charlie"].containsAny(["david","bob","juan"])  // true
[].containsAny(["bob"])                                        // false
["bob"].containsAny([])                                        // false
"ham".containsAny("ham and eggs")                              // type error - operand is a string
{"2": "ham"}.containsAny({"2": "ham", "3": "eggs "})           // type error - prefix and operands are records

IP address functions

Use these functions to test characteristics of IP addresses and ranges.

.isIpv4() (IPv4 address valid test)

Usage: <ipaddr>.isIpv4()

Evaluates to true if the receiver is an IPv4 address. This function takes no operand.

ip("127.0.0.1").isIpv4()     //true
ip("::1").isIpv4()           //false
ip("127.0.0.1/24").isIpv4()  //true

.isIpv6() (IPv6 address valid test)

Usage: <ipaddr>.isIpv6()

Function that evaluates to true if the receiver is an IPv6 address. This function takes no operand.

ip("127.0.0.1/24").isIpv6()  //false
ip("ffee::/64").isIpv6()     //true
ip("::1").isIpv6()           //true

.isLoopback() (test for IP loopback address)

Usage: <ipaddr>.isLoopback()

Function that evaluates to true if the receiver is a valid loopback address for its IP version type. This function takes no operand.

ip("127.0.0.2").isLoopback()  //true
ip("::1").isLoopback()        //true
ip("::2").isLoopback()        //false

.isMulticast() (test for multicast address)

Usage: <ipaddr>.isMulticast()

Function that evaluates to true if the receiver is a multicast address for its IP version type. This function takes no operand.

ip("127.0.0.1").isMulticast()  //false
ip("ff00::2").isMulticast()    //true

.isInRange() (test for inclusion in IP address range)

Usage: <ipaddr>.isInRange(<ipaddr>)

Function that evaluates to true if the receiver is an IP address or a range of addresses that fall completely within the range specified by the operand.

ip("192.168.0.1").isInRange(ip("192.168.0.1/24"))   //true
ip("192.168.0.1").isInRange(ip("192.168.0.1/28"))   //true
ip("192.168.0.75").isInRange(ip("192.168.0.1/24"))  //true
ip("192.168.0.75").isInRange(ip("192.168.0.1/28"))  //false
ip("1:2:3:4::/48").isInRange(ip("1:2:3:4::"))       //true
ip("192.168.0.1").isInRange(ip("1:2:3:4::"))        //false