//! [![github]](https://github.com/usagi/tia) [![crates-io]](https://crates.io/crates/tia) [![docs-rs]](https://docs.rs/tia)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//! <br>
//!
//! # tia; trait, impl accessors | automatic
//!
//! This is a syntax sugar proc-macro crate for `trait`, `impl` accessors patterns. `tia` generate to an accessor `impl`s of an indivisual `trait`s for any `struct`|`enun`|`union`s.
//!
//! ## Basic Example
//!
//! Cargo.toml:
//!
//! ```toml
//! [dependencies]
//! tia = "*"
//! ```
//!
//! main.rs:
//!
//! ```rust
//! use tia::Tia; // 1. use
//!
//! #[derive(Tia)] // 2. derive
//! #[tia(rg)] // 3. tia directives
//! struct MyStruct
//! {
//! foo: i32,
//! bar: String
//! }
//!
//! fn main()
//! {
//! let mys = MyStruct {
//! foo: 123,
//! bar: "Hello".into()
//! };
//! let foo = mys.get_foo(); // <-- 4. !! generated by tia automatically !!
//! let bar = mys.get_bar(); // <-- 5. !! generated by tia automatically !!
//! println!("foo={} bar={}", foo, bar);
//! }
//! ```
//!
//! `cargo run`:
//!
//! ```sh
//! foo=123 bar=Hello
//! ```
//!
//! ### with `trait`s;
//!
//! ```rust
//! use tia::Tia;
//!
//! trait FooGettable<T>
//! {
//! fn get_foo(&self) -> T;
//! }
//! trait Fruit
//! {
//! fn get_bar(&self) -> &String;
//! }
//! trait Sushi
//! {
//! fn tuna(&self) -> u8;
//! fn avocado(&mut self, v: u8);
//! }
//!
//! // include!(".tia/MyStruct.rs");
//! #[derive(Tia, Debug, Default)] // derive
//! struct MyStruct
//! {
//! #[tia(s, "FooGettable<i32>", g)]
//! foo: i32,
//! #[tia("Fruit", rg, "", rsi)]
//! bar: String,
//! #[tia("Sushi",g*="tuna",s*="avocado")] // <- `g` and `s`: Sushi trait
//! baz: u8
//! }
//!
//! /// Build ok = Test ok
//! fn main()
//! {
//! let mut mys = MyStruct::default();
//! mys.set_foo(123);
//! mys.set_bar("meow");
//! let foo_gettable = &mys as &dyn FooGettable<i32>;
//! let fruit = &mys as &dyn Fruit;
//! println!("{}, {}", foo_gettable.get_foo(), fruit.get_bar());
//! let sushi = &mut mys as &mut dyn Sushi;
//! sushi.avocado(32);
//! println!("{}", sushi.tuna());
//! }
//! ```
//!
//! `cargo run`:
//!
//! ```sh
//! 123, meow
//! 32
//! ```
//!
//! More details and examples are exists in the [README.md][] and [examples/] and [tests/].
//!
//! [README.md]: https://github.com/usagi/tia
//! [examples/]: https://github.com/usagi/tia/blob/master/examples
//! [tests/]: https://github.com/usagi/tia/blob/master/tests
use proc_macro as pm;
#[cfg(not(feature = "disable"))]
mod detail;
#[cfg(not(feature = "disable"))]
use detail::*;
#[cfg(not(feature = "disable"))]
#[proc_macro_derive(Tia, attributes(tia))]
pub fn derive_tia(s: pm::TokenStream) -> pm::TokenStream
{
let i = syn::parse_macro_input!(s as syn::DeriveInput);
if cfg!(feature = "include") || cfg!(feature = "include-force")
{
let target_type_symbol = i
.ident
.to_string();
let cargo_root_path = std::env::var("CARGO_MANIFEST_DIR").expect("");
let file_path = std::path::Path::new(&cargo_root_path)
.join("src")
.join(".tia")
.join(format!("{}.rs", target_type_symbol));
let file_path = std::path::Path::new(&file_path);
let include_path = file_path
.to_string_lossy()
.replace("\\", "/");
if file_path.exists()
{
eprintln!(
"[proc-macro:tia +include|+include-force Target: {} => no generate, instead include!. ]",
target_type_symbol
);
let r = format!(r#"include!("{}");"#, include_path);
let r = r.parse::<pm::TokenStream>();
return r.expect("tia +include|+include-force feature, tia::into<proc_macro::TokenStream> was failed. #TIA-PANIC-5001");
}
eprintln!(
"[proc-macro:tia +include|+include-force Target: {} => file not found (It's not an error, yet).; expected path = {} ]",
target_type_symbol, include_path
);
if cfg!(feature = "include-force")
{
panic!("tia +include-force feature, but the include file is not found. #TIA-PANIC-5002");
}
}
let tia = Tia::new(i);
tia.into()
}
#[cfg(feature = "disable")]
#[proc_macro_derive(Tia, attributes(tia))]
pub fn derive_tia(s: pm::TokenStream) -> pm::TokenStream { pm::TokenStream::default() }