syn-path 3.0.0

A simple macro to declare a syn::Path at compile time
Documentation
# syn-path ![License: 0BSD]https://img.shields.io/badge/license-0BSD-blue [![syn-path on crates.io]https://img.shields.io/crates/v/syn-path]https://crates.io/crates/syn-path [![syn-path on docs.rs]https://docs.rs/syn-path/badge.svg]https://docs.rs/syn-path [![Source Code Repository]https://img.shields.io/badge/Code-On%20Codeberg-blue?logo=Codeberg]https://codeberg.org/msrd0/syn-path

This crate contains macros to construct [`syn`][__link0]-types that contain paths inside a
procedural macro.

* The [`path!`][__link1] macro constructs a [`syn::Path`][__link2].
  
  **Example:**
  
  ```rust
  use syn_path::path;
  let path = path!(::std::option::Option<::std::string::String>);
  ```

* The [`type_path!`][__link3] macro constructs a [`syn::TypePath`][__link4].
  
  **Example:**
  
  ```rust
  use syn_path::type_path;
  let type_path = type_path!(<i64 as ::std::str::FromStr>::Err);
  ```

* The [`ty!`][__link5] macro constructs a [`syn::Type`][__link6].
  
  **Example:**
  
  ```rust
  use syn_path::ty;
  let ty = ty!(<i64 as ::std::str::FromStr>::Err);
  ```

While we can just type whatever we need into [`quote!`][__link7] most of the time when writing
procedural macros, sometimes we need a certain syn type. The macros from this crate
help you out in these situations.

### Example: Making a type optional

Some derive macros might need to transform a type to an optional type. For example,
this function takes a [`Field`][__link8] and returns its type or an option of its
type based on the `nullable` parameter:

```rust
use syn_path::type_path;

fn field_ty(field: &Field, nullable: bool) -> Type {
	let mut ty = field.ty.clone();
	if nullable {
		let mut args = Punctuated::new();
		args.push(GenericArgument::Type(ty));
		let mut type_path = type_path!(::core::option::Option);
		type_path.path.segments.last_mut().unwrap().arguments = PathArguments::AngleBracketed(
			AngleBracketedGenericArguments {
				colon2_token: None,
				lt_token: Default::default(),
				args,
				gt_token: Default::default()
			}
		);
		ty = Type::Path(type_path);
	}
	ty
}

let field = // x: String
let ty = field_ty(field, true);
assert_eq!(ty, syn::parse2(quote!(::core::option::Option<String>)).unwrap());
```

This example is adopted from the
[`openapi_type_derive`][__link9]
crate. The full example can be found
[here][__link10].

### Example: Adding a where clause

This example shows how to add `T: Send` clauses for each field of a struct. We cannot
just write `where T: Send` into [`quote!`][__link11] since there might or might
not be a where clause for the struct our derive macro received as an input.

```rust
use syn_path::path;

fn where_predicate_t_send(t: Type) -> WherePredicate {
	WherePredicate::Type(PredicateType {
		attrs: Vec::new(),
		lifetimes: None,
		bounded_ty: t,
		colon_token: Default::default(),
		bounds: [TypeParamBound::Trait(TraitBound {
			paren_token: None,
			modifiers: TraitBoundModifiers::default(),
			lifetimes: None,
			maybe: None,
			path: path!(::std::marker::Send)
		})].into_iter().collect()
	})
}

let strukt =
	struct Foo<T> where T: Hash + Eq { foo: HashSet<T> }
let ident = strukt.ident;
let (impl_generics, ty_generics, where_clause) = strukt.generics.split_for_impl();
let mut where_clause = where_clause.cloned().unwrap_or(WhereClause {
	where_token: Default::default(),
	predicates: Default::default()
});
for field in strukt.fields {
	where_clause.predicates.push(where_predicate_t_send(field.ty));
}
assert_eq!(
	quote!(impl #impl_generics MyTrait for #ident #ty_generics #where_clause {}).to_string(),
	quote!(impl<T> MyTrait for Foo<T> where T: Hash + Eq, HashSet<T>: ::std::marker::Send {}).to_string()
)
```


 [__cargo_doc2readme_dependencies_info]: ggGmYW0CYXZlMC43LjNhdIQb2o_SNWoR6AAb3_T-k0ODPHwbnQW7uS_D2XsbjVFFtK-lC3BhYvVhcoQbcTmIZH-MwmUbm22TCjNdz00bnMdDck9nroEbsbiVpfbKpRxhZIKCY3N5bmUzLjAuM4Noc3luLXBhdGhlMy4wLjBoc3luX3BhdGg
 [__link0]: https://crates.io/crates/syn/3.0.3
 [__link1]: https://docs.rs/syn-path/3.0.0/syn_path/macro.path.html
 [__link10]: https://github.com/msrd0/openapi_type/blob/6ba01686a0a8b782dd2bfba711bbe5f50ddfdb08/derive/src/parser.rs#L98-L110
 [__link11]: https://docs.rs/quote/1/quote/macro.quote.html
 [__link2]: https://docs.rs/syn/3.0.3/syn/?search=Path
 [__link3]: https://docs.rs/syn-path/3.0.0/syn_path/macro.type_path.html
 [__link4]: https://docs.rs/syn/3.0.3/syn/?search=TypePath
 [__link5]: https://docs.rs/syn-path/3.0.0/syn_path/macro.ty.html
 [__link6]: https://docs.rs/syn/3.0.3/syn/?search=Type
 [__link7]: https://docs.rs/quote/1/quote/macro.quote.html
 [__link8]: https://docs.rs/syn/3.0.3/syn/?search=Field
 [__link9]: https://crates.io/crates/openapi_type_derive