Skip to content

Latest commit

 

History

History
135 lines (101 loc) · 5.87 KB

File metadata and controls

135 lines (101 loc) · 5.87 KB

Плагины

Вы можете создавать собственный плагины для RDL на языке Rust.

Крейт

Для упрощения разработки плагинов создан специальный крейт netter_plugger (crates.io). Установка крейта:

cargo add netter_plugger - добавит крейт для создания плагинов в зависимости вашего кода.

Структура кода

Начнём с простого примера:

use netter_plugger::{netter_plugin, generate_dispatch_func};

generate_dispatch_func!();

#[netter_plugin]
fn something(
    path: String,
) -> Result<String, String> {
    let result = "heey".to_string();
    if path == "error" {
        Err("err from plugin".to_string())
    } else {
        Ok(format!("{result}: {path}"))
    }
}

#[netter_plugin]
fn add_numbers(a: i32, b: i32) -> Result<String, String> {
    Ok((a + b).to_string())
}

#[netter_plugin]
fn check_flag(flag: bool) -> Result<String, String> {
    if flag {
        Ok("Flag is set".to_string())
    } else {
        Ok("Flag is not set".to_string())
    }
}
  • use netter_plugger::{netter_plugin, generate_dispatch_func}; - импорт атрибута и макроса от крейта для упрощения;
  • generate_dispatch_func!(); - данный макрос инициализирует входную точку в плагин. Очень важно расположить этот макрос в самом верху вашего кода (после всех use)
  • #[netter_plugin] - атрибут, который ставится на функции, чтобы пометить их для интеграции в RDL.

Warning

У функций, которые вы интегрируете в RDL есть важные ограничения: Входные типы данных На вход функция может принимать только следующие типы: String, &str, i64, i32, f64, f32, bool. Выходные типы Функция обязательно должна возвращать тип Result<String, String>

Данные ограничения связаны со строковой типизацией RDL и ограничений интерпретатора. Со времен список поддерживаемых типов будет увеличиваться

  • После атрибута объявляется функция и вся её логика - всё как обычно.

Под капотом

Весь ваш код функций преобразуется в C-совместимые типы, соответственно участвует unsafe extern "C" (подробнее можно почитать здесь). Учтите это, но чаще всего проблем быть не должно.

Вызов функций из RDL

Чтобы вызвать фукнции вашего плагина из RDL вам необходимо получить динамическую библиотеку из вашего кода плагина:

Note

Ваш Rust проект должен быть инициализирован с флагом --lib: cargo init --lib

Настройка Cargo.toml

Добавьте в ваш Cargo.toml следующее:

[dependencies]
netter_plugger = "0.1.0"
syn = { version = "2.0", features = ["full"] }
quote = "1.0"
lazy_static = "1.5.0"
serde = "1.0.219"
serde_json = "1.0.140"
ctor = "0.4.2"
...

[lib]
crate-type = ["cdylib"]

Все зависимости, который указаны в кодде выше, обязательно должны быть добавлны в ваш Cargo.toml Версию плагина выбирайте самую последнюю, чтобы избежать проблем с несовместимостью весрий и получить доступ ко всему функционалу крейта!

Сборка

В терминале пропишите следующее:

cargo build --release

Это сгенерирует динамическую библиотеку (.dll или .so).

Интеграция в RDL

До объявления маршрутов (Ключевое слово route) вам необходимо импортировать динамическую библиотеку, собранную ранее:

import "path/to/file.dll" as plugin_alias; // "path/to/file.dll" - путь (относительный или абсолютный) до вашей динамической библиотеки
// plugin_alias - алиас для использования далее

После этого вы сможете использовать ваши функции в коде:

route "/" GET {
    val a = 1;
    val b = 2;
    val plugin = plugin_alias::add_numbers(a, b)?;
    Response.body(plugin);
    Response.send();
} onError(e) {
    Response.status(500);
    Response.body(e);
    Response.send();
};

Important

Вы могли заметить, что после вызова функции из плагина стоит ?. Он необходим, чтобы поймать ошибку, если вддруг функция до неё дойдёт, поэтому обрабатывать эту ошибку надо точно также, как и обычные ошибки Хотя вы, если уверены, что до ошибки не дойдёт, можете её игнорировать с помощью !!, но тогда, в случае ошибки, код завершиться паникой (экстренное звершение)