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 |
|
#27 in #gear
1,645 个月下载量
在 16 个 包中使用 (7 个直接使用)
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