1#![allow(unreachable_pub)]
5#![allow(clippy::derive_partial_eq_without_eq)]
7
8use identifiers::expand_id_zst;
9use palpo_identifiers_validation::{
10 device_key_id, event_id, key_id, mxc_uri, room_alias_id, room_id, room_version_id, server_name, user_id,
11};
12use proc_macro::TokenStream;
13use proc_macro2 as pm2;
14use quote::quote;
15use syn::{DeriveInput, ItemEnum, ItemStruct, parse_macro_input};
16
17mod events;
18mod identifiers;
19mod serde;
20mod util;
21
22use self::{
23 events::{
24 event::expand_event,
25 event_content::expand_event_content,
26 event_enum::{expand_event_enums, expand_from_impls_derived},
27 event_parse::EventEnumInput,
28 event_type::expand_event_type_enum,
29 },
30 identifiers::IdentifierInput,
31 serde::{
32 as_str_as_ref_str::expand_as_str_as_ref_str,
33 debug_as_ref_str::expand_debug_as_ref_str,
34 deserialize_from_cow_str::expand_deserialize_from_cow_str,
35 display_as_ref_str::expand_display_as_ref_str,
36 enum_as_ref_str::expand_enum_as_ref_str,
37 enum_from_string::expand_enum_from_string,
38 eq_as_ref_str::expand_partial_eq_as_ref_str,
39 ord_as_ref_str::{expand_ord_as_ref_str, expand_partial_ord_as_ref_str},
40 serialize_as_ref_str::expand_serialize_as_ref_str,
41 },
42 util::import_palpo_core,
43};
44
45#[proc_macro]
72pub fn event_enum(input: TokenStream) -> TokenStream {
73 let event_enum_input = syn::parse_macro_input!(input as EventEnumInput);
74
75 let palpo_core = import_palpo_core();
76
77 let enums = event_enum_input
78 .enums
79 .iter()
80 .map(|e| expand_event_enums(e).unwrap_or_else(syn::Error::into_compile_error))
81 .collect::<pm2::TokenStream>();
82
83 let event_types =
84 expand_event_type_enum(event_enum_input, &palpo_core).unwrap_or_else(syn::Error::into_compile_error);
85
86 let tokens = quote! {
87 #enums
88 #event_types
89 };
90
91 tokens.into()
92}
93
94#[proc_macro_derive(EventContent, attributes(palpo_event))]
110pub fn derive_event_content(input: TokenStream) -> TokenStream {
111 let palpo_core = import_palpo_core();
112 let input = parse_macro_input!(input as DeriveInput);
113
114 expand_event_content(&input, &palpo_core)
115 .unwrap_or_else(syn::Error::into_compile_error)
116 .into()
117}
118
119#[proc_macro_derive(Event, attributes(palpo_event))]
121pub fn derive_event(input: TokenStream) -> TokenStream {
122 let input = parse_macro_input!(input as DeriveInput);
123 expand_event(input)
124 .unwrap_or_else(syn::Error::into_compile_error)
125 .into()
126}
127
128#[proc_macro_derive(EventEnumFromEvent)]
130pub fn derive_from_event_to_enum(input: TokenStream) -> TokenStream {
131 let input = parse_macro_input!(input as DeriveInput);
132 expand_from_impls_derived(input).into()
133}
134
135#[proc_macro_derive(IdZst, attributes(palpo_id))]
137pub fn derive_id_zst(input: TokenStream) -> TokenStream {
138 let input = parse_macro_input!(input as ItemStruct);
139 expand_id_zst(input)
140 .unwrap_or_else(syn::Error::into_compile_error)
141 .into()
142}
143
144#[proc_macro]
146pub fn device_key_id(input: TokenStream) -> TokenStream {
147 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
148 assert!(device_key_id::validate(&id.value()).is_ok(), "Invalid device key id");
149
150 let output = quote! {
151 <&#dollar_crate::DeviceKeyId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
152 };
153
154 output.into()
155}
156
157#[proc_macro]
159pub fn event_id(input: TokenStream) -> TokenStream {
160 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
161 assert!(event_id::validate(&id.value()).is_ok(), "Invalid event id");
162
163 let output = quote! {
164 <&#dollar_crate::EventId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
165 };
166
167 output.into()
168}
169
170#[proc_macro]
172pub fn room_alias_id(input: TokenStream) -> TokenStream {
173 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
174 assert!(room_alias_id::validate(&id.value()).is_ok(), "Invalid room_alias_id");
175
176 let output = quote! {
177 <&#dollar_crate::RoomAliasId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
178 };
179
180 output.into()
181}
182
183#[proc_macro]
185pub fn room_id(input: TokenStream) -> TokenStream {
186 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
187 assert!(room_id::validate(&id.value()).is_ok(), "Invalid room_id");
188
189 let output = quote! {
190 <&#dollar_crate::RoomId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
191 };
192
193 output.into()
194}
195
196#[proc_macro]
198pub fn room_version_id(input: TokenStream) -> TokenStream {
199 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
200 assert!(
201 room_version_id::validate(&id.value()).is_ok(),
202 "Invalid room_version_id"
203 );
204
205 let output = quote! {
206 <#dollar_crate::RoomVersionId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
207 };
208
209 output.into()
210}
211
212#[proc_macro]
214pub fn server_signing_key_id(input: TokenStream) -> TokenStream {
215 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
216 assert!(key_id::validate(&id.value()).is_ok(), "Invalid server_signing_key_id");
217
218 let output = quote! {
219 <&#dollar_crate::ServerSigningKeyId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
220 };
221
222 output.into()
223}
224
225#[proc_macro]
227pub fn server_name(input: TokenStream) -> TokenStream {
228 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
229 assert!(server_name::validate(&id.value()).is_ok(), "Invalid server_name");
230
231 let output = quote! {
232 <&#dollar_crate::ServerName as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
233 };
234
235 output.into()
236}
237
238#[proc_macro]
240pub fn mxc_uri(input: TokenStream) -> TokenStream {
241 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
242 assert!(mxc_uri::validate(&id.value()).is_ok(), "Invalid mxc://");
243
244 let output = quote! {
245 <&#dollar_crate::MxcUri as ::std::convert::From<&str>>::from(#id)
246 };
247
248 output.into()
249}
250
251#[proc_macro]
253pub fn user_id(input: TokenStream) -> TokenStream {
254 let IdentifierInput { dollar_crate, id } = parse_macro_input!(input as IdentifierInput);
255 assert!(user_id::validate(&id.value()).is_ok(), "Invalid user_id");
256
257 let output = quote! {
258 <&#dollar_crate::UserId as ::std::convert::TryFrom<&str>>::try_from(#id).unwrap()
259 };
260
261 output.into()
262}
263
264#[proc_macro_derive(AsRefStr, attributes(palpo_enum))]
266pub fn derive_enum_as_ref_str(input: TokenStream) -> TokenStream {
267 let input = parse_macro_input!(input as ItemEnum);
268 expand_enum_as_ref_str(&input)
269 .unwrap_or_else(syn::Error::into_compile_error)
270 .into()
271}
272
273#[proc_macro_derive(FromString, attributes(palpo_enum))]
275pub fn derive_enum_from_string(input: TokenStream) -> TokenStream {
276 let input = parse_macro_input!(input as ItemEnum);
277 expand_enum_from_string(&input)
278 .unwrap_or_else(syn::Error::into_compile_error)
279 .into()
280}
281
282#[proc_macro_derive(AsStrAsRefStr, attributes(palpo_enum))]
287pub fn derive_as_str_as_ref_str(input: TokenStream) -> TokenStream {
288 let input = parse_macro_input!(input as DeriveInput);
289 expand_as_str_as_ref_str(&input.ident)
290 .unwrap_or_else(syn::Error::into_compile_error)
291 .into()
292}
293
294#[proc_macro_derive(DisplayAsRefStr)]
296pub fn derive_display_as_ref_str(input: TokenStream) -> TokenStream {
297 let input = parse_macro_input!(input as DeriveInput);
298 expand_display_as_ref_str(&input.ident)
299 .unwrap_or_else(syn::Error::into_compile_error)
300 .into()
301}
302
303#[proc_macro_derive(DebugAsRefStr)]
305pub fn derive_debug_as_ref_str(input: TokenStream) -> TokenStream {
306 let input = parse_macro_input!(input as DeriveInput);
307 expand_debug_as_ref_str(&input.ident)
308 .unwrap_or_else(syn::Error::into_compile_error)
309 .into()
310}
311
312#[proc_macro_derive(SerializeAsRefStr)]
314pub fn derive_serialize_as_ref_str(input: TokenStream) -> TokenStream {
315 let input = parse_macro_input!(input as DeriveInput);
316 expand_serialize_as_ref_str(&input.ident)
317 .unwrap_or_else(syn::Error::into_compile_error)
318 .into()
319}
320
321#[proc_macro_derive(DeserializeFromCowStr)]
323pub fn derive_deserialize_from_cow_str(input: TokenStream) -> TokenStream {
324 let input = parse_macro_input!(input as DeriveInput);
325 expand_deserialize_from_cow_str(&input.ident)
326 .unwrap_or_else(syn::Error::into_compile_error)
327 .into()
328}
329
330#[proc_macro_derive(PartialOrdAsRefStr)]
332pub fn derive_partial_ord_as_ref_str(input: TokenStream) -> TokenStream {
333 let input = parse_macro_input!(input as DeriveInput);
334 expand_partial_ord_as_ref_str(&input.ident)
335 .unwrap_or_else(syn::Error::into_compile_error)
336 .into()
337}
338
339#[proc_macro_derive(OrdAsRefStr)]
341pub fn derive_ord_as_ref_str(input: TokenStream) -> TokenStream {
342 let input = parse_macro_input!(input as DeriveInput);
343 expand_ord_as_ref_str(&input.ident)
344 .unwrap_or_else(syn::Error::into_compile_error)
345 .into()
346}
347
348#[proc_macro_derive(PartialEqAsRefStr)]
350pub fn derive_partial_eq_as_ref_str(input: TokenStream) -> TokenStream {
351 let input = parse_macro_input!(input as DeriveInput);
352 expand_partial_eq_as_ref_str(&input.ident)
353 .unwrap_or_else(syn::Error::into_compile_error)
354 .into()
355}
356
357#[proc_macro_derive(StringEnum, attributes(palpo_enum))]
360pub fn derive_string_enum(input: TokenStream) -> TokenStream {
361 fn expand_all(input: ItemEnum) -> syn::Result<proc_macro2::TokenStream> {
362 let as_ref_str_impl = expand_enum_as_ref_str(&input)?;
363 let from_string_impl = expand_enum_from_string(&input)?;
364 let as_str_impl = expand_as_str_as_ref_str(&input.ident)?;
365 let display_impl = expand_display_as_ref_str(&input.ident)?;
366 let debug_impl = expand_debug_as_ref_str(&input.ident)?;
367 let serialize_impl = expand_serialize_as_ref_str(&input.ident)?;
368 let deserialize_impl = expand_deserialize_from_cow_str(&input.ident)?;
369
370 Ok(quote! {
371 #as_ref_str_impl
372 #from_string_impl
373 #as_str_impl
374 #display_impl
375 #debug_impl
376 #serialize_impl
377 #deserialize_impl
378 })
379 }
380
381 let input = parse_macro_input!(input as ItemEnum);
382 expand_all(input).unwrap_or_else(syn::Error::into_compile_error).into()
383}