Skip to content

Commit

Permalink
feat(models): add MsgType
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Sep 2, 2024
1 parent 3c3e613 commit 084eb23
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,6 @@ opt-level = 1

[package.metadata.docs.rs]
features = ["base64", "serde", "models", "sync", "stats", "abi"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
83 changes: 83 additions & 0 deletions src/models/message/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Message models.

use std::borrow::Borrow;

use crate::cell::*;
use crate::error::Error;
use crate::num::*;
Expand Down Expand Up @@ -131,6 +133,13 @@ where
}
}

impl<I: Borrow<MsgInfo>, B> BaseMessage<I, B> {
/// Returns the type of this message.
pub fn ty(&self) -> MsgType {
self.info.borrow().ty()
}
}

impl<I: ExactSize, B: ExactSize> BaseMessage<I, B> {
/// Computes the most optimal layout of the message parts.
pub fn compute_layout(info: &I, init: Option<&StateInit>, body: &B) -> MessageLayout {
Expand Down Expand Up @@ -576,6 +585,56 @@ impl<'a> Load<'a> for RelaxedMsgInfo {
}
}

/// Message type.
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub enum MsgType {
/// Internal message.
Int,
/// External incoming message.
ExtIn,
/// External outgoing message.
ExtOut,
}

impl MsgType {
/// Returns whether this message is internal.
pub const fn is_internal(&self) -> bool {
matches!(self, Self::Int)
}

/// Returns whether this message is external incoming.
pub const fn is_external_in(&self) -> bool {
matches!(self, Self::ExtIn)
}

/// Returns whether this message is external outgoing.
pub const fn is_external_out(&self) -> bool {
matches!(self, Self::ExtOut)
}
}

impl Store for MsgType {
fn store_into(&self, b: &mut CellBuilder, _: &mut dyn CellContext) -> Result<(), Error> {
match self {
Self::Int => b.store_bit_zero(),
Self::ExtIn => b.store_small_uint(0b10, 2),
Self::ExtOut => b.store_small_uint(0b11, 2),
}
}
}

impl<'a> Load<'a> for MsgType {
fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
Ok(if !ok!(slice.load_bit()) {
Self::Int
} else if !ok!(slice.load_bit()) {
Self::ExtIn
} else {
Self::ExtOut
})
}
}

/// Message info.
#[derive(Debug, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Expand All @@ -590,6 +649,30 @@ pub enum MsgInfo {
}

impl MsgInfo {
/// Returns the type of this message info.
pub const fn ty(&self) -> MsgType {
match self {
Self::Int(_) => MsgType::Int,
Self::ExtIn(_) => MsgType::ExtIn,
Self::ExtOut(_) => MsgType::ExtOut,
}
}

/// Returns whether this message is internal.
pub const fn is_internal(&self) -> bool {
matches!(self, Self::Int(_))
}

/// Returns whether this message is external incoming.
pub const fn is_external_in(&self) -> bool {
matches!(self, Self::ExtIn(_))
}

/// Returns whether this message is external outgoing.
pub const fn is_external_out(&self) -> bool {
matches!(self, Self::ExtOut(_))
}

/// Exact size of this value when it is stored in slice.
pub const fn exact_size_const(&self) -> Size {
Size {
Expand Down
9 changes: 9 additions & 0 deletions src/models/message/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ fn check_message(boc: &[u8]) -> Cell {
#[test]
fn external_message() -> anyhow::Result<()> {
let boc = check_message(include_bytes!("external_message.boc"));
assert_eq!(boc.parse::<MsgType>()?, MsgType::ExtIn);

let body = Boc::decode(include_bytes!("external_message_body.boc")).unwrap();
let serialized = serialize_message(Message {
info: MsgInfo::ExtIn(ExtInMsgInfo {
Expand All @@ -57,6 +59,8 @@ fn external_message() -> anyhow::Result<()> {
#[test]
fn external_outgoing() {
let boc = check_message(include_bytes!("external_out_message.boc"));
assert_eq!(boc.parse::<MsgType>().unwrap(), MsgType::ExtOut);

let body = Boc::decode_base64("te6ccgEBAQEADgAAGJMdgs1k/wsgCERmwQ==").unwrap();
let serialized = serialize_message(Message {
info: MsgInfo::ExtOut(ExtOutMsgInfo {
Expand All @@ -77,6 +81,7 @@ fn external_outgoing() {
#[test]
fn internal_message_empty() {
let boc = check_message(include_bytes!("empty_internal_message.boc"));
assert_eq!(boc.parse::<MsgType>().unwrap(), MsgType::Int);

let serialized = serialize_message(Message {
info: MsgInfo::Int(IntMsgInfo {
Expand All @@ -103,6 +108,8 @@ fn internal_message_empty() {
#[test]
fn internal_message_with_body() -> anyhow::Result<()> {
let boc = check_message(include_bytes!("internal_message_with_body.boc"));
assert_eq!(boc.parse::<MsgType>().unwrap(), MsgType::Int);

let body = Boc::decode(include_bytes!("internal_message_body.boc")).unwrap();

let serialized = serialize_message(Message {
Expand Down Expand Up @@ -132,6 +139,7 @@ fn internal_message_with_body() -> anyhow::Result<()> {
#[test]
fn internal_message_with_deploy() -> anyhow::Result<()> {
let boc = check_message(include_bytes!("internal_message_with_deploy.boc"));
assert_eq!(boc.parse::<MsgType>().unwrap(), MsgType::Int);

let init = Boc::decode(include_bytes!(
"internal_message_with_deploy_state_init.boc"
Expand Down Expand Up @@ -170,6 +178,7 @@ fn internal_message_with_deploy_special() -> anyhow::Result<()> {
use crate::models::account::*;

let boc = check_message(include_bytes!("internal_message_with_deploy_special.boc"));
assert_eq!(boc.parse::<MsgType>().unwrap(), MsgType::Int);

let init = StateInit {
split_depth: None,
Expand Down

0 comments on commit 084eb23

Please sign in to comment.