#serde-json #call #dynamic #traits #run-time #arguments #name

dynamic_call

在运行时通过名称查找 trait 方法,并使用 json 调用它

2 个版本

0.1.1 2023 年 9 月 26 日
0.1.0 2023 年 9 月 26 日

#1895 in 解析器实现

MIT/Apache

17KB
165

dynamic_call

Crates.io Documentation

此包允许在运行时通过名称查找 trait 方法,并使用 serde_json 反序列化的 json 参数调用该方法。

示例

use dynamic_call::dynamic_call;

#[dynamic_call(foo_dynamic_call)]
trait Foo {
    fn add(&mut self, x: i32) -> i32;
    fn show(&self, message: &str);
}

上面的代码生成一个类似下面的模块

pub mod foo_dynamic_call {
    /// Returns information about the signature of the given method.
    ///
    /// Returns `None` if the method is not a member of the trait or has been skipped
    /// using the `#[dynamic_call::skip]` attribute.
    pub fn method(name: &str) -> Option<MethodInfo> {
        // ...
    }

    /// Returns a list of methods in the trait, in declaration order.
    ///
    /// Excludes methods which have been skipped using the `#[dynamic_call::skip]`
    /// attribute.
    pub fn methods() -> Vec<MethodInfo> {
        // ...
    }

    /// Deserializes the given arguments using `serde_json` and calls [Foo::add].
    ///
    /// The arguments must be an array or an object with keys equal to the parameter names.
    pub fn call_method_add<T: Foo>(
        this: &mut T,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }

    /// Deserializes the given arguments using `serde_json` and calls [Foo::show].
    ///
    /// The arguments must be an array or an object with keys equal to the parameter names.
    pub fn call_method_show<T: Foo>(
        this: &T,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }

    /// Calls a static or `&self` method of [Foo] dynamically.
    ///
    /// The method name must be one of the methods in the trait. The arguments must be an
    /// array or an object with keys equal to the parameter names.
    pub fn call_dynamic<T: Foo>(
        this: &T,
        method_name: &str,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }

    /// Calls a static, `&self`, or `&mut self` method of [Foo] dynamically.
    ///
    /// The method name must be one of the methods in the trait. The arguments must be an
    /// array or an object with keys equal to the parameter names.
    pub fn call_dynamic_mut<T: Foo>(
        this: &mut T,
        method_name: &str,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }

    /// Calls any method of [Foo] dynamically.
    ///
    /// The method name must be one of the methods in the trait. The arguments must be an
    /// array or an object with keys equal to the parameter names.
    pub fn call_dynamic_value<T: Foo>(
        mut this: T,
        method_name: &str,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }

    /// Calls a static method of [Foo] dynamically.
    ///
    /// The method name must be one of the methods in the trait. The arguments must be an
    /// array or an object with keys equal to the parameter names.
    pub fn call_dynamic_static<T: Foo>(
        method_name: &str,
        args: serde_json::Value,
    ) -> Result<serde_json::Value, Error> {
        // ...
    }
}

支持的方法

不支持泛型类型的方法。

静态方法以及带有 self&self&mut self 的方法都受支持。必须根据方法的 self 类型调用兼容版本的 call_dynamic_X

使用 serde_json 反序列化参数。参数值必须是一个数组或一个对象,其中键与方法的参数名称匹配。数组或对象中的额外参数将被忽略。

如果类型实现了 CloneDeserializeOwned,则支持参数类型。此外,还支持字符串、数组和路径切片。更具体地说,一个参数可以是 T&T&mut T 的形式,其中 T 必须实现 ToOwned,并且 T::Owned 必须实现 DeserializeOwned

要跳过方法,请使用 #[dynamic_call::skip] 属性。

许可:MIT OR Apache-2.0

依赖

~0.7–1.6MB
~35K SLoC