PING-PONG
Vara is very easy to write code for! Let's look at the minimal program.
The code of the program is in the src/lib.rs
file. The program replies with Pong
string if the sender sent Ping
message to it. It also saves how many times a user sent a ping message to the program.
So, the program contains:
- message log definition:
ping/src/lib.rs
static mut MESSAGE_LOG: Vec<String> = vec![];
- entry point
handle
:
ping/src/lib.rs
#[no_mangle]
extern fn handle() {
let new_msg: String = msg::load().expect("Unable to create string");
if new_msg == "PING" {
msg::reply_bytes("PONG", 0).expect("Unable to reply");
}
unsafe {
MESSAGE_LOG.push(new_msg);
debug!("{:?} total message(s) stored: ", MESSAGE_LOG.len());
for log in &MESSAGE_LOG {
debug!("{log:?}");
}
}
}
state
function that allows to read the program state:
ping/src/lib.rs
#[no_mangle]
extern fn state() {
msg::reply(unsafe { MESSAGE_LOG.clone() }, 0)
.expect("Failed to encode or reply with `<AppMetadata as Metadata>::State` from `state()`");
}
The io
crate defines the program metadata.
ping/io/src/lib.rs
#![no_std]
use gmeta::{InOut, Metadata, Out};
use gstd::prelude::*;
pub struct DemoPingMetadata;
impl Metadata for DemoPingMetadata {
type Init = ();
type Handle = InOut<String, String>;
type Others = ();
type Reply = ();
type Signal = ();
type State = Out<Vec<String>>;
}
The DemoPingMetadata
struct is used in build.rs
in order to generate meta.txt
file:
ping/build.rs
use ping_io::DemoPingMetadata;
fn main() {
gear_wasm_builder::build_with_metadata::<DemoPingMetadata>();
}
The state
is the independent crate for reading the program state. It depends on the ping-io
crate where the type of the program state is defined:
ping/state/src/lib.rs
#![no_std]
use gstd::prelude::*;
#[gmeta::metawasm]
pub mod metafns {
pub type State = Vec<String>;
pub fn get_first_message(state: State) -> String {
state.first().expect("Message log is empty!").to_string()
}
pub fn get_last_message(state: State) -> String {
state.last().expect("Message log is empty!").to_string()
}
pub fn get_messages_len(state: State) -> u64 {
state.len() as u64
}
pub fn get_message(state: State, index: u64) -> String {
state
.get(index as usize)
.expect("Invalid index!")
.to_string()
}
}
In the tests directory, you can see an example of testing the program using gclient
and gtest
. For more details about testing Vara programs, refer to the Program Testing article.