53 个版本 (14 个稳定版)

1.5.0 2024 年 8 月 12 日
1.4.2 2024 年 7 月 2 日
1.4.1 2024 年 5 月 13 日
1.1.1 2024 年 2 月 12 日
0.0.0 2022 年 12 月 26 日

#27 in #gear

Download history 858/week @ 2024-04-22 341/week @ 2024-04-29 719/week @ 2024-05-06 491/week @ 2024-05-13 481/week @ 2024-05-20 259/week @ 2024-05-27 247/week @ 2024-06-03 248/week @ 2024-06-10 248/week @ 2024-06-17 252/week @ 2024-06-24 601/week @ 2024-07-01 474/week @ 2024-07-08 474/week @ 2024-07-15 479/week @ 2024-07-22 311/week @ 2024-07-29 358/week @ 2024-08-05

1,645 个月下载量
16 包中使用 (7 个直接使用)

GPL-3.0 许可证

19KB
153

Crate 提供 Gear 程序的元数据。

元数据用于描述 Gear 程序的接口。例如,在通过 https://idea.gear-tech.io 上传程序时可以使用它。元数据会通知用户有关程序接口的信息,并允许他们通过自定义类型在 Web 应用程序的 UI 中与之交互。

另一个用例是使用 gear-js 库在 JavaScript 中解析元数据,并获取一些自定义 UI 的元数据详情。

请注意,元数据不是 Gear 程序运行所必需的。它仅用于提供有关程序的其他信息。此外,元数据可用于各种用途,但我们将关注与 https://idea.gear-tech.io 相关的用例。

要为程序生成元数据输出文件,你需要

  • gmeta crate 添加到你的 Cargo.toml 文件。
  • 定义一个空的结构体,该结构体会识别程序元数据。
  • 通过定义特质的关联类型来实现此结构体的 Metadata 特质。
  • 选项 1:在 build.rs 文件中调用 gear_wasm_builder::build_with_metadata 函数。
  • 选项 2:使用 MetadataRepr::hex 函数将元数据转换为十六进制字符串,并将其写入文本文件。

示例

在本示例中,我们将创建一个简单的 ping-pong 程序。让我们在单独的 ping-io crate 中定义消息类型和元数据,以便在程序和 build.rs 文件中使用。

我们将为 handle()state() 函数定义消息类型。

  • ping-io crate
#[no_std]
use gmeta::{InOut, Metadata, Out};
use gstd::prelude::*;

// Message type for `handle()` function.
#[derive(Encode, Decode, TypeInfo)]
pub enum PingPong {
    Ping,
    Pong,
}

// Metadata struct.
pub struct ProgramMetadata;

impl Metadata for ProgramMetadata {
    // The unit tuple is used as neither incoming nor outgoing messages are
    // expected in the `init()` function.
    type Init = ();
    // We use the same `PingPong` type for both incoming and outgoing
    // messages.
    type Handle = InOut<PingPong, PingPong>;
    // The unit tuple is used as we don't use asynchronous interaction in this
    // program.
    type Others = ();
    // The unit tuple is used as we don't process any replies in this program.
    type Reply = ();
    // The unit tuple is used as we don't process any signals in this program.
    type Signal = ();
    // We return a counter value (`i32`) in the `state()` function in this program.
    type State = Out<i32>;
}
  • ping 程序 crate
#[no_std]
use gmeta::{InOut, Metadata};
use gstd::{msg, prelude::*};
use ping_io::PingPong;

// Counter that will be incremented on each `Ping` message.
static mut COUNTER: i32 = 0;

#
#[no_mangle]
extern "C" fn handle() {
    // Load incoming message of `PingPong` type.
    let payload: PingPong = msg::load().expect("Unable to load");

    if let PingPong::Ping = payload {
        unsafe { COUNTER += 1 };
        // Send a reply message of `PingPong` type back to the sender.
        msg::reply(PingPong::Pong, 0).expect("Unable to reply");
    }
}

#[no_mangle]
extern "C" fn state() {
    msg::reply(unsafe { COUNTER }, 0).expect("Unable to reply");
}
  • build.rs 文件
use ping_io::ProgramMetadata;
#

fn main() {
    gear_wasm_builder::build_with_metadata::<ProgramMetadata>();
}

您还可以在不使用 build.rs 的情况下手动生成元数据并将其写入文件。

use gmeta::{Metadata, Out};
use ping_io::ProgramMetadata;
use std::fs;

#
#
let metadata_hex = ProgramMetadata::repr().hex();
assert_eq!(metadata_hex.len(), 146);
fs::write("ping.meta.txt", metadata_hex).expect("Unable to write");

您可以使用 JavaScript 中的 gear-js API 解析生成的元数据文件。

import { getProgramMetadata } from '@gear-js/api';
import { readFileSync } from 'fs';

const metadataHex = readFileSync('ping.meta.txt', 'utf-8');
const metadata = getProgramMetadata('0x' + metadataHex);

console.log('Registry:', metadata.regTypes);
console.log('Types:', metadata.types);

这将打印以下内容

Registry: Map(2) {
  0 => { name: 'RustOutPingPong', def: '{"_enum":["Ping","Pong"]}' },
  1 => { name: 'i32', def: null }
}
Types: {
  init: { input: null, output: null },
  handle: { input: 0, output: 0 },
  reply: { input: null, output: null },
  others: { input: null, output: null },
  signal: null,
  state: 1
}

依赖项

~3.5MB
~79K SLoC