| Crates.io | rusmpp-macros |
| lib.rs | rusmpp-macros |
| version | 0.2.0 |
| created_at | 2025-10-10 09:55:05.112994+00 |
| updated_at | 2025-12-16 11:48:58.662349+00 |
| description | Procedural macros for Rusmpp-Core |
| homepage | |
| repository | https://github.com/Rusmpp/Rusmpp |
| max_upload_size | |
| id | 1876737 |
| size | 161,868 |
Procedural macros for rusmpp-core. Used to derive traits defined in rusmpp-core and implement boilerplate code for SMPP types.
This crate assumes that the traits are defined in the crate itself under the modules decode, encode and tests.
You should not depend on this crate directly as it is strongly coupled with rusmpp-core.
#[derive(Rusmpp)]
#[rusmpp(decode = owned)]
pub struct Command {
id: CommandId,
pub status: CommandStatus,
pub sequence_number: u32,
#[rusmpp(key = id, length = "unchecked")]
pdu: Option<Pdu>,
}
This will expand to:
#[derive(Debug)]
pub struct CommandParts {
pub id: CommandId,
pub status: CommandStatus,
pub sequence_number: u32,
pub pdu: Option<Pdu>,
}
impl CommandParts {
#[inline]
#[allow(clippy::too_many_arguments)]
pub const fn new(
id: CommandId,
status: CommandStatus,
sequence_number: u32,
pdu: Option<Pdu>,
) -> Self {
Self {
id,
status,
sequence_number,
pdu,
}
}
#[inline]
#[allow(unused_parens)]
pub fn raw(self) -> (CommandId, CommandStatus, u32, Option<Pdu>) {
(self.id, self.status, self.sequence_number, self.pdu)
}
}
impl Command {
#[inline]
pub fn into_parts(self) -> CommandParts {
CommandParts {
id: self.id,
status: self.status,
sequence_number: self.sequence_number,
pdu: self.pdu,
}
}
}
impl crate::encode::Length for Command {
fn length(&self) -> usize {
let mut length = 0;
length += crate::encode::Length::length(&self.id);
length += crate::encode::Length::length(&self.status);
length += crate::encode::Length::length(&self.sequence_number);
length += crate::encode::Length::length(&self.pdu);
length
}
}
impl crate::encode::Encode for Command {
fn encode(&self, dst: &mut [u8]) -> usize {
let size = 0;
let size = crate::encode::EncodeExt::encode_move(&self.id, dst, size);
let size = crate::encode::EncodeExt::encode_move(&self.status, dst, size);
let size = crate::encode::EncodeExt::encode_move(&self.sequence_number, dst, size);
let size = crate::encode::EncodeExt::encode_move(&self.pdu, dst, size);
size
}
}
impl crate::decode::owned::DecodeWithLength for Command {
fn decode(src: &[u8], length: usize) -> Result<(Self, usize), crate::decode::DecodeError> {
let size = 0;
let (id, size) = crate::decode::DecodeErrorExt::map_as_source(
crate::decode::owned::DecodeExt::decode_move(src, size),
crate::fields::SmppField::id,
)?;
let (status, size) = crate::decode::DecodeErrorExt::map_as_source(
crate::decode::owned::DecodeExt::decode_move(src, size),
crate::fields::SmppField::status,
)?;
let (sequence_number, size) = crate::decode::DecodeErrorExt::map_as_source(
crate::decode::owned::DecodeExt::decode_move(src, size),
crate::fields::SmppField::sequence_number,
)?;
let (pdu, size) = crate::decode::DecodeErrorExt::map_as_source(
crate::decode::owned::DecodeWithKeyOptionalExt::decode_move(
id,
src,
length.saturating_sub(size),
size,
),
crate::fields::SmppField::pdu,
)?
.map(|(this, size)| (Some(this), size))
.unwrap_or((None, size));
Ok((
Self {
id,
status,
sequence_number,
pdu,
},
size,
))
}
}
Notice the crate prefix. This is because the macro assumes that the traits are defined in the same crate.
Macro attributes are documented in the macro code itself.
Licensed under either of
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.