|
35 | 35 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
36 | 36 | //SOFTWARE. |
37 | 37 |
|
38 | | -/*! Macro for embedding (trees, strings, arrays) into macro trees directly from files. |
| 38 | +/*! Macros for ultra-flexible injection of compiler trees, literals, or binary data into Rust syntax trees from external sources. |
| 39 | +
|
39 | 40 | ```rust |
40 | 41 | use include_tt::inject; |
41 | 42 | use std::fmt::Write; |
42 | | -
|
43 | | -// Example demonstrating the usage of inject! macro for embedding content from files. |
44 | | -{ |
45 | | - // Embedding trees from a file in an arbitrary place of other macros. |
46 | | - let a = 10; |
47 | | - let b = 20; |
48 | | - let mut end_str = String::new(); |
49 | | -
|
50 | | - // Using inject! to embed content into a macro. |
51 | | - inject! { |
52 | | - let _e = write!( |
53 | | - &mut end_str, |
54 | | -
|
55 | | - "arg1: {}, arg2: {}", |
56 | | -
|
57 | | - // This file contains `a, b`. |
58 | | - #tt("./examples/full.tt") // this file contains `a, b`. |
59 | | - ); |
60 | | - } |
61 | | -
|
62 | | - // Asserting the result matches the expected output. |
63 | | - assert_eq!(end_str, "arg1: 10, arg2: 20"); |
64 | | -} |
65 | | -
|
66 | | -{ |
67 | | - // Loading a string from "full.tt" using inject! macro. |
68 | | - let str = inject!( |
69 | | - #str("./examples/full.tt") // this file contains `a, b`. |
70 | | - ); |
71 | | -
|
72 | | - // Asserting the result matches the expected output. |
73 | | - assert_eq!(str, "a, b"); |
| 43 | +let mut buf = String::new(); |
| 44 | +
|
| 45 | +inject! { |
| 46 | + write!( |
| 47 | + &mut buf, |
| 48 | + "Welcome, {}. Your score is {}!", |
| 49 | + #tt("examples/name.tt"), // `"Ferris"` |
| 50 | + #tt("examples/" "score" ".tt") // `100500` |
| 51 | + ).unwrap(); |
74 | 52 | } |
75 | 53 |
|
76 | | -{ |
77 | | - // Loading a array from "full.tt" using inject! macro. |
78 | | - let array: &'static [u8; 4] = inject!( |
79 | | - #arr("./examples/full.tt") // this file contains `a, b`. |
80 | | - ); |
81 | | -
|
82 | | - // Asserting the result matches the expected output. |
83 | | - assert_eq!(array, b"a, b"); |
84 | | -} |
| 54 | +assert_eq!(buf, "Welcome, Ferris. Your score is 100500!"); |
85 | 55 | ``` |
86 | 56 | */ |
87 | 57 |
|
@@ -432,43 +402,58 @@ fn autoinject_tt_in_group<'tk, 'gpsn>( |
432 | 402 | SearchGroup::Break |
433 | 403 | } |
434 | 404 |
|
435 | | -/// Macro for including trees, strings, arrays from files. |
436 | | -/// |
437 | | -/// Multiple occurrences of groups are supported. |
438 | | -/// |
| 405 | +/// Macro for injecting trees, strings, arrays from files. |
| 406 | +/// |
| 407 | +/// ## template_macro |
439 | 408 | /// ```rust |
440 | 409 | /// use include_tt::inject; |
441 | 410 | /// use std::fmt::Write; |
| 411 | +/// let mut buf = String::new(); |
| 412 | +/// |
| 413 | +/// inject! { |
| 414 | +/// write!( |
| 415 | +/// &mut buf, |
| 416 | +/// "Welcome, {}. Your score is {}!", |
| 417 | +/// #tt("examples/name.tt"), // `"Ferris"` |
| 418 | +/// #tt("examples/" "score" ".tt") // `100500` |
| 419 | +/// ).unwrap(); |
| 420 | +/// } |
442 | 421 | /// |
443 | | -/// { // Embedding compiler trees from a file in an arbitrary place of other macros. |
444 | | -/// let a = 10; |
445 | | -/// let b = 20; |
446 | | -/// |
447 | | -/// let mut end_str = String::new(); |
448 | | -/// inject! { |
449 | | -/// let _e = write!( |
450 | | -/// &mut end_str, |
451 | | -/// |
452 | | -/// "arg1: {}, arg2: {}", |
453 | | -/// #tt("./examples/full.tt") // this file contains `a, b`. |
454 | | -/// ); |
455 | | -/// } |
456 | | -/// assert_eq!(end_str, "arg1: 10, arg2: 20"); |
457 | | -/// } |
458 | | -/// |
459 | | -/// { |
460 | | -/// let str = inject!( |
461 | | -/// #str("./examples/full.tt") // this file contains `a, b`. |
462 | | -/// ); |
463 | | -/// assert_eq!(str, "a, b"); |
464 | | -/// } |
465 | | -/// |
466 | | -/// { |
467 | | -/// let array: &'static [u8; 4] = inject!( |
468 | | -/// #arr("./examples/full.tt") // this file contains `a, b`. |
469 | | -/// ); |
470 | | -/// assert_eq!(array, b"a, b"); |
471 | | -/// } |
| 422 | +/// assert_eq!(buf, "Welcome, Ferris. Your score is 100500!"); |
| 423 | +/// ``` |
| 424 | +/// |
| 425 | +/// ## basic_codegen |
| 426 | +/// |
| 427 | +/// ```rust |
| 428 | +/// macro_rules! new_module { |
| 429 | +/// [ @($const_t: ident) : [ $($path:tt)* ]; ] => { |
| 430 | +/// include_tt::inject! { |
| 431 | +/// #[allow(dead_code)] |
| 432 | +/// #[allow(non_upper_case_globals)] |
| 433 | +/// pub mod my_module { |
| 434 | +/// pub const a: usize = 0; |
| 435 | +/// pub const b: usize = 10; |
| 436 | +/// |
| 437 | +/// // The `#POINT_TRACKER_FILES:` marker allows the macro to add additional |
| 438 | +/// // instructions that tell the compiler which files to track so that it can |
| 439 | +/// // recompile the macro if they change. This is completely optional, but without |
| 440 | +/// // it tracking will not work. |
| 441 | +/// #POINT_TRACKER_FILES: |
| 442 | +/// |
| 443 | +/// pub const $const_t: (usize, usize) = (#tt($($path)*)); |
| 444 | +/// } |
| 445 | +/// } |
| 446 | +/// }; |
| 447 | +/// } |
| 448 | +/// |
| 449 | +/// // we created a module "my_module" and a constant "T" containing (a, b). |
| 450 | +/// // |
| 451 | +/// // if you need to change, for example, to (b,a) or substitute constant values, |
| 452 | +/// // we will only change the contents of the file "for_examples/full.tt"! |
| 453 | +/// new_module! { |
| 454 | +/// @(T): [examples / "full" . t 't']; // this file contains "a, b", see "for_examples/full.tt" |
| 455 | +/// } |
| 456 | +/// assert_eq!(my_module::T, (0, 10)); |
472 | 457 | /// ``` |
473 | 458 | #[proc_macro] |
474 | 459 | pub fn inject(input: TokenStream) -> TokenStream { |
|
0 commit comments