proc_macro_assertions/
passed_data.rs

1use std::ops::{Deref, DerefMut};
2
3use proc_macro2::TokenStream;
4
5use crate::token_store::{AddTokens, TokenLevel, TokenStore};
6
7/// Data passed between stages during generation of [`Generatable`](crate::generatable::Generatable) types.
8#[derive(Debug, Default)]
9pub struct PassedData<T> {
10    /// The tokens returned by the stage
11    tokens: Option<TokenStream>,
12    /// The data passed
13    data: T,
14}
15
16impl<T> Eq for PassedData<T> where T: Eq {}
17
18impl<T> PartialEq for PassedData<T>
19where
20    T: Eq,
21{
22    fn eq(&self, other: &Self) -> bool {
23        let data_is_equal = self.data == other.data;
24
25        let self_string_tokens = self.tokens.as_ref().map(ToString::to_string);
26        let other_string_tokens = other.tokens.as_ref().map(ToString::to_string);
27
28        let tokens_are_equal = self_string_tokens == other_string_tokens;
29
30        data_is_equal && tokens_are_equal
31    }
32}
33
34impl<T> From<PassedData<T>> for TokenStream {
35    fn from(passed_data: PassedData<T>) -> Self {
36        passed_data.tokens.unwrap_or_default()
37    }
38}
39
40impl<T> PassedData<T> {
41    /// Create new passed data from tokens
42    #[must_use]
43    pub fn tokens(tokens: TokenStream) -> Self
44    where
45        T: Default,
46    {
47        Self {
48            tokens: Some(tokens),
49            data: T::default(),
50        }
51    }
52
53    /// Create new passed data from the data.
54    pub const fn data(data: T) -> Self {
55        Self { tokens: None, data }
56    }
57
58    /// Remove the data from `Self`.
59    pub fn without_data(self) -> PassedData<()> {
60        PassedData {
61            tokens: self.tokens,
62            data: (),
63        }
64    }
65
66    /// Change tokens of `Self` to `tokens`.
67    #[must_use]
68    pub fn with_tokens(self, tokens: TokenStream) -> Self {
69        Self {
70            data: self.data,
71            tokens: Some(tokens),
72        }
73    }
74
75    /// Seperate tokens into a [`TokenStore`](crate::token_store::TokenStore), and return the passed data.
76    pub(crate) fn seperate_tokens_into(
77        self,
78        token_level: TokenLevel,
79        token_store: &mut TokenStore,
80    ) -> T {
81        token_store.add_tokens(token_level, self.tokens);
82
83        self.data
84    }
85}
86
87/// Add some data to some tokens, wrapping them into [`PassedData`].
88pub trait WithData {
89    fn with_data<T>(self, data: T) -> PassedData<T>;
90}
91
92impl WithData for TokenStream {
93    fn with_data<T>(self, data: T) -> PassedData<T> {
94        PassedData {
95            tokens: Some(self),
96            data,
97        }
98    }
99}
100
101impl<T> Deref for PassedData<T> {
102    type Target = T;
103
104    fn deref(&self) -> &Self::Target {
105        &self.data
106    }
107}
108
109impl<T> DerefMut for PassedData<T> {
110    fn deref_mut(&mut self) -> &mut Self::Target {
111        &mut self.data
112    }
113}