9 releases
Uses new Rust 2024
| new 0.2.0 | Nov 6, 2025 |
|---|---|
| 0.1.1 | Nov 2, 2025 |
| 0.0.25 | Apr 29, 2025 |
#294 in Text processing
46 downloads per month
Used in 3 crates
(2 directly)
140KB
2.5K
SLoC
PHS – Phlow Script
PHS (Phlow Script) é um formato de script leve para Phlow, baseado em Rhai. Permite lógica dinâmica, manipulação de dados e integração profunda com módulos Phlow, tudo em arquivos .phs.
✨ Visão Geral
PHS traz o poder do scripting embutido para workflows YAML, permitindo lógica dinâmica, manipulação de variáveis, funções, arrays, objetos e integração com módulos Rust customizados.
Scripts .phs podem ser importados em flows Phlow via !import, e têm acesso global aos módulos declarados no YAML.
📑 Sumário
- ✨ Visão Geral
- 🔌 Injeção de Módulos via YAML
- 🧪 Exemplo
- 📁 Extensões de Arquivo
- 🔐 Módulos Suportados
- 🧠 Variáveis
- 🧱 Arrays e Objetos (Maps)
- 🧭 Condicionais
- 🔁 Loops
- 🧩 Funções
- 🧬 Sintaxe e Recursos
🔌 Injeção de Módulos via YAML
Todos os módulos declarados em modules: no YAML ficam disponíveis globalmente no script .phs.
🧪 Exemplo
main.phlow
main: cli
modules:
- module: cli
- module: log
steps:
- return: !import script.phs
script.phs
log("warn", `Hello, ${main.name}`);
// or
log({
level: "warn",
message: `Hello, ${main.name}`
});
📁 Extensões de Arquivo
Phlow carrega scripts .phs via !import e executa com engine Rhai estendida.
� Módulos Suportados
Qualquer módulo com bindings de scripting pode ser usado: log, cli, http_server, etc.
🧠 Variáveis
Declare variáveis com let:
let nome = main.name;
let saudacao = "Olá";
let mensagem = `${saudacao}, ${nome}!`;
log("info", mensagem);
Reatribuição:
let cont = 1;
cont = cont + 1;
Funções podem retornar valores:
let status = "warn";
let msg = "Algo aconteceu";
log(status, msg);
🧱 Arrays e Objetos (Maps)
Arrays:
let frutas = ["maçã", "banana", "laranja"];
frutas.push("uva");
Objetos:
let usuario = #{ nome: main.name, idade: 30 };
usuario.idade = 31;
usuario.status = "online";
Nesting:
let config = #{ tags: ["dev"], options: #{ retries: 3 } };
🧭 Condicionais
if main.name == "Philippe" {
log("info", "Bem-vindo!");
} else if main.name == "Alice" {
log("info", "Oi Alice!");
} else {
log("info", "Olá, visitante!");
}
🔁 Loops
for fruta in frutas {
log("info", `Fruta: ${fruta}`);
}
for i in 0..5 {
log("debug", `Índice: ${i}`);
}
🧩 Funções
Defina funções com fn:
fn saudacao(nome) {
log("info", `Olá, ${nome}!");
}
saudacao("Philippe");
Funções podem retornar valores:
fn dobro(n) { return n * 2; }
let resultado = dobro(5);
🧬 Sintaxe e Recursos
Tipos suportados: bool, string, int, float, array, null, map, fn Operadores: +, -, *, /, %, ==, !=, <, >, <=, >=, &&, ||, ! Escopo global: main, modules, funções utilitárias
Expressões & Ternário
let msg = when main.name == "" ? "Anônimo" : `Olá, ${main.name}`;
Funções de String
search(pattern)— regexstarts_with(prefix)— prefixoreplace(target, replacement)— substituiçãoslice(start, end)/slice(start)— substringcapitalize()— primeira letra maiúsculato_snake_case(),to_camel_case(),to_kebab_case()— conversão de caseto_url_encode()— codificação URLto_base64()— codificação Base64base64_to_utf8()— decodificação Base64url_decode()— decodificação URL
Conversão de Tipos
let numero = "42".to_int();
let flag = "true".to_bool();
Manipulação de Maps & Arrays
let chaves = usuario.keys();
if frutas.contains("banana") { log("info", "Achou!"); }
Debug
log("debug", `Debug: ${data}`);
Acesso aninhado YAML
config:
retries: 3
labels:
- core
- beta
let retry = main.config.retries;
let tag = main.config.labels[0];
Notas Futuras
break/continue— não suportadomatch— planejadotry/catch— TBD
Para mais detalhes, consulte a documentação oficial do Phlow e do Rhai.
- Standard encoding: Uses the standard Base64 alphabet
- Automatic padding: Adds
=characters when needed - UTF-8 support: Handles special characters correctly
- Binary safe: Works with any byte sequence
� base64_to_utf8() - Base64 Decoding
Decode Base64 strings back to UTF-8 text:
"SGVsbG8gV29ybGQ=".base64_to_utf8(); // "Hello World"
"dXNlckBleGFtcGxlLmNvbQ==".base64_to_utf8(); // "user@example.com"
"Y2Fmw6k=".base64_to_utf8(); // "café"
"MTIzNDU=".base64_to_utf8(); // "12345"
"".base64_to_utf8(); // ""
"invalid_base64!@#".base64_to_utf8(); // "" (empty on error)
Features:
- Standard decoding: Uses the standard Base64 alphabet
- UTF-8 validation: Returns empty string if result is not valid UTF-8
- Error handling: Returns empty string for invalid Base64 input
- Safe operation: Never crashes on malformed input
🔓 url_decode() - URL Decoding
Decode URL-encoded strings back to UTF-8 text:
"Hello+World".url_decode(); // "Hello World"
"user%40example.com".url_decode(); // "user@example.com"
"caf%C3%A9+%26+ma%C3%A7%C3%A3".url_decode(); // "café & maçã"
"abc-123_test.file~".url_decode(); // "abc-123_test.file~" (unchanged)
"Ol%C3%A1+mundo%21".url_decode(); // "Olá mundo!"
"%ZZ".url_decode(); // "%ZZ" (invalid hex preserved)
"test%".url_decode(); // "test%" (incomplete sequence preserved)
Features:
- RFC 3986 compliant: Handles standard URL encoding rules
- Plus to space: Converts
+characters to spaces - UTF-8 support: Properly decodes multi-byte UTF-8 sequences
- Error tolerance: Preserves malformed sequences rather than failing
- Safe operation: Returns empty string only for UTF-8 validation errors
�📋 parse() - JSON Parser
Parse JSON strings into native Rhai types:
"\"hello world\"".parse(); // "hello world" (string)
"42".parse(); // 42 (integer)
"3.14".parse(); // 3.14 (float)
"true".parse(); // true (boolean)
"false".parse(); // false (boolean)
"null".parse(); // () (unit/null)
// Objects are converted to Rhai Maps
let obj = "{\"name\":\"João\",\"age\":30}".parse();
obj.name; // "João"
obj.age; // 30
// Arrays are converted to Rhai Arrays
let arr = "[1, 2, 3, \"test\"]".parse();
arr[0]; // 1
arr[3]; // "test"
arr.len(); // 4
// Nested structures work too
let nested = "{\"user\":{\"name\":\"Maria\",\"roles\":[\"admin\",\"user\"]}}".parse();
nested.user.name; // "Maria"
nested.user.roles[0]; // "admin"
Features:
- Type conversion: Automatically converts to appropriate Rhai types
- Primitive support: Handles strings, numbers, booleans, and null
- Native structures: Objects become Maps, arrays become Arrays
- Nested support: Handles complex nested JSON structures
- Direct access: Use dot notation and indexing on parsed objects/arrays
- Error handling: Returns null (unit) for invalid JSON
- Safe parsing: Never crashes on malformed input
📖 Additional String Methodsehavior scripting using .phs files while deeply integrating with the Phlow runtime and module system.
✨ Overview
PHS (Phlow Script) brings the power of embedded scripting to YAML-based workflows. It's designed to let you inject dynamic logic through readable scripts, while preserving Phlow's declarative style.
You can inject modules directly into your PHS context via the modules section of your .yaml configuration. Each module declared becomes globally accessible in the .phs script, making it easy to mix scripting with orchestrated steps.
📑 Summary
- ✨ Overview
- 🔌 Module Injection via YAML
- 🧪 Example
- 📁 File Extensions
- 🔐 Modules Supported in PHS
- 🧠 Variables in PHS
- 🧱 Arrays and Objects (Maps)
- 🧭 Conditionals in PHS
- 🔁 Loops in PHS
- 🧩 Functions in PHS
- 🧬 PHS Syntax and Language Features
🔌 Module Injection via YAML
All modules declared in the YAML under modules: are automatically available inside your .phs script. For example, when you load the log module, its functions can be used directly in the script.
🧪 Example
main.phlow
main: cli
name: Example Cli
version: 1.0.0
description: Example CLI module
author: Your Name
modules:
- module: cli
version: latest
with:
additional_args: false
args:
- name: name
description: Name of the user
index: 1
type: string
required: false
- module: log
version: latest
steps:
- return: !import script.phs
script.phs
log("warn", `Hello, ${main.name}`);
💡Output
If the user runs:
phlow run main.phlow --name Philippe
The script will log:
[warn] Hello, Philippe
📁 File Extensions
Phlow automatically loads .phs scripts when referenced in the flow via !import. These scripts are parsed and executed using the internal Rhai engine extended with Phlow modules.
🔐 Modules Supported in PHS
Any module that exposes scripting bindings can be used. Example modules:
- log
- cli
- http_server
- (and any custom Rust module registered with bindings)
🧠 Variables in PHS
You can declare and use variables in .phs scripts using the let keyword. These variables help you store temporary values, compose strings, perform calculations, or reuse values throughout your script.
🔤 Declaring Variables
let name = main.name;
let greeting = "Hello";
let message = `${greeting}, ${name}!`;
log("info", message);
✍️ Reassigning Values
Variables can be reassigned at any point:
let count = 1;
count = count + 1;
🔄 Using Function Results
You can assign the result of a function to a variable:
let status = "warn";
let msg = "Something happened";
log(status, msg);
🧱 Arrays and objects (maps)
PHS allows you to work with arrays and objects (maps) natively. These are useful when handling lists of items, grouping values, or building dynamic data structures.
📚 Arrays
You can create arrays using square brackets []:
let fruits = ["apple", "banana", "orange"];
log("info", `First fruit: ${fruits[0]}`);
➕ Adding Items
fruits.push("grape");
🔄 Looping Through Arrays
for fruit in fruits {
log("debug", `Fruit: ${fruit}`);
}
🧳 Objects (Maps)
You can define key-value objects using curly braces {}:
let user = #{
name: main.name,
age: 30,
active: true
};
log("info", `User: ${user.name} (age: ${user.age})`);
🔧 Updating Properties
user.age = 31;
user.status = "online";
📦 Nesting
Objects and arrays can be nested:
let config = #{
tags: ["dev", "backend"],
options: #{
retries: 3,
timeout: 1000
}
};
log("debug", `Retries: ${config.options.retries}`);
🧭 Conditionals in PHS
PHS supports conditional logic using if, else if, and else blocks. These let you define dynamic behaviors based on data or user input.
✅ Basic If
if main.name == "Philippe" {
log("info", "Welcome back, boss!");
}
🔁 If...Else
if main.name == "Alice" {
log("info", "Hi Alice!");
} else {
log("info", "Hello, guest!");
}
🔀 Else If
if main.name == "Bob" {
log("info", "Hello Bob!");
} else if main.name == "Charlie" {
log("info", "Hey Charlie!");
} else {
log("info", "Who are you?");
}
🔗 Nested Conditions
if main.name != "" {
if main.name.len > 5 {
log("debug", "That's a long name.");
} else {
log("debug", "Short and sweet.");
}
}
Conditionals are a great way to adapt the behavior of your script based on CLI arguments, environment values, or runtime results.
🔁 Loops in PHS
PHS supports looping structures to help you iterate over arrays or repeat actions multiple times. The most common loop you'll use is the for loop.
📚 Looping Through an Array
let fruits = ["apple", "banana", "orange"];
for fruit in fruits {
log("info", `Fruit: ${fruit}`);
}
🔢 Looping with a Range
You can loop through a range of numbers:
for i in 0..5 {
log("debug", `Index: ${i}`);
}
This prints numbers from 0 to 4.
🔄 Nested Loops
Loops can be nested for handling multi-dimensional data:
let matrix = [
[1, 2],
[3, 4]
];
for row in matrix {
for value in row {
log("debug", `Value: ${value}`);
}
}
🛑 Breaking a Loop (not supported yet)
Currently, there's no support for break or continue in .phs. Keep your loops simple and controlled with conditions when needed.
Loops are powerful for automating repetitive tasks or handling collections of data. Combine them with conditionals and functions to build expressive scripts.
🧩 Functions in PHS
You can define your own functions in .phs to reuse logic, organize your code, and make scripts cleaner and more modular.
🛠 Defining a Function
Use the fn keyword:
fn greet(name) {
log("info", `Hello, ${name}!`);
}
▶️ Calling a Function
Once defined, just call it like this:
greet("Philippe");
This will log:
[info] Hello, Philippe!
↩️ Returning Values
Functions can return values using return:
fn double(n) {
return n * 2;
}
let result = double(5);
log("debug", `Result: ${result}`);
🧠 Functions with Logic
You can include conditionals, loops, and other functions inside your custom function:
fn log_fruits(fruits) {
for fruit in fruits {
log("info", `Fruit: ${fruit}`);
}
}
let list = ["apple", "banana", "orange"];
log_fruits(list);
⚠️ Scope
Variables declared inside a function are local to that function unless returned or passed back explicitly.
🧬 PHS Syntax and Language Features
This guide expands on PHS (Phlow Script)'s syntax, types, and scripting features.
📐 Data Types in PHS
PHS supports common primitive types, plus arrays and maps (objects):
| Type | Example |
|---|---|
bool |
true, false |
string |
"hello", `hi ${name}` |
int |
42 |
float |
3.14 (if enabled) |
array |
[1, 2, 3] |
null |
null |
map |
{ key: "value" } |
fn |
fn name(x) { ... } |
➕ Operators
| Operator | Description | Example |
|---|---|---|
+ |
Add / Concatenate | 2 + 3, "a" + "b" |
- |
Subtract | 10 - 4 |
* |
Multiply | 5 * 6 |
/ |
Divide | 9 / 3 |
% |
Modulo | 10 % 3 |
== |
Equals | x == y |
!= |
Not equal | x != y |
<, >, <=, >= |
Comparisons | x >= 10 |
&& |
Logical AND | x && y |
| ` | ` | |
! |
Logical NOT | !x |
🌐 Global Scope
main– the full YAML input- Declared
modules– globally exposed - Utility functions like
log(...)
🧪 Expressions & Statements
let upper = main.name.to_uppercase().trim();
🔀 Ternary Expressions
PHS supports ternary expressions using the when keyword for conditional logic:
let msg = when main.name == "" ? "Anonymous" : `Hello, ${main.name}`;
let status = when age >= 18 ? "adult" : "minor";
let value = when condition ? true_value : false_value;
🔤 String Functions
PHS includes several custom string manipulation functions in addition to Rhai's built-in string methods:
🔍 search(pattern) - Regex Pattern Matching
Search for regex patterns in strings, returns true if found:
let text = "Hello World";
let hasHello = text.search("Hello"); // true
let startsWithH = text.search("^H"); // true (regex: starts with H)
let endsWithD = text.search("d$"); // true (regex: ends with d)
let hasNumbers = text.search("[0-9]"); // false
🎯 starts_with(prefix) - Prefix Checking
Check if a string starts with a specific prefix:
let auth = "Bearer abc123";
let hasBearer = auth.starts_with("Bearer"); // true
let hasSpace = auth.starts_with("Bearer "); // true
let isBasic = auth.starts_with("Basic"); // false
let email = "user@example.com";
let isUserEmail = email.starts_with("user"); // true
let hasAt = email.starts_with("@"); // false
let empty = "";
let anyString = "test".starts_with(""); // true (empty prefix always matches)
Features:
- Case-sensitive: Distinguishes between uppercase and lowercase
- Exact matching: No regex patterns, just literal string comparison
- Fast operation: More efficient than regex for simple prefix checks
- Empty prefix: Always returns
truefor empty string prefix - Safe operation: Never fails, returns
falsefor invalid cases
When to use starts_with() vs search():
- Use
starts_with("prefix")for simple prefix checking (faster) - Use
search("^prefix")for regex-based prefix checking with patterns
🔄 replace(target, replacement) - String Replacement
⚠️ Important: Unlike native Rhai replace, this function returns the modified string instead of changing the variable in place:
let text = "Hello World";
let newText = text.replace("World", "Universe"); // Returns "Hello Universe"
// text is still "Hello World" - original unchanged
✂️ slice(start, end) / slice(start) - Substring Extraction
Extract a portion of a string with bounds checking. Supports two variants:
Two parameters - slice(start, end):
let text = "Hello World";
let part = text.slice(0, 5); // "Hello"
let middle = text.slice(6, 11); // "World"
let safe = text.slice(0, 100); // "Hello World" (auto-bounds)
One parameter - slice(start):
let text = "abcdef";
let fromIndex = text.slice(3); // "def" (from index 3 to end)
let lastTwo = text.slice(-2); // "ef" (last 2 characters)
let fromStart = text.slice(0); // "abcdef" (entire string)
- Positive index: Takes from that position to the end
- Negative index: Takes the last N characters
🎩 capitalize() - First Letter Uppercase
Capitalize the first character of a string:
let name = "joão";
let capitalized = name.capitalize(); // "João"
let empty = "".capitalize(); // ""
🐍 Case Conversion Functions
Convert between different naming conventions. These functions automatically detect the current format:
// to_snake_case() - Convert to snake_case
"meuTextoExemplo".to_snake_case(); // "meu_texto_exemplo"
"MeuTextoExemplo".to_snake_case(); // "meu_texto_exemplo"
"meu-texto-exemplo".to_snake_case(); // "meu_texto_exemplo"
"Meu texto exemplo".to_snake_case(); // "meu_texto_exemplo"
// to_camel_case() - Convert to camelCase
"meu_texto_exemplo".to_camel_case(); // "meuTextoExemplo"
"meu-texto-exemplo".to_camel_case(); // "meuTextoExemplo"
"Meu texto exemplo".to_camel_case(); // "meuTextoExemplo"
// to_kebab_case() - Convert to kebab-case
"meuTextoExemplo".to_kebab_case(); // "meu-texto-exemplo"
"meu_texto_exemplo".to_kebab_case(); // "meu-texto-exemplo"
"Meu texto exemplo".to_kebab_case(); // "meu-texto-exemplo"
� to_url_encode() - URL Encoding
Encode strings for safe use in URLs following RFC 3986:
"Hello World".to_url_encode(); // "Hello+World"
"user@example.com".to_url_encode(); // "user%40example.com"
"café & maçã".to_url_encode(); // "caf%C3%A9+%26+ma%C3%A7%C3%A3"
"abc-123_test.file~".to_url_encode(); // "abc-123_test.file~" (unchanged)
Encoding rules:
- Safe characters: Letters, numbers,
-,_,.,~remain unchanged - Spaces: Converted to
+ - Other characters: Encoded as
%XX(hexadecimal) - UTF-8: Full support for multi-byte characters
🔐 to_base64() - Base64 Encoding
Encode strings to Base64 format (RFC 4648):
"Hello World".to_base64(); // "SGVsbG8gV29ybGQ="
"user@example.com".to_base64(); // "dXNlckBleGFtcGxlLmNvbQ=="
"café".to_base64(); // "Y2Fmw6k="
"12345".to_base64(); // "MTIzNDU="
"".to_base64(); // ""
Features:
- Standard encoding: Uses the standard Base64 alphabet
- Automatic padding: Adds
=characters when needed - UTF-8 support: Handles special characters correctly
- Binary safe: Works with any byte sequence
�📖 Additional String Methods
For more string manipulation functions, refer to Rhai Language Reference.
🔎 Type Conversion Helpers
let number = "42".to_int();
let flag = "true".to_bool();
🛠 Working with Maps & Arrays
let keys = user.keys();
let vals = user.values();
if fruits.contains("banana") {
log("info", "Found it!");
}
🧯 Error Handling
Structured try/catch is not supported.
🪛 Debugging Tools
log("debug", `Debugging var: ${data}`);
🧬 Nested Access in YAML
config:
retries: 3
labels:
- core
- beta
let retry = main.config.retries;
let tag = main.config.labels[0];
📍Future Support Notes
break/continue→ not supported yetmatch/ pattern matching → plannedtry/catch→ TBD
📚 Catálogo de Funções do Engine (com exemplos)
Esta seção lista as funções utilitárias disponíveis globalmente em scripts .phs via o engine do PHS. Todas podem ser usadas diretamente nas expressões do seu script.
🕒 Datas e Tempo
today() -> int— Timestamp (segundos) do início do dia UTC.- Ex.:
let t0 = today();
- Ex.:
now() -> int— Timestamp atual (segundos).- Ex.:
let ts = now();
- Ex.:
format(ts, fmt) -> string— Formata um timestamp comstrftime.- Ex.:
format(1692362096, "%d/%m/%Y %H:%M:%S") // "18/08/2023 12:34:56"
- Ex.:
diff(ts1, ts2) -> int— Diferença em segundos:ts1 - ts2.- Ex.:
diff(now(), today())
- Ex.:
add_days(ts, n) -> int- Ex.:
add_days(now(), 2)
- Ex.:
add_hours(ts, n) -> int,add_minutes(ts, n) -> int,add_seconds(ts, n) -> int- Ex.:
add_minutes(1000, 2) // 1120
- Ex.:
sub_minutes(ts, n) -> int,sub_seconds(ts, n) -> int- Ex.:
sub_seconds(1000, 10) // 990
- Ex.:
weekday(ts) -> int— 0=Dom, 1=Seg, ...- Ex.:
weekday(1692362096) // 5 (sexta)
- Ex.:
year(ts),month(ts),day(ts),hour(ts),minute(ts),second(ts)- Ex.:
year(1692362096) // 2023
- Ex.:
from_iso(iso) -> int— Converte ISO-8601 para timestamp.- Ex.:
from_iso("2023-08-18T12:34:56Z") // 1692362096
- Ex.:
to_iso(ts) -> string— Converte timestamp para ISO-8601.- Ex.:
to_iso(1692362096) // "2023-08-18T12:34:56+00:00"
- Ex.:
🔤 Strings
search(pattern: regex) -> bool(método de string)- Ex.:
"meu texto".search("^meu") // true
- Ex.:
starts_with(prefix) -> bool(método de string)- Ex.:
"Bearer abc".starts_with("Bearer ") // true
- Ex.:
contains(substr) -> bool(método de string)- Ex.:
"The quick brown fox".contains("brown") // true
- Ex.:
replace(target, replacement) -> string(retorna nova string)- Ex.:
"abc abc".replace("abc", "x") // "x x"
- Ex.:
slice(start, end?) -> string(método de string)- Ex.:
"abcdef".slice(1,4) // "bcd","abcdef".slice(-2) // "ef"
- Ex.:
capitalize() -> string- Ex.:
"joão".capitalize() // "João"
- Ex.:
to_snake_case(),to_camel_case(),to_kebab_case()- Ex.:
"MeuTexto".to_snake_case() // "meu_texto"
- Ex.:
to_url_encode() -> string- Ex.:
"Hello World".to_url_encode() // "Hello+World"
- Ex.:
to_base64() -> string- Ex.:
"café".to_base64() // "Y2Fmw6k="
- Ex.:
base64_to_utf8() -> string- Ex.:
"SGVsbG8gV29ybGQ=".base64_to_utf8() // "Hello World"
- Ex.:
url_decode() -> string- Ex.:
"user%40example.com".url_decode() // "user@example.com"
- Ex.:
SQL-like Matching
like(pattern) -> bool- Usa curingas
%(qualquer sequência) e_(um caractere). O padrão deve casar a string inteira. - Ex.:
"hello world".like("h%o w%ld") // true
- Usa curingas
ilike(pattern) -> bool- Igual ao
like, mas case-insensitive. - Ex.:
"hello world".ilike("H%O W%LD") // true
- Igual ao
not_like(pattern) -> bool- Negação do
like. - Ex.:
"hello world".not_like("H%X W%LD") // true
- Negação do
not_ilike(pattern) -> bool- Negação do
ilike. - Ex.:
"hello world".not_ilike("H%X W%LD") // true
- Negação do
🧩 Objetos (Maps) e Arrays
merge(mapA, mapB) -> map— Junta mapas;mapBsobrescreve chaves.- Ex.:
merge(#{a:1,b:2}, #{b:3,c:4}) // #{a:1,b:3,c:4}
- Ex.:
contains_key(key) -> bool(método de map)- Ex.:
#{a:1}.contains_key("a") // true
- Ex.:
some(|item| expr) -> bool(método de array)- Ex.:
[1,2,3].some(|x| x > 2) // true - Ex.:
[#{a:1}, #{b:2}].some(|obj| obj.contains_key("b")) // true
- Ex.:
Observação: Funções internas __spread_object(arrDeMaps) e __spread_array(arrDeArrays) existem para suporte a sintaxe de spread e não são recomendadas para uso direto em scripts.
🔄 Conversão e JSON
parse(jsonStr) -> any— Converte JSON em tipos Rhai (map, array, string, número, bool, null).- Ex.:
let obj = "{\"name\":\"João\"}".parse(); obj.name // "João" - Ex.:
let arr = "[1,2,\"x\"]".parse(); arr[2] // "x"
- Ex.:
to_json(valor) -> string— Converte qualquer valor Rhai em JSON string.- Ex.:
#{name: "João", age: 30}.to_json()
- Ex.:
🆔 UUIDs
uuid("v4"),uuid("v6"),uuid("v7")— Gera UUIDs sem entrada.- Ex.:
let id = uuid("v7");
- Ex.:
uuid("v3", seed),uuid("v5", seed)— Gera UUID determinístico baseado emseed.- Ex.:
uuid("v5", "example.com")
- Ex.:
✅ Predicados de Tipo e Validação
is_null(x),is_not_null(x)is_empty(x)e também"str".is_empty()is_array(x),is_object(x),is_string(x)is_number(x),is_boolean(x)is_datetime(x)— valida string ISO-8601is_float(x),is_int(x)
🧪 Sintaxe Condicional Custom
when <cond> then <expr> else <expr>- Ex.:
when 2 + 2 == 4 then "certo" else "errado"
- Ex.:
it <cond> ? <expr> : <expr>- Ex.:
it "abc".search("b") ? "encontrou" : "não"
- Ex.:
Se notar alguma função ausente aqui, abra uma issue ou PR — essa seção é gerada a partir das utilidades registradas no engine em phs/src/functions.rs.
Dependencies
~17MB
~290K SLoC