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() }