tia 1.0.3

tia; trait, impl, accessors | automatic
Documentation
//! [![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() }