// Some fields may not always need to be specified. Typically these would be
// represented as Option<T> in the struct being built.
//
// Have your macro identify fields in the macro input whose type is Option and
// make the corresponding builder method optional for the caller. In the test
// case below, current_dir is optional and not passed to one of the builders in
// main.
//
// Be aware that the Rust compiler performs name resolution only after macro
// expansion has finished completely. That means during the evaluation of a
// procedural macro, "types" do not exist yet, only tokens. In general many
// different token representations may end up referring to the same type: for
// example `Option<T>` and `std::option::Option<T>` and `<Vec<Option<T>> as
// IntoIterator>::Item` are all different names for the same type. Conversely,
// a single token representation may end up referring to many different types in
// different places; for example the meaning of `Error` will depend on whether
// the surrounding scope has imported std::error::Error or std::io::Error. As a
// consequence, it isn't possible in general for a macro to compare two token
// representations and tell whether they refer to the same type.
//
// In the context of the current test case, all of this means that there isn't
// some compiler representation of Option that our macro can compare fields
// against to find out whether they refer to the eventual Option type after name
// resolution. Instead all we get to look at are the tokens of how the user has
// described the type in their code. By necessity, the macro will look for
// fields whose type is written literally as Option<...> and will not realize
// when the same type has been written in some different way.
//
// The syntax tree for types parsed from tokens is somewhat complicated because
// there is such a large variety of type syntax in Rust, so here is the nested
// data structure representation that your macro will want to identify:
//
// Type::Path(
// TypePath {
// qself: None,
// path: Path {
// segments: [
// PathSegment {
// ident: "Option",
// arguments: PathArguments::AngleBracketed(
// AngleBracketedGenericArguments {
// args: [
// GenericArgument::Type(
// ...
// ),
// ],
// },
// ),
// },
// ],
// },
// },
// )
use Builder;