# syn-path  [](https://crates.io/crates/syn-path) [](https://docs.rs/syn-path) [](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