gmsol_decode/value/
event.rs

1use std::marker::PhantomData;
2
3use solana_sdk::signature::Signature;
4
5use crate::{Decode, Visitor};
6
7use super::OwnedData;
8
9/// Anchor CPI Events.
10#[derive(Debug, Clone)]
11pub struct AnchorCPIEvents<T> {
12    slot: u64,
13    index: Option<usize>,
14    signature: Signature,
15    events: Vec<OwnedData<T>>,
16}
17
18impl<T> AnchorCPIEvents<T> {
19    /// Get the slot at which the events were generated.
20    pub fn slot(&self) -> u64 {
21        self.slot
22    }
23
24    /// Get the `index` in the block of the transaction where the events were genereated.
25    pub fn index(&self) -> Option<usize> {
26        self.index
27    }
28
29    /// Get the `signature` of the transaction where the events were generated.
30    pub fn signature(&self) -> &Signature {
31        &self.signature
32    }
33
34    /// Get the event datas.
35    pub fn events(&self) -> &[OwnedData<T>] {
36        &self.events
37    }
38}
39
40impl<T> IntoIterator for AnchorCPIEvents<T> {
41    type Item = OwnedData<T>;
42
43    type IntoIter = std::vec::IntoIter<Self::Item>;
44
45    fn into_iter(self) -> Self::IntoIter {
46        self.events.into_iter()
47    }
48}
49
50impl<T> Decode for AnchorCPIEvents<T>
51where
52    T: Decode,
53{
54    fn decode<D: crate::Decoder>(decoder: D) -> Result<Self, crate::DecodeError> {
55        struct CPIEventsData<T>(PhantomData<T>);
56
57        impl<T> Visitor for CPIEventsData<T>
58        where
59            T: Decode,
60        {
61            type Value = AnchorCPIEvents<T>;
62
63            fn visit_anchor_cpi_events<'a>(
64                self,
65                mut events: impl crate::AnchorCPIEventsAccess<'a>,
66            ) -> Result<Self::Value, crate::DecodeError> {
67                let slot = events.slot()?;
68                let index = events.index()?;
69                let signature = *events.signature()?;
70                let events =
71                    std::iter::repeat_with(|| events.next_event::<OwnedData<T>>().transpose())
72                        .take_while(Option::is_some)
73                        .flatten()
74                        .collect::<Result<Vec<_>, crate::DecodeError>>()?;
75                Ok(AnchorCPIEvents {
76                    signature,
77                    slot,
78                    index,
79                    events,
80                })
81            }
82        }
83
84        let events = decoder.decode_anchor_cpi_events(CPIEventsData::<T>(PhantomData))?;
85
86        Ok(events)
87    }
88}