1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//! [![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`:
//!
//! ```
//! 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`:
//!
//! ```
//! 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()
}