structural/
lib.rs

1/*!
2
3This library provides field accessor traits,and emulation of structural types.
4
5# Features
6
7These are some of the features this library provides:
8
9- [`Structural`] derive macro to implement accessor traits for every public field:
10[`GetField`]/[`GetFieldMut`]/[`IntoField`] for structs,
11and [`GetVariantField`]/[`GetVariantFieldMut`]/[`IntoVariantField`] for enums.
12
13- The [`StructuralExt`] extension trait,which defines the main methods to access fields,
14so long as the type implements the accessor traits for those fields.
15
16- The [`StrucWrapper`] wrapper type,defined as an alternative to [`StructuralExt`].
17
18- The [`structural_alias`] macro, to declare trait aliases for accessor traits,
19using field-in-trait syntax.
20
21- The [`impl_struct`] macro to declare structural parameter/return types,
22as well as [`make_struct`] to construct anonymous structs
23
24- The [`FromStructural`] and [`TryFromStructural`] conversion traits,
25similar (but not identical) to the standard library `From` and `TryFrom` traits
26for structural types.
27
28
29# Clarifications
30
31The way that this library emulates structural types is by using traits as bounds
32or trait objects.
33
34All the `structural` traits are dyn-compatible(also known as object-safe),
35and no change will be made to make them not dyn-compatible.
36
37By default all structural types are open,
38structs and enums can have more variants and or fields than are required.<br>
39The only exception to this is exhaustive enums,
40in which the variant count and names must match exactly,
41this is useful for exhaustive matching of variants (in the [`switch`] macro).
42
43Every trait with the `_SI`/`_ESI`/`_VSI` suffixes in the examples are traits
44generated by the `Structural` derive macro.
45These traits alias the accessor traits implemented by the type they're named after.
46
47### Required macros
48
49The only macros that are required to use this crate are the ones for [`TStr`],
50every other macro expands to code that can be written manually
51(except for the [`__TS`] type,
52that is an implementation detail that only macros from
53this crate should use by name).
54
55<span id="root-mod-examples"></span>
56# Examples
57
58
59### Structural Derive for structs
60
61This demonstrates how you can use any type with a superset of the fields of
62another one in a function.
63
64[`Structural`] derive macro docs for more details on derivation.
65
66```rust
67use structural::{fp, Structural, StructuralExt};
68
69fn reads_point3<S>(point: &S)
70where
71    // The `Point3D_SI` trait was generated by the `Structural` derive for `Point3D`,
72    // aliasing the accessor traits implemented by `Point3D`.
73    S: Point3D_SI<u32>,
74{
75    let (a, b, c) = point.fields(fp!(x, y, z));
76
77    assert_eq!(a, &0);
78    assert_eq!(b, &11);
79    assert_eq!(c, &33);
80}
81
82fn main() {
83    reads_point3(&Point3D { x: 0, y: 11, z: 33 });
84
85    reads_point3(&Point4D {
86        x: 0,
87        y: 11,
88        z: 33,
89        a: 0xDEAD,
90    });
91
92    reads_point3(&Point5D {
93        x: 0,
94        y: 11,
95        z: 33,
96        a: 0xDEAD,
97        b: 0xBEEF,
98    });
99}
100
101#[derive(Structural)]
102// Using the `#[struc(public)]` attribute tells the derive macro to
103// generate the accessor trait impls for non-`pub` fields.
104#[struc(public)]
105struct Point3D<T> {
106    x: T,
107    y: T,
108    z: T,
109}
110
111#[derive(Structural)]
112// By default only public fields get accessor trait impls,
113// using `#[struc(public)]` you can have impls to access private fields.
114#[struc(public)]
115struct Point4D<T> {
116    x: T,
117    y: T,
118    z: T,
119    a: T,
120}
121
122#[derive(Structural)]
123struct Point5D<T> {
124    pub x: T,
125    pub y: T,
126    pub z: T,
127    pub a: T,
128    pub b: T,
129}
130
131```
132
133### Structural Derive for enums
134
135This demonstrates how you can use structural enums.
136
137For details on [enums look here](./docs/enums/index.html).
138
139```rust
140use structural::{fp, switch, Structural, StructuralExt};
141
142fn main() {
143    {
144        // Command
145
146        run_command(Command::SendEmail(SendEmail {
147            to: "ferris@lib.rs".to_string(),
148            content: "Hello".to_string(),
149        }));
150        run_command(Command::RemoveAddress("gopher".to_string()));
151    }
152    {
153        // ExtraCommand
154        //
155        // ExtraCommand can't be passed to `run_command` because that function requires
156        // an enum with exactly the `SendEmail` and `RemoveAddress` variants.
157
158        // The `SendEmail` variant can have more fields than the one in the `Command` enum,
159        // they're just ignored.
160        run_command_nonexhaustive(ExtraCommand::SendEmail {
161            to: "squatter@crates.io".to_string(),
162            content: "Can you stop squatting crate names?".to_string(),
163            topic: "squatting".to_string(),
164        })
165        .unwrap();
166
167        let ra_cmd = ExtraCommand::RemoveAddress("smart_person".to_string());
168        run_command_nonexhaustive(ra_cmd).unwrap();
169
170        let ca_cmd = ExtraCommand::CreateAddress("honest_person".to_string());
171        let res = run_command_nonexhaustive(ca_cmd.clone());
172        assert_eq!(res, Err(UnsupportedCommand(ca_cmd)));
173    }
174}
175
176// Runs the passed in command.
177//
178// The `Command_ESI` trait allows only enums with the same variants as
179// `Command` to be passed in(they can have a superset of the fields in `Command`).
180fn run_command<S>(cmd: S)
181where
182    S: Command_ESI,
183{
184    run_command_nonexhaustive(cmd)
185        .ok()
186        .expect("`run_command_nonexhaustive` must match all `Command` variants")
187}
188
189// Runs the passed in command.
190//
191// The `Command_SI` trait allows enums with a superset of the variants in `Command`
192// to be passed in,
193// requiring the a `_=>` branch when it's matched on with the `switch` macro.
194fn run_command_nonexhaustive<S>(cmd: S) -> Result<(), UnsupportedCommand<S>>
195where
196    S: Command_SI,
197{
198    switch! {cmd;
199        // This matches the SendEmail variant and destructures the
200        // `to` and `content` fields  by value.
201        SendEmail{to,content}=>{
202            println!("Sending message to the '{}' email address.",to);
203            println!("Content:{:?}",content);
204            Ok(())
205        }
206        // This matches the RemoveAddress variant and destructures it into
207        // the 0th field (by reference,because of the `ref`).
208        ref RemoveAddress(address)=>{
209            println!("removing the '{}' email address",address);
210            Ok(())
211        }
212        _=>Err(UnsupportedCommand(cmd))
213    }
214}
215
216#[derive(Structural)]
217enum Command {
218    // The `newtype(bounds="...")` attribute marks the variant as being a newtype variant,
219    // delegating field accessors of the variant to `SendEmail`(its one field),
220    // as well as replacing the bounds for the variant in the
221    // trait aliases generated by the `Structural` derive (`Command_SI` and `Command_ESI`)
222    // with `SendEmail_VSI<TS!(SendEmail)>`.
223    //
224    // `SendEmail_VSI` was generated by the `Structural` derive on `SendEmail`,
225    // with accessor trait bounds for accessing the struct's fields
226    // in a variant (it takes the name of the variant as a generic parameter).
227    #[struc(newtype(bounds = "SendEmail_VSI<@variant>"))]
228    SendEmail(SendEmail),
229    RemoveAddress(String),
230}
231
232#[derive(Structural)]
233pub struct SendEmail {
234    pub to: String,
235    pub content: String,
236}
237
238#[derive(Debug, Structural, Clone, PartialEq)]
239// This attribute stops the generation of the
240// `ExtraCommands_SI` and `ExtraCommands_ESI` traits
241#[struc(no_trait)]
242pub enum ExtraCommand {
243    SendEmail {
244        to: String,
245        content: String,
246        topic: String,
247    },
248    RemoveAddress(String),
249    CreateAddress(String),
250}
251
252#[derive(Debug, PartialEq)]
253pub struct UnsupportedCommand<T>(pub T);
254```
255
256### Structural alias for struct
257
258This demonstrates how you can define a trait aliasing field accessors,
259using a fields-in-traits syntax.
260
261For more details you can look at the docs for the [`structural_alias`] macro.
262
263```rust
264
265use structural::{fp, structural_alias, FP, IntoFieldMut, Structural, StructuralExt};
266
267use std::borrow::Borrow;
268
269structural_alias! {
270    trait Person<H: House>{
271        name: String,
272        house: H,
273    }
274
275    trait House{
276        dim: Dimension3D,
277    }
278}
279
280fn print_name<T, H>(this: &T)
281where
282    T: ?Sized + Person<H>,
283
284    // This is the one trait that `House` requires in its blanket implementation.
285    // `H: House,` is equivalent to this
286    H: IntoFieldMut<FP!(dim), Ty = Dimension3D>,
287{
288    let (name, house_dim) = this.fields(fp!(name, house.dim));
289    println!("Hello, {}!", name);
290
291    let (w, h, d) = house_dim.fields(fp!(width, height, depth));
292
293    if w * h * d >= 1_000_000 {
294        println!("Your house is enormous.");
295    } else {
296        println!("Your house is normal sized.");
297    }
298}
299
300// most structural aliases are object safe
301fn print_name_dyn<H>(this: &dyn Person<H>)
302where
303    // This is the one trait that `House` requires in its blanket implementation.
304    // `H: House,` is equivalent to this
305    H: IntoFieldMut<FP!(dim), Ty = Dimension3D>,
306{
307    print_name(this)
308}
309
310#[derive(Structural)]
311#[struc(public)]
312struct Dimension3D {
313    width: u32,
314    height: u32,
315    depth: u32,
316}
317
318//////////////////////////////////////////////////////////////////////////
319////          The stuff here could be defined in a separate crate
320
321fn main() {
322    let worker = Worker {
323        name: "John Doe".into(),
324        salary: Cents(1_000_000_000_000_000),
325        house: Mansion {
326            dim: Dimension3D {
327                width: 300,
328                height: 300,
329                depth: 300,
330            },
331            money_vault_location: "In the basement".into(),
332        },
333    };
334
335    let student = Student {
336        name: "Jake English".into(),
337        birth_year: 1995,
338        house: SmallHouse {
339            dim: Dimension3D {
340                width: 30,
341                height: 30,
342                depth: 30,
343            },
344            residents: 10,
345        },
346    };
347
348    print_name(&worker);
349    print_name(&student);
350
351    print_name_dyn(&worker);
352    print_name_dyn(&student);
353}
354
355#[derive(Structural)]
356// Using the `#[struc(public)]` attribute tells the derive macro to
357// generate the accessor trait impls for non-`pub` fields.
358#[struc(public)]
359struct Worker {
360    name: String,
361    salary: Cents,
362    house: Mansion,
363}
364
365#[derive(Structural)]
366#[struc(public)]
367struct Student {
368    name: String,
369    birth_year: u32,
370    house: SmallHouse,
371}
372
373#[derive(Debug, Copy, Clone, PartialEq, Eq)]
374struct Cents(u64);
375
376#[derive(Structural)]
377#[struc(public)]
378struct Mansion {
379    dim: Dimension3D,
380    money_vault_location: String,
381}
382
383#[derive(Structural)]
384#[struc(public)]
385struct SmallHouse {
386    dim: Dimension3D,
387    residents: u32,
388}
389```
390
391### Structural alias for enums
392
393This demonstrates how you can use structural aliases for enums.
394
395This shows both exhaustive and nonexhaustive enum structural aliases.
396
397For more details you can look at the docs for the [`structural_alias`] macro.
398
399```rust
400use std::fmt::Debug;
401use structural::{fp, structural_alias, switch, Structural, StructuralExt};
402
403fn main() {
404    pet_animal_ex(&SomeMammals::Dog {
405        years: 1,
406        volume_cm3: 1,
407    });
408    pet_animal_ex(&SomeMammals::Horse);
409
410    // `MoreAnimals` cannot be passed to `pet_animal_ex`
411    // since that function requires an enum with only `Dog` and `Horse` variants.
412    assert_eq!(
413        pet_animal(&MoreAnimals::Dog {
414            years: 10,
415            volume_cm3: 100
416        }),
417        Ok(())
418    );
419    assert_eq!(pet_animal(&MoreAnimals::Horse), Ok(()));
420    assert_eq!(pet_animal(&MoreAnimals::Cat { lives: 9 }), Err(CouldNotPet));
421    assert_eq!(pet_animal(&MoreAnimals::Seal), Err(CouldNotPet));
422}
423
424// For an equivalent function that's ergonomic to write, look below for `pet_animal_switch`
425fn pet_animal(animal: &dyn Animal) -> Result<(), CouldNotPet> {
426    // `::Dog` accesses the `Dog` variant
427    // (without the `::` it'd be interpreted as a field access),
428    // The `=>` allows getting multiple fields from inside a nested field
429    // (this includes enum variants).
430    // `years,volume_cm3` are the field accessed from inside `::Dog`
431    let dog_fields = fp!(::Dog=>years,volume_cm3);
432
433    // The `is_horse` method comes from the `Animal` trait.
434    if animal.is_horse() {
435        println!("You are petting the horse");
436    } else if let Some((years, volume_cm3)) = animal.fields(dog_fields) {
437        println!(
438            "You are petting the {} year old,{} cm³ dog",
439            years, volume_cm3
440        );
441    } else {
442        return Err(CouldNotPet);
443    }
444    Ok(())
445}
446
447// This can't take a `&dyn Animal_Ex` because traits objects don't
448// automatically support upcasting into other trait objects
449// (except for auto traits like Send and Sync ).
450fn pet_animal_ex(animal: &impl Animal_Ex) {
451    pet_animal(animal).expect("`pet_animal` must match on all variants from the `Animal` trait");
452}
453
454// The same as `pet_animal` ,except that this uses the `switch` macro
455fn pet_animal_switch(animal: &dyn Animal) -> Result<(), CouldNotPet> {
456    switch! {animal;
457        Horse=>{
458            println!("You are petting the horse");
459        }
460        // This matches the Dog variant,
461        // and destructures it into its `years` and `volume_cm3` fields
462        // as references(because of the `ref`)
463        ref Dog{years,volume_cm3}=>{
464            println!("You are petting the {} year old,{} cm³ dog",years,volume_cm3);
465        }
466        _=>return Err(CouldNotPet)
467    }
468    Ok(())
469}
470
471#[derive(Debug, PartialEq)]
472struct CouldNotPet;
473
474structural_alias! {
475    // The `#[struc(and_exhaustive_enum(suffix = "_Ex"))]` attribute
476    // generates the `Animal_Ex` trait with this trait as a supertrait,
477    // and with the additional requirement that the enum
478    // only has the `Horse` and `Dog` variants
479    // (Those variants can still have more fields than required).
480    //
481    // structural aliases can have supertraits,here it's `Debug`
482    #[struc(and_exhaustive_enum(suffix = "_Ex"))]
483    trait Animal: Debug{
484        Horse,
485        Dog{years: u16, volume_cm3: u64},
486
487        // Structural aliases can define extension methods,
488        fn is_horse(&self) -> bool {
489            self.is_variant(fp!(Horse))
490        }
491    }
492}
493
494#[derive(Debug, Structural)]
495#[struc(no_trait)]
496enum SomeMammals {
497    Horse,
498    Dog { years: u16, volume_cm3: u64 },
499}
500
501#[derive(Debug, Structural)]
502#[struc(no_trait)]
503enum MoreAnimals {
504    Cat { lives: u8 },
505    Dog { years: u16, volume_cm3: u64 },
506    Horse,
507    Seal,
508}
509
510```
511
512### Anonymous structs (`make_struct` macro)
513
514This demonstrates how you can construct an anonymous struct.
515
516For more details you can look at the docs for the
517[`make_struct`](./macro.make_struct.html) macro.
518
519Docs for the [`impl_struct` macro](./macro.impl_struct.html).
520
521```rust
522use structural::{fp, impl_struct, make_struct, structural_alias, StructuralExt};
523
524structural_alias! {
525    trait Person<T>{
526        // We only have shared access (`&String`) to the field.
527        ref name: String,
528
529        // We have shared,mutable,and by value access to the field.
530        // Not specifying any of `mut`/`ref`/`move` is equivalent to `mut move value: T,`
531        value: T,
532    }
533}
534
535fn make_person(name: String) -> impl_struct! { name: String, value: () } {
536    make_struct! {
537        name,
538        value: (),
539    }
540}
541
542fn print_name(mut this: impl_struct! { ref name: String, value: Vec<String> }) {
543    println!("Hello, {}!", this.field_(fp!(name)));
544
545    let list = vec!["what".into()];
546    *this.field_mut(fp!(value)) = list.clone();
547    assert_eq!(this.field_(fp!(value)), &list);
548    assert_eq!(this.into_field(fp!(value)), list);
549}
550
551// most structural aliases are object safe
552//
553// This has to use the Person trait,
554// since `impl_struct!{....}` expands to `impl Trait0 + Trait1 + etc`.
555fn print_name_dyn(this: &mut dyn Person<Vec<String>>) {
556    println!("Hello, {}!", this.field_(fp!(name)));
557
558    let list = vec!["what".into()];
559    *this.field_mut(fp!(value)) = list.clone();
560    assert_eq!(this.field_(fp!(value)), &list);
561}
562
563//////////////////////////////////////////////////////////////////////////
564////          The stuff here could be defined in a separate crate
565
566fn main() {
567    let worker = make_struct! {
568        // This derives clone for the anonymous struct
569        #![derive(Clone)]
570        name: "John Doe".into(),
571        salary: Cents(1_000_000_000_000_000),
572        value: vec![],
573    };
574
575    let student = make_struct! {
576        // This derives clone for the anonymous struct
577        #![derive(Clone)]
578        name: "Jake English".into(),
579        birth_year: 1995,
580        value: vec![],
581    };
582
583    print_name(worker.clone());
584    print_name(student.clone());
585
586    print_name_dyn(&mut worker.clone());
587    print_name_dyn(&mut student.clone());
588
589    let person = make_person("Louis".into());
590
591    assert_eq!(person.field_(fp!(name)), "Louis");
592    assert_eq!(person.field_(fp!(value)), &());
593
594    // Destructuring the anonymous struct by value.
595    // The type annotation here is just to demonstrate that it returns a `String` by value.
596    let (name, value): (String, ()) = person.into_fields(fp!(name, value));
597    assert_eq!(name, "Louis");
598}
599
600#[derive(Debug, Copy, Clone, PartialEq, Eq)]
601struct Cents(u64);
602```
603
604[`Structural`]: ./docs/structural_macro/index.html
605[`GetField`]: ./field/trait.GetField.html
606[`GetFieldMut`]: ./field/trait.GetFieldMut.html
607[`IntoField`]: ./field/trait.IntoField.html
608[`GetVariantField`]: ./field/trait.GetVariantField.html
609[`GetVariantFieldMut`]: ./field/trait.GetVariantFieldMut.html
610[`IntoVariantField`]: ./field/trait.IntoVariantField.html
611
612[`StrucWrapper`]: ./struct.StrucWrapper.html
613
614[`StructuralExt`]: ./trait.StructuralExt.html
615[`impl_struct`]: ./macro.impl_struct.html
616[`make_struct`]: ./macro.make_struct.html
617[`structural_alias`]: ./macro.structural_alias.html
618[`switch`]: ./macro.switch.html
619
620[`__TS`]: ./struct.TStr.html#semver-concerns
621
622[`FromStructural`]: ./convert/trait.FromStructural.html
623[`TryFromStructural`]: ./convert/trait.TryFromStructural.html
624
625*/
626#![cfg_attr(feature = "nightly_impl_fields", feature(associated_type_bounds))]
627#![cfg_attr(feature = "nightly_specialization", feature(specialization))]
628#![cfg_attr(
629    all(feature = "nightly_use_const_str", not(feature = "disable_const_str")),
630    feature(const_if_match)
631)]
632#![cfg_attr(
633    all(feature = "nightly_use_const_str", not(feature = "disable_const_str")),
634    feature(const_generics)
635)]
636#![cfg_attr(
637    all(feature = "nightly_use_const_str", not(feature = "disable_const_str")),
638    allow(incomplete_features)
639)]
640#![deny(rust_2018_idioms)]
641#![allow(non_camel_case_types)]
642#![no_std]
643// The associated constants from this crate use trait bounds,
644// so they can't be translated to `const fn`.
645// Also,the constants don't use cell types,they're just generic.
646#![allow(clippy::declare_interior_mutable_const)]
647// This triggers for types that represent values, like `NestedFieldPath<(TS!(0), TS!(1))>`,
648// so it's mostly noise in this crate.
649#![allow(clippy::type_complexity)]
650// This lint is silly
651#![allow(clippy::blacklisted_name)]
652// This lint is silly
653#![allow(clippy::needless_doctest_main)]
654#![deny(clippy::missing_safety_doc)]
655#![deny(clippy::shadow_unrelated)]
656#![deny(clippy::wildcard_imports)]
657#![deny(missing_docs)]
658
659#[cfg(feature = "std")]
660#[doc(hidden)]
661pub extern crate std;
662
663#[doc(hidden)]
664pub extern crate core as std_;
665
666#[doc(hidden)]
667#[cfg(all(feature = "alloc"))]
668#[cfg_attr(feature = "hide_reexports", doc(hidden))]
669pub extern crate alloc;
670
671extern crate self as structural;
672
673pub use structural_derive::Structural;
674
675#[doc(hidden)]
676pub use structural_derive::{
677    _FP_impl_, _FP_literal_, _TStr_ident_impl_, _TStr_impl_, _TStr_lit_impl_,
678    _field_path_aliases_impl, _impl_struct_impl, _switch_tstring_aliases, _tstring_aliases_impl,
679    structural_alias_impl,
680};
681
682#[macro_use]
683mod macros;
684
685#[doc(hidden)]
686#[cfg(all(feature = "use_const_str", not(feature = "disable_const_str")))]
687pub mod const_generic_utils;
688pub mod convert;
689pub mod docs;
690pub mod enums;
691pub mod field;
692mod field_cloner;
693#[doc(hidden)]
694pub mod msg;
695pub mod path;
696pub mod structural_aliases;
697mod structural_ext;
698mod structural_trait;
699pub mod type_level;
700pub mod utils;
701mod wrapper;
702
703#[doc(hidden)]
704#[cfg(feature = "testing")]
705pub mod test_utils;
706
707#[doc(hidden)]
708#[cfg(feature = "testing")]
709pub mod tests;
710
711include! {"p.rs"}
712
713pub use crate::{
714    field::{
715        FieldType, GetField, GetFieldMut, GetFieldType, GetFieldType2, GetFieldType3,
716        GetFieldType4, GetVariantField, GetVariantFieldMut, GetVariantFieldType, IntoField,
717        IntoFieldMut, IntoVariantField, IntoVariantFieldMut,
718    },
719    field_cloner::FieldCloner,
720    structural_ext::StructuralExt,
721    structural_trait::Structural,
722    wrapper::StrucWrapper,
723};
724
725/// Reexports from other crates.
726///
727/// This reexports from `core_extensions`.
728pub mod reexports {
729    #[doc(no_inline)]
730    pub use core_extensions::{
731        collection_traits::{Cloned, ClonedOut, IntoArray},
732        const_default, ConstDefault,
733    };
734
735    #[cfg(feature = "alloc")]
736    #[cfg_attr(feature = "hide_reexports", doc(hidden))]
737    #[doc(no_inline)]
738    pub use crate::alloc::boxed::Box;
739}
740
741// pmr(proc macro reexports):
742// Reexports for the proc macros in structural_derive.
743//
744// Importing stuff from this module anywhere other than `structural_derive` is
745// explicitly disallowed,and is likely to break.
746#[doc(hidden)]
747pub mod pmr {
748    pub use crate::convert::*;
749    pub use crate::enums::variant_count::*;
750    pub use crate::enums::*;
751    pub use crate::field::ownership::*;
752    pub use crate::field::*;
753    pub use crate::path::*;
754    pub use crate::type_level::collection_traits::*;
755    pub use crate::type_level::*;
756    pub use crate::utils::{RunOnDrop, _Structural_BorrowSelf, as_phantomdata};
757    pub use core_extensions::{ConstDefault, MarkerType};
758
759    pub use crate::std_::{
760        convert::Infallible,
761        format_args,
762        marker::PhantomData,
763        mem::{drop, forget},
764        option::Option::{self, None, Some},
765        ptr::{drop_in_place, NonNull},
766    };
767
768    #[cfg(feature = "alloc")]
769    pub use crate::alloc::boxed::Box;
770}
771
772/// Structural-deriving types used in examples,
773///
774/// These are in the docs purely so that documentation examples only use
775/// types that are documented.
776///
777/// You can only use items from this module when the "for_examples" feature is enabled.
778#[cfg(any(feature = "for_examples", all(rust_1_41, doc)))]
779pub mod for_examples;
780
781/// Structural-deriving types used in examples,
782///
783/// You can only use items from this module when the "for_examples" feature is enabled.
784#[cfg(all(not(feature = "for_examples"), not(all(rust_1_41, doc))))]
785pub mod for_examples {}
786
787#[cfg(all(test, not(feature = "testing")))]
788compile_error! { "tests must be run with the \"testing\" feature" }
789
790//////////////////////////////
791
792use std_::marker::PhantomData;
793use std_::mem::ManuallyDrop;
794
795include! {"path/declare_field_path_types.rs"}