1use proc_macro::TokenStream;
24use proc_macro_error2::{abort_call_site, proc_macro_error};
25use proc_macro2::TokenStream as TokenStream2;
26use quote::quote;
27use std::convert::*;
28
29mod common;
30mod entity;
31mod field_type;
32mod holder_attr;
33mod select;
34mod table_init;
35mod type_decl;
36
37use common::*;
38use field_type::*;
39use holder_attr::*;
40use table_init::*;
41
42#[proc_macro_error]
74#[proc_macro_derive(TableInit)]
75pub fn derive_table_init_entry(input: TokenStream) -> TokenStream {
76 derive_table_init(&syn::parse(input).unwrap()).into()
77}
78
79#[proc_macro_error]
81#[proc_macro_derive(Deserialize)]
82pub fn derive_deserialize_entry(input: TokenStream) -> TokenStream {
83 derive_deserialize(&syn::parse(input).unwrap()).into()
84}
85
86fn derive_deserialize(ast: &syn::DeriveInput) -> TokenStream2 {
87 let ident = &ast.ident;
88 match &ast.data {
89 syn::Data::Struct(st) => entity::derive_deserialize(ident, st),
90 syn::Data::Enum(e) => select::derive_deserialize(ident, e),
91 _ => abort_call_site!("Only struct is supprted currently"),
92 }
93}
94
95#[proc_macro_error]
135#[proc_macro_derive(Holder, attributes(holder))]
136pub fn derive_holder_entry(input: TokenStream) -> TokenStream {
137 derive_holder(&syn::parse(input).unwrap()).into()
138}
139
140fn derive_holder(ast: &syn::DeriveInput) -> TokenStream2 {
141 let attr = HolderAttr::parse(&ast.attrs);
142 let ident = &ast.ident;
143 match &ast.data {
144 syn::Data::Struct(st) => match st.fields {
145 syn::Fields::Named(_) => entity::derive_holder(ident, st, &attr),
146 syn::Fields::Unnamed(_) => {
147 type_decl::derive_holder(ident, st, &attr)
148 }
149 syn::Fields::Unit => {
150 abort_call_site!("Unit struct is not supported.")
151 }
152 },
153 syn::Data::Enum(e) => select::derive_holder(ident, e, &attr),
154 _ => abort_call_site!("Only struct is supprted currently"),
155 }
156}
157
158#[proc_macro_error]
162#[proc_macro]
163pub fn as_holder(input: TokenStream) -> TokenStream {
164 let path = as_holder_path(&syn::parse(input).unwrap());
165 let ts = quote! { #path };
166 ts.into()
167}
168
169#[cfg(test)]
170mod snapshot_tests {
171 use super::derive_holder;
172
173 #[test]
174 fn derive_holder_enum() {
175 let input: syn::DeriveInput = syn::parse_str(
176 r#"
177 #[holder(table = Table)]
178 #[holder(generate_deserialize)]
179 pub enum S1 {
180 #[holder(use_place_holder)]
181 A(Box<A>),
182 #[holder(use_place_holder)]
183 B(Box<B>),
184 }
185 "#,
186 )
187 .unwrap();
188
189 let tt = derive_holder(&input);
190 let out = step_p11::codegen::rust::rustfmt(tt.to_string());
191
192 insta::assert_snapshot!(out, @r#"
193 #[doc = r" Auto-generated by `#[derive(Holder)]`"]
194 #[derive(Clone, Debug, PartialEq)]
195 pub enum S1Holder {
196 A(Box<AHolder>),
197 B(Box<BHolder>),
198 }
199 impl ::step_p21::tables::IntoOwned for S1Holder {
200 type Owned = S1;
201 type Table = Table;
202
203 fn into_owned(
204 self,
205 table: &Self::Table,
206 ) -> ::step_p21::error::Result<Self::Owned> {
207 Ok(match self {
208 S1Holder::A(sub) => S1::A(Box::new(sub.into_owned(table)?)),
209 S1Holder::B(sub) => S1::B(Box::new(sub.into_owned(table)?)),
210 })
211 }
212 }
213 impl ::step_p21::tables::Holder for S1Holder {
214 fn name() -> &'static str {
215 "S1"
216 }
217
218 fn attr_len() -> usize {
219 0
220 }
221 }
222 impl<'de> ::step_p21::serde::de::Deserialize<'de> for S1Holder {
223 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
224 where
225 D: ::step_p21::serde::de::Deserializer<'de>,
226 {
227 deserializer.deserialize_tuple_struct("S1", 0, S1HolderVisitor {})
228 }
229 }
230 #[doc(hidden)]
231 pub struct S1HolderVisitor;
232 impl<'de> ::step_p21::serde::de::Visitor<'de> for S1HolderVisitor {
233 type Value = S1Holder;
234
235 fn expecting(
236 &self,
237 formatter: &mut ::std::fmt::Formatter,
238 ) -> ::std::fmt::Result {
239 write!(formatter, "S1")
240 }
241
242 fn visit_map<A>(
243 self,
244 mut map: A,
245 ) -> ::std::result::Result<Self::Value, A::Error>
246 where
247 A: ::step_p21::serde::de::MapAccess<'de>,
248 {
249 let key: String = map
250 .next_key()?
251 .expect("Empty map cannot be accepted as step_p21 Holder");
252 match key.as_str() {
253 "A" => {
254 let owned = map.next_value()?;
255 return Ok(S1Holder::A(Box::new(owned)));
256 }
257 "B" => {
258 let owned = map.next_value()?;
259 return Ok(S1Holder::B(Box::new(owned)));
260 }
261 _ => {
262 use step_p21::serde::de::{Error, Unexpected};
263 return Err(A::Error::invalid_value(
264 Unexpected::Other(&key),
265 &self,
266 ));
267 }
268 }
269 }
270 }
271 impl ::step_p21::tables::WithVisitor for S1Holder {
272 type Visitor = S1HolderVisitor;
273
274 fn visitor_new() -> Self::Visitor {
275 S1HolderVisitor {}
276 }
277 }
278 impl ::step_p21::tables::EntityTable<S1Holder> for Table {
279 fn get_owned(&self, entity_id: u64) -> ::step_p21::error::Result<S1> {
280 if let Ok(owned) = ::step_p21::tables::EntityTable::<AHolder>::get_owned(
281 self, entity_id,
282 ) {
283 return Ok(S1::A(Box::new(owned.into())));
284 }
285 if let Ok(owned) = ::step_p21::tables::EntityTable::<BHolder>::get_owned(
286 self, entity_id,
287 ) {
288 return Ok(S1::B(Box::new(owned.into())));
289 }
290 Err(::step_p21::error::Error::UnknownEntity(entity_id))
291 }
292
293 fn owned_iter<'table>(
294 &'table self,
295 ) -> Box<dyn Iterator<Item = ::step_p21::error::Result<S1>> + 'table> {
296 Box::new(::step_p21::itertools::chain![
297 ::step_p21::tables::EntityTable::<AHolder>::owned_iter(self)
298 .map(|owned| owned.map(|owned| S1::A(Box::new(owned.into())))),
299 ::step_p21::tables::EntityTable::<BHolder>::owned_iter(self)
300 .map(|owned| owned.map(|owned| S1::B(Box::new(owned.into()))))
301 ])
302 }
303 }
304 "#);
305 }
306
307 #[test]
308 fn derive_holder_enum_any_subsuper() {
309 let input: syn::DeriveInput = syn::parse_str(
310 r#"
311 # [holder (table = Tables)]
312 #[holder(generate_deserialize)]
313 pub enum BaseAny {
314 #[holder(use_place_holder)]
315 # [holder (field = base)]
316 Base(Box<Base>),
317 #[holder(use_place_holder)]
318 # [holder (field = sub)]
319 Sub(Box<SubAny>),
320 }
321 "#,
322 )
323 .unwrap();
324
325 let tt = derive_holder(&input);
326 let out = step_p11::codegen::rust::rustfmt(tt.to_string());
327
328 insta::assert_snapshot!(out, @r#"
329 #[doc = r" Auto-generated by `#[derive(Holder)]`"]
330 #[derive(Clone, Debug, PartialEq)]
331 pub enum BaseAnyHolder {
332 Base(Box<BaseHolder>),
333 Sub(Box<SubAnyHolder>),
334 }
335 impl ::step_p21::tables::IntoOwned for BaseAnyHolder {
336 type Owned = BaseAny;
337 type Table = Tables;
338
339 fn into_owned(
340 self,
341 table: &Self::Table,
342 ) -> ::step_p21::error::Result<Self::Owned> {
343 Ok(match self {
344 BaseAnyHolder::Base(sub) => {
345 BaseAny::Base(Box::new(sub.into_owned(table)?))
346 }
347 BaseAnyHolder::Sub(sub) => {
348 BaseAny::Sub(Box::new(sub.into_owned(table)?))
349 }
350 })
351 }
352 }
353 impl ::step_p21::tables::Holder for BaseAnyHolder {
354 fn name() -> &'static str {
355 "BASE_ANY"
356 }
357
358 fn attr_len() -> usize {
359 0
360 }
361 }
362 impl<'de> ::step_p21::serde::de::Deserialize<'de> for BaseAnyHolder {
363 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
364 where
365 D: ::step_p21::serde::de::Deserializer<'de>,
366 {
367 deserializer.deserialize_tuple_struct(
368 "BASE_ANY",
369 0,
370 BaseAnyHolderVisitor {},
371 )
372 }
373 }
374 #[doc(hidden)]
375 pub struct BaseAnyHolderVisitor;
376 impl<'de> ::step_p21::serde::de::Visitor<'de> for BaseAnyHolderVisitor {
377 type Value = BaseAnyHolder;
378
379 fn expecting(
380 &self,
381 formatter: &mut ::std::fmt::Formatter,
382 ) -> ::std::fmt::Result {
383 write!(formatter, "BASE_ANY")
384 }
385
386 fn visit_map<A>(
387 self,
388 mut map: A,
389 ) -> ::std::result::Result<Self::Value, A::Error>
390 where
391 A: ::step_p21::serde::de::MapAccess<'de>,
392 {
393 let key: String = map
394 .next_key()?
395 .expect("Empty map cannot be accepted as step_p21 Holder");
396 match key.as_str() {
397 "BASE" => {
398 let owned = map.next_value()?;
399 return Ok(BaseAnyHolder::Base(Box::new(owned)));
400 }
401 "SUB" => {
402 let owned = map.next_value()?;
403 return Ok(BaseAnyHolder::Sub(Box::new(owned)));
404 }
405 _ => {
406 use step_p21::serde::de::{Error, Unexpected};
407 return Err(A::Error::invalid_value(
408 Unexpected::Other(&key),
409 &self,
410 ));
411 }
412 }
413 }
414 }
415 impl ::step_p21::tables::WithVisitor for BaseAnyHolder {
416 type Visitor = BaseAnyHolderVisitor;
417
418 fn visitor_new() -> Self::Visitor {
419 BaseAnyHolderVisitor {}
420 }
421 }
422 impl ::step_p21::tables::EntityTable<BaseAnyHolder> for Tables {
423 fn get_owned(&self, entity_id: u64) -> ::step_p21::error::Result<BaseAny> {
424 if let Ok(owned) =
425 ::step_p21::tables::EntityTable::<BaseHolder>::get_owned(
426 self, entity_id,
427 )
428 {
429 return Ok(BaseAny::Base(Box::new(owned.into())));
430 }
431 if let Ok(owned) =
432 ::step_p21::tables::EntityTable::<SubAnyHolder>::get_owned(
433 self, entity_id,
434 )
435 {
436 return Ok(BaseAny::Sub(Box::new(owned.into())));
437 }
438 Err(::step_p21::error::Error::UnknownEntity(entity_id))
439 }
440
441 fn owned_iter<'table>(
442 &'table self,
443 ) -> Box<dyn Iterator<Item = ::step_p21::error::Result<BaseAny>> + 'table>
444 {
445 Box::new(::step_p21::itertools::chain![
446 ::step_p21::tables::EntityTable::<BaseHolder>::owned_iter(self)
447 .map(|owned| owned
448 .map(|owned| BaseAny::Base(Box::new(owned.into())))),
449 ::step_p21::tables::EntityTable::<SubAnyHolder>::owned_iter(self)
450 .map(|owned| owned
451 .map(|owned| BaseAny::Sub(Box::new(owned.into()))))
452 ])
453 }
454 }
455 "#);
456 }
457
458 #[test]
459 fn skip_unrelated_attributes() {
460 let input: syn::DeriveInput = syn::parse_str(
461 r#"
462 #[derive(
463 Debug, Clone, PartialEq, AsRef, AsMut, Deref, DerefMut, :: derive_new :: new, Holder,
464 )]
465 # [holder (table = Tables)]
466 # [holder (field = sub1)]
467 #[holder(generate_deserialize)]
468 pub struct Sub1 {
469 #[as_ref]
470 #[as_mut]
471 #[deref]
472 #[deref_mut]
473 #[holder(use_place_holder)]
474 pub base: Base,
475 pub y1: f64,
476 }
477 "#,
478 )
479 .unwrap();
480
481 let tt = derive_holder(&input);
482 let out = step_p11::codegen::rust::rustfmt(tt.to_string());
483
484 insta::assert_snapshot!(out, @r#"
485 #[doc = r" Auto-generated by `#[derive(Holder)]`"]
486 #[derive(Debug, Clone, PartialEq)]
487 pub struct Sub1Holder {
488 pub base: ::step_p21::tables::PlaceHolder<BaseHolder>,
489 pub y1: f64,
490 }
491 #[automatically_derived]
492 impl ::step_p21::tables::IntoOwned for Sub1Holder {
493 type Owned = Sub1;
494 type Table = Tables;
495
496 fn into_owned(
497 self,
498 table: &Self::Table,
499 ) -> ::step_p21::error::Result<Self::Owned> {
500 let Sub1Holder { base, y1 } = self;
501 Ok(Sub1 {
502 base: base.into_owned(table)?,
503 y1,
504 })
505 }
506 }
507 #[automatically_derived]
508 impl ::step_p21::tables::Holder for Sub1Holder {
509 fn name() -> &'static str {
510 "SUB_1"
511 }
512
513 fn attr_len() -> usize {
514 2usize
515 }
516 }
517 #[automatically_derived]
518 impl ::step_p21::tables::EntityTable<Sub1Holder> for Tables {
519 fn get_owned(&self, entity_id: u64) -> ::step_p21::error::Result<Sub1> {
520 ::step_p21::tables::get_owned(self, &self.sub1, entity_id)
521 }
522
523 fn owned_iter<'table>(
524 &'table self,
525 ) -> Box<dyn Iterator<Item = ::step_p21::error::Result<Sub1>> + 'table>
526 {
527 ::step_p21::tables::owned_iter(self, &self.sub1)
528 }
529 }
530 #[doc(hidden)]
531 pub struct Sub1HolderVisitor;
532 #[automatically_derived]
533 impl<'de> ::step_p21::serde::de::Visitor<'de> for Sub1HolderVisitor {
534 type Value = Sub1Holder;
535
536 fn expecting(
537 &self,
538 formatter: &mut ::std::fmt::Formatter,
539 ) -> ::std::fmt::Result {
540 write!(formatter, "SUB_1")
541 }
542
543 fn visit_seq<A>(
544 self,
545 mut seq: A,
546 ) -> ::std::result::Result<Self::Value, A::Error>
547 where
548 A: ::step_p21::serde::de::SeqAccess<'de>,
549 {
550 if let Some(size) = seq.size_hint() {
551 if size != 2usize {
552 use step_p21::serde::de::Error;
553 return Err(A::Error::invalid_length(size, &self));
554 }
555 }
556 let base = seq.next_element()?.unwrap();
557 let y1 = seq.next_element()?.unwrap();
558 Ok(Sub1Holder { base, y1 })
559 }
560
561 fn visit_map<A>(
562 self,
563 mut map: A,
564 ) -> ::std::result::Result<Self::Value, A::Error>
565 where
566 A: ::step_p21::serde::de::MapAccess<'de>,
567 {
568 let key: String = map
569 .next_key()?
570 .expect("Empty map cannot be accepted as step_p21 Holder");
571 if key != "SUB_1" {
572 use step_p21::serde::de::{Error, Unexpected};
573 return Err(A::Error::invalid_value(
574 Unexpected::Other(&key),
575 &self,
576 ));
577 }
578 let value = map.next_value()?;
579 Ok(value)
580 }
581 }
582 #[automatically_derived]
583 impl<'de> ::step_p21::serde::de::Deserialize<'de> for Sub1Holder {
584 fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
585 where
586 D: ::step_p21::serde::de::Deserializer<'de>,
587 {
588 deserializer.deserialize_tuple_struct(
589 "SUB_1",
590 2usize,
591 Sub1HolderVisitor {},
592 )
593 }
594 }
595 #[automatically_derived]
596 impl ::step_p21::tables::WithVisitor for Sub1Holder {
597 type Visitor = Sub1HolderVisitor;
598
599 fn visitor_new() -> Self::Visitor {
600 Sub1HolderVisitor {}
601 }
602 }
603 "#);
604 }
605}