fuel_streams_core/blocks/subjects.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use fuel_streams_macros::subject::{IntoSubject, Subject, SubjectBuildable};
use crate::types::*;
/// Represents a NATS subject for blocks in the Fuel network.
///
/// This subject format allows for efficient querying and filtering of blocks
/// based on their producer and height.
///
/// # Examples
///
/// Creating a subject for a specific block:
///
/// ```
/// # use fuel_streams_core::blocks::BlocksSubject;
/// # use fuel_streams_core::types::*;
/// # use fuel_streams_macros::subject::IntoSubject;
/// let subject = BlocksSubject {
/// producer: Some(Address::zeroed()),
/// height: Some(23.into()),
/// };
/// assert_eq!(subject.parse(), "blocks.0x0000000000000000000000000000000000000000000000000000000000000000.23");
/// ```
///
/// All blocks wildcard:
///
/// ```
/// # use fuel_streams_core::blocks::BlocksSubject;
/// assert_eq!(BlocksSubject::WILDCARD, "blocks.>");
/// ```
///
/// Creating a subject query using the `wildcard` method for flexible parameter-based filtering
///
/// ```
/// # use fuel_streams_core::blocks::BlocksSubject;
/// # use fuel_streams_core::types::*;
/// let wildcard = BlocksSubject::wildcard(None, Some(23.into()));
/// assert_eq!(wildcard, "blocks.*.23");
/// ```
///
/// Using the builder pattern for flexible subject construction:
/// This approach allows for step-by-step creation of a `BlocksSubject`,
///
/// ```
/// # use fuel_streams_core::blocks::BlocksSubject;
/// # use fuel_streams_core::types::*;
/// # use fuel_streams_macros::subject::*;
/// let subject = BlocksSubject::new()
/// .with_producer(Some(Address::zeroed()))
/// .with_height(Some(23.into()));
/// assert_eq!(subject.parse(), "blocks.0x0000000000000000000000000000000000000000000000000000000000000000.23");
/// ```
#[derive(Subject, Debug, Clone, Default)]
#[subject_wildcard = "blocks.>"]
#[subject_format = "blocks.{producer}.{height}"]
pub struct BlocksSubject {
pub producer: Option<Address>,
pub height: Option<BlockHeight>,
}
impl From<&Block> for BlocksSubject {
fn from(block: &Block) -> Self {
let block_height = *block.header().height();
BlocksSubject::new().with_height(Some(BlockHeight::from(block_height)))
}
}
#[cfg(test)]
mod test {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn block_subjects_from_block() {
let mock_block = &MockBlock::build(1);
let subject: BlocksSubject = mock_block.into();
assert!(subject.producer.is_none());
assert_eq!(subject.height.unwrap(), mock_block.clone().into());
}
}