Rust 绑定,用于在 Rust 应用中嵌入 Candle 脚本引擎
candle crate 提供了类型安全的 Rust API,允许你在 Rust 项目中嵌入和执行 Candle 脚本。
- ✅ 类型安全 - 完整的 Rust 类型系统支持
- ✅ 零成本抽象 - 直接调用 C ABI,无运行时开销
- ✅ 内存安全 - RAII 资源管理,自动 GC 根管理
- ✅ 易于使用 - 符合 Rust 惯用法的 API
- ✅ 完整文档 - 所有公开 API 都有文档注释
[dependencies]
candle = { path = "../include" }use candle::{Runtime, Value};
fn main() -> candle::Result<()> {
// 创建运行时
let mut rt = Runtime::new();
// 创建值
let s = Value::string("Hello, Candle!");
let num = Value::int(42);
let list = rt.create_list::<i64>();
let map = rt.create_map::<String, i64>();
Ok(())
}let mut rt = Runtime::new();
// 创建各种值
let string = rt.create_string("hello");
let list = rt.create_list::<i64>();
let map = rt.create_map::<String, i64>();
// 手动触发 GC
rt.collect_garbage();// 创建值
let null = Value::null();
let boolean = Value::bool(true);
let integer = Value::int(42);
let string = Value::string("hello");
// 类型检查
if value.is_int() {
let num = value.as_int()?;
println!("{}", num);
}
// 获取类型
match value.value_type() {
ValueType::Int => println!("整数"),
ValueType::String => println!("字符串"),
_ => println!("其他类型"),
}let s = Value::string("Hello, World!");
let candle_str = s.as_string()?;
// 属性
println!("长度: {}", candle_str.len());
println!("是否为空: {}", candle_str.is_empty());
// 方法
let sub = candle_str.substring(0, 5)?;
println!("包含 'World': {}", candle_str.contains("World"));
println!("以 'Hello' 开头: {}", candle_str.starts_with("Hello"));
println!("以 '!' 结尾: {}", candle_str.ends_with("!"));
// 转换为 Rust String
let rust_str = candle_str.to_string();let list = rt.create_list::<i64>();
let mut candle_list = list.as_list()?;
// 添加元素
candle_list.add(Value::int(10));
candle_list.add(Value::int(20));
// 访问元素
let first = candle_list.get(0)?;
candle_list.set(0, Value::int(100))?;
// 查询
println!("长度: {}", candle_list.len());
println!("包含 20: {}", candle_list.contains(&Value::int(20)));
// 移除元素
let removed = candle_list.remove(&Value::int(20));
// 迭代
for val in candle_list.iter() {
if let Ok(num) = val.as_int() {
println!("{}", num);
}
}
// 转换为 Vec
let vec = candle_list.to_vec();let map = rt.create_map::<String, i64>();
let mut candle_map = map.as_map()?;
// 设置键值对
candle_map.set_str("age", Value::int(30));
candle_map.set_str("score", Value::int(95));
// 获取值
if let Ok(age) = candle_map.get_str("age") {
println!("年龄: {}", age.as_int()?);
}
// 查询
println!("长度: {}", candle_map.len());
println!("包含 'age': {}", candle_map.contains_str("age"));
// 移除
let removed = candle_map.remove_str("score");
// 获取所有键和值
let keys = candle_map.keys();
let values = candle_map.values();use candle::Error;
match value.as_int() {
Ok(num) => println!("整数: {}", num),
Err(Error::TypeError { expected, actual }) => {
println!("类型错误: 期望 {}, 实际 {:?}", expected, actual);
}
Err(e) => println!("其他错误: {}", e),
}// 使用 Candle 替代 JSON/TOML
let config = rt.eval(r#"
String app_name = "MyApp";
int port = 8080;
bool debug = true;
"#)?;// 允许非程序员编写业务规则
let rules = rt.eval(r#"
int calculate_discount(int amount, bool is_vip) {
if (is_vip && amount > 1000) return 20;
if (amount > 500) return 5;
return 0;
}
"#)?;// 用户提供的插件脚本
let plugin = rt.eval(r#"
class MyPlugin {
String process(String data) {
return data + " (processed)";
}
}
"#)?;// 动态表达式计算
let result = rt.eval("(10 + 20) * 3")?;
println!("{}", result.as_int()?);// 使用脚本描述测试场景
let test = rt.eval(r#"
List<int> numbers = List<int>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
assert(numbers.length == 3);
"#)?;查看 examples/ 目录:
hello.rs- 基础 API 使用eval.rs- 脚本执行示例embedding.rs- 嵌入式应用场景
运行示例:
cd include
cargo run --example hello
cargo run --example eval
cargo run --example embeddingRust 应用程序
↓ 使用
Candle Rust API (include/)
↓ 调用
Candle Runtime (C ABI)
↓ 执行
Candle VM
- 自动 GC - Candle 值由 GC 管理
- RAII - Rust 端自动管理 GC 根
- 引用计数 - Value 类型实现了 Clone 和 Drop
{
let s = Value::string("hello");
// 自动调用 candle_rt_gc_add_root
let s2 = s.clone();
// 增加引用计数
} // 自动调用 candle_rt_gc_remove_root- ✅ 零成本抽象 - 直接调用 C ABI
- ✅ 编译时优化 - LLVM 优化
- ✅ 无运行时开销 - 没有额外的包装层
Runtime不实现Send和Sync- 每个线程需要自己的
Runtime实例 - 未来版本可能添加线程安全支持
- Rust 1.70+
- Candle 运行时库 (
libcandle_runtime.a)
🚧 实验性版本
当前版本提供了完整的 API 接口设计,但部分功能(如 eval)需要完整的编译器运行时集成才能工作。
已实现:
- ✅ 类型安全的 Value 封装
- ✅ String、List、Map 操作
- ✅ 内存管理(GC 根)
- ✅ 错误处理
待实现:
- ⏳ eval 脚本执行
- ⏳ 函数调用
- ⏳ 全局变量访问
- ⏳ 异常捕获
欢迎贡献!主要需要:
- 完善运行时集成(eval 功能)
- 添加更多测试
- 改进文档
- 性能优化
MIT License
Candle - 现代、高性能的脚本语言