Skip to content

Commit

Permalink
Merge pull request #466 from Peefy/docs-rust-plugin-docs
Browse files Browse the repository at this point in the history
docs: add rust kcl plugin guide documents
  • Loading branch information
Peefy authored Sep 10, 2024
2 parents e97e72b + b13b274 commit af14d01
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
76 changes: 76 additions & 0 deletions docs/reference/plugin/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,79 @@ import kcl_plugin.my_plugin
result = my_plugin.add(1, 1)
```

## Use Rust to Write Plugins

### 0. Prerequisites

Using the KCL Rust plugin requires the presence of `Rust 1.79+` in your `PATH` and install the KCL Rust SDK.

```shell
cargo add anyhow
cargo add kclvm-parser --git https://github.com/kcl-lang/kcl
cargo add kclvm-loader --git https://github.com/kcl-lang/kcl
cargo add kclvm-evaluator --git https://github.com/kcl-lang/kcl
cargo add kclvm-runtime --git https://github.com/kcl-lang/kcl
```

### 1. Hello Plugin

Write the following Rust code and add the the plugin named `my_plugin`.

```rust
use anyhow::{anyhow, Result};
use kclvm_evaluator::Evaluator;
use kclvm_loader::{load_packages, LoadPackageOptions};
use kclvm_parser::LoadProgramOptions;
use kclvm_runtime::{Context, IndexMap, PluginFunction, ValueRef};
use std::{cell::RefCell, rc::Rc, sync::Arc};
fn my_plugin_sum(_: &Context, args: &ValueRef, _: &ValueRef) -> Result<ValueRef> {
let a = args
.arg_i_int(0, Some(0))
.ok_or(anyhow!("expect int value for the first param"))?;
let b = args
.arg_i_int(1, Some(0))
.ok_or(anyhow!("expect int value for the second param"))?;
Ok((a + b).into())
}
fn context_with_plugin() -> Rc<RefCell<Context>> {
let mut plugin_functions: IndexMap<String, PluginFunction> = Default::default();
let func = Arc::new(my_plugin_sum);
plugin_functions.insert("my_plugin.add".to_string(), func);
let mut ctx = Context::new();
ctx.plugin_functions = plugin_functions;
Rc::new(RefCell::new(ctx))
}
fn main() -> Result<()> {
let src = r#"
import kcl_plugin.my_plugin
sum = my_plugin.add(1, 1)
"#;
let p = load_packages(&LoadPackageOptions {
paths: vec!["test.k".to_string()],
load_opts: Some(LoadProgramOptions {
load_plugins: true,
k_code_list: vec![src.to_string()],
..Default::default()
}),
load_builtin: false,
..Default::default()
})?;
let evaluator = Evaluator::new_with_runtime_ctx(&p.program, context_with_plugin());
let result = evaluator.run()?;
println!("yaml result {}", result.1);
Ok(())
}
```

The content of `test.k` are:

```python
import kcl_plugin.my_plugin
result = my_plugin.add(1, 1)
```
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,79 @@ import kcl_plugin.my_plugin
result = my_plugin.add(1, 1)
```

## 使用 Rust 编写插件

### 0. 先决条件

使用 KCL Rust 插件需要在您的 PATH 中具有 Rust 1.79+,并安装 KCL Rust SDK。

```shell
cargo add anyhow
cargo add kclvm-parser --git https://github.com/kcl-lang/kcl
cargo add kclvm-loader --git https://github.com/kcl-lang/kcl
cargo add kclvm-evaluator --git https://github.com/kcl-lang/kcl
cargo add kclvm-runtime --git https://github.com/kcl-lang/kcl
```

### 1. 你好插件

编写以下 Rust 代码并添加名为 `my_plugin` 的插件。

```rust
use anyhow::{anyhow, Result};
use kclvm_evaluator::Evaluator;
use kclvm_loader::{load_packages, LoadPackageOptions};
use kclvm_parser::LoadProgramOptions;
use kclvm_runtime::{Context, IndexMap, PluginFunction, ValueRef};
use std::{cell::RefCell, rc::Rc, sync::Arc};
fn my_plugin_sum(_: &Context, args: &ValueRef, _: &ValueRef) -> Result<ValueRef> {
let a = args
.arg_i_int(0, Some(0))
.ok_or(anyhow!("expect int value for the first param"))?;
let b = args
.arg_i_int(1, Some(0))
.ok_or(anyhow!("expect int value for the second param"))?;
Ok((a + b).into())
}
fn context_with_plugin() -> Rc<RefCell<Context>> {
let mut plugin_functions: IndexMap<String, PluginFunction> = Default::default();
let func = Arc::new(my_plugin_sum);
plugin_functions.insert("my_plugin.add".to_string(), func);
let mut ctx = Context::new();
ctx.plugin_functions = plugin_functions;
Rc::new(RefCell::new(ctx))
}
fn main() -> Result<()> {
let src = r#"
import kcl_plugin.my_plugin
sum = my_plugin.add(1, 1)
"#;
let p = load_packages(&LoadPackageOptions {
paths: vec!["test.k".to_string()],
load_opts: Some(LoadProgramOptions {
load_plugins: true,
k_code_list: vec![src.to_string()],
..Default::default()
}),
load_builtin: false,
..Default::default()
})?;
let evaluator = Evaluator::new_with_runtime_ctx(&p.program, context_with_plugin());
let result = evaluator.run()?;
println!("yaml result {}", result.1);
Ok(())
}
```

test.k 的内容为:

```python
import kcl_plugin.my_plugin
result = my_plugin.add(1, 1)
```

0 comments on commit af14d01

Please sign in to comment.