🦀 Custom Operators in TuskLang with Rust
Custom Operators in TuskLang with Rust
⚡ Extending TuskLang's Power
TuskLang's @ operator system is just the beginning. With Rust, you can create custom operators that extend the language's capabilities, add domain-specific functionality, and integrate with any external system or API.
🏗️ Operator Architecture
Core Operator System
[operator_system]
base_operators: ["@env", "@date", "@cache", "@learn", "@metrics"]
custom_operators: true
operator_registry: true
hot_reload: true[operator_lifecycle]
registration: "compile_time"
validation: "runtime"
execution: "async"
cleanup: "automatic"
Operator Interface
[operator_interface]
trait_name: "TuskOperator"
required_methods:
- "name() -> &'static str"
- "execute(args: &[Value]) -> Result<Value, OperatorError>"
- "validate(args: &[Value]) -> Result<(), ValidationError>"optional_methods:
- "help() -> &'static str"
- "examples() -> Vec<&'static str>"
- "performance_hint() -> PerformanceHint"
🔧 Creating Custom Operators
Basic Operator Template
[custom_operator_template]
name: "my_operator"
syntax: "@my_operator(arg1, arg2, ...)"
return_type: "Value"
error_handling: "Result"[operator_implementation]
struct MyOperator;
impl TuskOperator for MyOperator {
fn name(&self) -> &'static str {
"@my_operator"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
// Operator logic here
Ok(Value::String("result".to_string()))
}
fn validate(&self, args: &[Value]) -> Result<(), ValidationError> {
if args.len() < 1 {
return Err(ValidationError::InsufficientArguments);
}
Ok(())
}
}
Operator Registration
[operator_registry]
registration_method: "macro_based"
discovery: "automatic"
conflict_resolution: "error_on_duplicate"[registry_config]
global_operators: true
namespace_support: true
versioning: true
🌐 Web API Operators
HTTP Request Operator
[http_operator]
name: "@http"
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"]
timeout_ms: 5000
retry_attempts: 3[http_implementation]
struct HttpOperator;
impl TuskOperator for HttpOperator {
fn name(&self) -> &'static str {
"@http"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let method = args.get(0).ok_or(OperatorError::MissingArgument)?;
let url = args.get(1).ok_or(OperatorError::MissingArgument)?;
let client = reqwest::Client::new();
let response = client
.request(method.as_str()?, url.as_str()?)
.send()
.await?;
let body = response.text().await?;
Ok(Value::String(body))
}
}
GraphQL Operator
[graphql_operator]
name: "@graphql"
endpoint_config: true
query_caching: true
schema_introspection: true[graphql_implementation]
struct GraphQLOperator;
impl TuskOperator for GraphQLOperator {
fn name(&self) -> &'static str {
"@graphql"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let endpoint = args.get(0).ok_or(OperatorError::MissingArgument)?;
let query = args.get(1).ok_or(OperatorError::MissingArgument)?;
let client = reqwest::Client::new();
let response = client
.post(endpoint.as_str()?)
.json(&serde_json::json!({
"query": query.as_str()?
}))
.send()
.await?;
let result = response.json::<serde_json::Value>().await?;
Ok(Value::from(result))
}
}
🗄️ Database Operators
SQL Query Operator
[sql_operator]
name: "@sql"
databases: ["postgresql", "mysql", "sqlite", "mongodb"]
connection_pooling: true
query_caching: true[sql_implementation]
struct SqlOperator;
impl TuskOperator for SqlOperator {
fn name(&self) -> &'static str {
"@sql"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let connection_string = args.get(0).ok_or(OperatorError::MissingArgument)?;
let query = args.get(1).ok_or(OperatorError::MissingArgument)?;
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(connection_string.as_str()?)
.await?;
let rows = sqlx::query(query.as_str()?)
.fetch_all(&pool)
.await?;
let results: Vec<serde_json::Value> = rows
.iter()
.map(|row| serde_json::to_value(row).unwrap())
.collect();
Ok(Value::from(results))
}
}
Redis Operator
[redis_operator]
name: "@redis"
operations: ["get", "set", "del", "incr", "expire"]
connection_pooling: true
serialization: "json"[redis_implementation]
struct RedisOperator;
impl TuskOperator for RedisOperator {
fn name(&self) -> &'static str {
"@redis"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let operation = args.get(0).ok_or(OperatorError::MissingArgument)?;
let key = args.get(1).ok_or(OperatorError::MissingArgument)?;
let client = redis::Client::open("redis://127.0.0.1/")?;
let mut con = client.get_connection()?;
match operation.as_str()? {
"get" => {
let value: String = redis::cmd("GET").arg(key.as_str()?).query(&mut con)?;
Ok(Value::String(value))
}
"set" => {
let value = args.get(2).ok_or(OperatorError::MissingArgument)?;
redis::cmd("SET").arg(key.as_str()?).arg(value.as_str()?).execute(&mut con);
Ok(Value::Bool(true))
}
_ => Err(OperatorError::InvalidOperation)
}
}
}
🤖 AI and ML Operators
Machine Learning Operator
[ml_operator]
name: "@ml"
models: ["tensorflow", "pytorch", "onnx"]
inference: true
training: true[ml_implementation]
struct MlOperator;
impl TuskOperator for MlOperator {
fn name(&self) -> &'static str {
"@ml"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let operation = args.get(0).ok_or(OperatorError::MissingArgument)?;
let model_path = args.get(1).ok_or(OperatorError::MissingArgument)?;
let input_data = args.get(2).ok_or(OperatorError::MissingArgument)?;
match operation.as_str()? {
"predict" => {
let model = tract_onnx::simple_plan(&model_path.as_str()?)?;
let input = tract_ndarray::Array::from_vec(input_data.as_array()?);
let output = model.run(tvec!(input.into()))?;
Ok(Value::from(output[0].to_array_view()?.to_vec()))
}
"train" => {
// Training logic
Ok(Value::Bool(true))
}
_ => Err(OperatorError::InvalidOperation)
}
}
}
Natural Language Processing Operator
[nlp_operator]
name: "@nlp"
operations: ["tokenize", "embed", "classify", "summarize"]
models: ["bert", "gpt", "t5"]
language_support: ["en", "es", "fr", "de"][nlp_implementation]
struct NlpOperator;
impl TuskOperator for NlpOperator {
fn name(&self) -> &'static str {
"@nlp"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let operation = args.get(0).ok_or(OperatorError::MissingArgument)?;
let text = args.get(1).ok_or(OperatorError::MissingArgument)?;
match operation.as_str()? {
"tokenize" => {
let tokens = text.as_str()?.split_whitespace().collect::<Vec<_>>();
Ok(Value::from(tokens))
}
"embed" => {
// Embedding logic using rust-bert
let embeddings = vec![0.1, 0.2, 0.3]; // Placeholder
Ok(Value::from(embeddings))
}
"classify" => {
// Classification logic
let classification = "positive";
Ok(Value::String(classification.to_string()))
}
_ => Err(OperatorError::InvalidOperation)
}
}
}
🔐 Security Operators
Encryption Operator
[encryption_operator]
name: "@encrypt"
algorithms: ["aes_256_gcm", "chacha20_poly1305", "rsa_2048"]
key_management: true
secure_random: true[encryption_implementation]
struct EncryptionOperator;
impl TuskOperator for EncryptionOperator {
fn name(&self) -> &'static str {
"@encrypt"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let algorithm = args.get(0).ok_or(OperatorError::MissingArgument)?;
let data = args.get(1).ok_or(OperatorError::MissingArgument)?;
let key = args.get(2).ok_or(OperatorError::MissingArgument)?;
match algorithm.as_str()? {
"aes_256_gcm" => {
use aes_gcm::{Aes256Gcm, Key, Nonce};
use aes_gcm::aead::{Aead, NewAead};
let cipher = Aes256Gcm::new_from_slice(key.as_bytes()?)?;
let nonce = Nonce::from_slice(b"unique nonce");
let ciphertext = cipher.encrypt(nonce, data.as_bytes()?.as_ref())?;
Ok(Value::from(base64::encode(ciphertext)))
}
_ => Err(OperatorError::InvalidAlgorithm)
}
}
}
Authentication Operator
[auth_operator]
name: "@auth"
methods: ["jwt", "oauth2", "api_key", "basic"]
token_validation: true
user_management: true[auth_implementation]
struct AuthOperator;
impl TuskOperator for AuthOperator {
fn name(&self) -> &'static str {
"@auth"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let method = args.get(0).ok_or(OperatorError::MissingArgument)?;
let credentials = args.get(1).ok_or(OperatorError::MissingArgument)?;
match method.as_str()? {
"jwt" => {
let token = credentials.as_str()?;
let validation = jsonwebtoken::decode::<Claims>(
token,
&jsonwebtoken::DecodingKey::from_secret("secret".as_ref()),
&jsonwebtoken::Validation::default()
)?;
Ok(Value::from(validation.claims))
}
"oauth2" => {
// OAuth2 validation logic
Ok(Value::Bool(true))
}
_ => Err(OperatorError::InvalidMethod)
}
}
}
📊 Analytics Operators
Metrics Operator
[metrics_operator]
name: "@metrics"
backends: ["prometheus", "influxdb", "datadog"]
aggregation: true
alerting: true[metrics_implementation]
struct MetricsOperator;
impl TuskOperator for MetricsOperator {
fn name(&self) -> &'static str {
"@metrics"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let metric_name = args.get(0).ok_or(OperatorError::MissingArgument)?;
let value = args.get(1).ok_or(OperatorError::MissingArgument)?;
let labels = args.get(2);
let registry = prometheus::Registry::new();
let counter = prometheus::Counter::new(
metric_name.as_str()?,
"Metric description"
)?;
registry.register(Box::new(counter.clone()))?;
counter.inc_by(value.as_f64()?);
Ok(Value::Bool(true))
}
}
Logging Operator
[logging_operator]
name: "@log"
levels: ["trace", "debug", "info", "warn", "error"]
formatters: ["json", "text", "structured"]
destinations: ["file", "stdout", "syslog"][logging_implementation]
struct LoggingOperator;
impl TuskOperator for LoggingOperator {
fn name(&self) -> &'static str {
"@log"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let level = args.get(0).ok_or(OperatorError::MissingArgument)?;
let message = args.get(1).ok_or(OperatorError::MissingArgument)?;
match level.as_str()? {
"info" => info!("{}", message.as_str()?),
"warn" => warn!("{}", message.as_str()?),
"error" => error!("{}", message.as_str()?),
"debug" => debug!("{}", message.as_str()?),
"trace" => trace!("{}", message.as_str()?),
_ => return Err(OperatorError::InvalidLevel)
}
Ok(Value::Bool(true))
}
}
🔄 Workflow Operators
Pipeline Operator
[pipeline_operator]
name: "@pipeline"
stages: ["map", "filter", "reduce", "group"]
parallel_execution: true
error_handling: true[pipeline_implementation]
struct PipelineOperator;
impl TuskOperator for PipelineOperator {
fn name(&self) -> &'static str {
"@pipeline"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let data = args.get(0).ok_or(OperatorError::MissingArgument)?;
let operations = args.get(1).ok_or(OperatorError::MissingArgument)?;
let mut result = data.as_array()?;
for operation in operations.as_array()? {
let op_type = operation.get("type").ok_or(OperatorError::MissingArgument)?;
let op_func = operation.get("function").ok_or(OperatorError::MissingArgument)?;
match op_type.as_str()? {
"map" => {
result = result.iter()
.map(|item| self.apply_function(op_func, item))
.collect::<Result<Vec<_>, _>>()?;
}
"filter" => {
result = result.into_iter()
.filter(|item| self.apply_function(op_func, item)?.as_bool()?)
.collect();
}
_ => return Err(OperatorError::InvalidOperation)
}
}
Ok(Value::from(result))
}
}
Conditional Operator
[conditional_operator]
name: "@if"
syntax: "@if(condition, true_value, false_value)"
short_circuit: true
lazy_evaluation: true[conditional_implementation]
struct ConditionalOperator;
impl TuskOperator for ConditionalOperator {
fn name(&self) -> &'static str {
"@if"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let condition = args.get(0).ok_or(OperatorError::MissingArgument)?;
let true_value = args.get(1).ok_or(OperatorError::MissingArgument)?;
let false_value = args.get(2).ok_or(OperatorError::MissingArgument)?;
if condition.as_bool()? {
Ok(true_value.clone())
} else {
Ok(false_value.clone())
}
}
}
🎨 Custom Syntax Operators
Template Operator
[template_operator]
name: "@template"
syntax: "@template(template_string, variables)"
interpolation: true
escaping: true[template_implementation]
struct TemplateOperator;
impl TuskOperator for TemplateOperator {
fn name(&self) -> &'static str {
"@template"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let template = args.get(0).ok_or(OperatorError::MissingArgument)?;
let variables = args.get(1).ok_or(OperatorError::MissingArgument)?;
let mut result = template.as_str()?.to_string();
for (key, value) in variables.as_object()? {
let placeholder = format!("{{{{{}}}}}", key);
result = result.replace(&placeholder, &value.to_string());
}
Ok(Value::String(result))
}
}
Regex Operator
[regex_operator]
name: "@regex"
operations: ["match", "replace", "extract", "split"]
flags: ["case_insensitive", "multiline", "dot_all"][regex_implementation]
struct RegexOperator;
impl TuskOperator for RegexOperator {
fn name(&self) -> &'static str {
"@regex"
}
fn execute(&self, args: &[Value]) -> Result<Value, OperatorError> {
let operation = args.get(0).ok_or(OperatorError::MissingArgument)?;
let pattern = args.get(1).ok_or(OperatorError::MissingArgument)?;
let text = args.get(2).ok_or(OperatorError::MissingArgument)?;
let regex = Regex::new(pattern.as_str()?)?;
match operation.as_str()? {
"match" => {
let is_match = regex.is_match(text.as_str()?);
Ok(Value::Bool(is_match))
}
"replace" => {
let replacement = args.get(3).ok_or(OperatorError::MissingArgument)?;
let result = regex.replace_all(text.as_str()?, replacement.as_str()?);
Ok(Value::String(result.to_string()))
}
"extract" => {
let captures: Vec<String> = regex.captures_iter(text.as_str()?)
.map(|cap| cap[0].to_string())
.collect();
Ok(Value::from(captures))
}
_ => Err(OperatorError::InvalidOperation)
}
}
}
🚀 Performance Optimization
Operator Caching
[operator_caching]
enabled: true
cache_size: 1000
ttl_seconds: 300
invalidation: "lru"[cache_config]
memory_based: true
disk_backed: false
compression: true
Async Execution
[async_execution]
runtime: "tokio"
concurrency: "unbounded"
timeout_ms: 5000[async_config]
spawn_blocking: true
yield_now: true
cooperative_cancellation: true
🔧 Testing Custom Operators
Unit Testing
[operator_testing]
framework: "criterion"
benchmarking: true
property_testing: true[test_config]
test_operators:
- "http_operator"
- "sql_operator"
- "ml_operator"
- "encryption_operator"
[test_examples]
http_test:
input: ["GET", "https://api.example.com/data"]
expected: "json_response"
sql_test:
input: ["postgresql://localhost/db", "SELECT * FROM users"]
expected: "user_data_array"
Integration Testing
[integration_testing]
test_environment: "docker"
external_services: ["postgresql", "redis", "httpbin"]
cleanup: "automatic"[test_scenarios]
api_integration:
setup: "start_mock_server"
test: "http_operator_requests"
teardown: "stop_mock_server"
database_integration:
setup: "create_test_database"
test: "sql_operator_queries"
teardown: "drop_test_database"
📚 Operator Documentation
Auto-Generated Documentation
[operator_docs]
generation: "automatic"
format: "markdown"
examples: true
performance_notes: true[doc_config]
include_signatures: true
include_examples: true
include_performance: true
include_security: true
🎯 Best Practices
1. Operator Design
- Keep operators focused and single-purpose - Use clear, descriptive names - Implement proper error handling - Provide comprehensive documentation2. Performance
- Use async execution for I/O operations - Implement caching where appropriate - Optimize for common use cases - Monitor resource usage3. Security
- Validate all inputs - Sanitize user data - Use secure defaults - Implement proper access controls4. Testing
- Write comprehensive unit tests - Include integration tests - Test error conditions - Benchmark performance5. Documentation
- Provide clear examples - Document all parameters - Include performance characteristics - Add security considerationsCustom operators in TuskLang with Rust enable you to extend the language's capabilities in powerful ways, creating domain-specific functionality that integrates seamlessly with your applications.