reactive_graph_plugin_derive/
lib.rs

1// #[macro_use]
2// extern crate darling;
3// extern crate proc_macro;
4//
5// use proc_macro::TokenStream;
6// use proc_macro2::TokenStream as TokenStream2;
7//
8// use quote::format_ident;
9// use quote::quote;
10// use syn::parse_macro_input;
11// use syn::DeriveInput;
12// use syn::Ident;
13//
14// use crate::darling::FromDeriveInput;
15//
16// #[derive(FromDeriveInput)]
17// #[darling(attributes(type_provider))]
18// struct TypeProviderConfig {
19//     tys: syn::Type,
20//     path: String,
21//     component_alias: Option<bool>,
22// }
23//
24// uses_type_params!(TypeProviderConfig, tys);
25//
26// #[proc_macro_derive(TypeProvider, attributes(type_provider))]
27// pub fn type_provider(input: TokenStream) -> TokenStream {
28//     let input: DeriveInput = parse_macro_input!(input);
29//
30//     let ident: Ident = input.ident.clone();
31//     let ident_assets = format_ident!("{}Assets", ident);
32//
33//     let type_provider_config = match TypeProviderConfig::from_derive_input(&input) {
34//         Ok(type_provider_config) => type_provider_config,
35//         Err(e) => {
36//             return e.write_errors().into();
37//         }
38//     };
39//     let tys = type_provider_config.tys;
40//     let path = type_provider_config.path;
41//     let type_provider_id = ident.to_string();
42//
43//     let component_alias = if type_provider_config.component_alias.unwrap_or(true) {
44//         quote! {
45//             #[reactive_graph_plugin_api::springtime_di::component_alias]
46//         }
47//     } else {
48//         TokenStream2::new()
49//     };
50//
51//     #[cfg(feature = "json")]
52//     let json = {
53//         quote! {
54//             match reactive_graph_plugin_api::serde_json::from_str(asset_str) {
55//                 Ok(parsed_entry) => {
56//                     let entry: <#tys as reactive_graph_graph::NamespacedTypeContainer>::Type = parsed_entry;
57//                     reactive_graph_graph::NamespacedTypeContainer::push(&entries, entry);
58//                 }
59//                 Err(e) => log::error!("Error in parsing JSON file {filename}: {e}"),
60//             }
61//         }
62//     };
63//     #[cfg(not(feature = "json"))]
64//     let json = {
65//         quote! {
66//             log::error!("Failed to read type definition from {filename}: JSON is not a supported file format!");
67//         }
68//     };
69//
70//     #[cfg(feature = "json5")]
71//     let json5 = {
72//         quote! {
73//             match reactive_graph_plugin_api::json5::from_str(asset_str) {
74//                 Ok(parsed_entry) => {
75//                     let entry: <#tys as reactive_graph_graph::NamespacedTypeContainer>::Type = parsed_entry;
76//                     reactive_graph_graph::NamespacedTypeContainer::push(&entries, entry);
77//                 }
78//                 Err(e) => log::error!("Error in parsing JSON5 file {filename}: {e}"),
79//             }
80//         }
81//     };
82//     #[cfg(not(feature = "json5"))]
83//     let json5 = {
84//         quote! {
85//             log::error!("Failed to read type definition from {filename}: JSON5 is not a supported file format!");
86//         }
87//     };
88//
89//     #[cfg(feature = "toml")]
90//     let toml = {
91//         quote! {
92//             match reactive_graph_plugin_api::toml::from_str(asset_str) {
93//                 Ok(parsed_entry) => {
94//                     let entry: <#tys as reactive_graph_graph::NamespacedTypeContainer>::Type = parsed_entry;
95//                     reactive_graph_graph::NamespacedTypeContainer::push(&entries, entry);
96//                 }
97//                 Err(e) => log::error!("Error in parsing TOML file {filename}: {e}"),
98//             }
99//         }
100//     };
101//     #[cfg(not(feature = "toml"))]
102//     let toml = {
103//         quote! {
104//             log::error!("Failed to read type definition from {filename}: TOML is not a supported file format!");
105//         }
106//     };
107//
108//     let expanded = quote! {
109//         #[derive(rust_embed::RustEmbed)]
110//         #[folder = #path]
111//         struct #ident_assets;
112//
113//         #[automatically_derived]
114//         #component_alias
115//         impl reactive_graph_plugin_api::TypeProvider<#tys> for #ident {
116//             fn id<'a>(&self) -> &'a str {
117//                 #type_provider_id
118//             }
119//             fn get_types(&self) -> #tys {
120//                 let mut entries = <#tys as reactive_graph_graph::NamespacedTypeContainer>::new();
121//                 for file in #ident_assets::iter() {
122//                     let filename = file.as_ref();
123//                     if filename.starts_with(".") {
124//                         // do nothing
125//                         continue;
126//                     }
127//                     log::debug!("Loading resource {}", filename);
128//                     match #ident_assets::get(filename) {
129//                         Some(asset) => match std::str::from_utf8(asset.data.as_ref()) {
130//                             Ok(asset_str) => {
131//                                 if filename.ends_with(".json") {
132//                                     #json
133//                                 } else if filename.ends_with(".json5") {
134//                                     #json5
135//                                 } else if filename.ends_with(".toml") {
136//                                     #toml
137//                                 } else {
138//                                     log::error!("Can't read type definition {}: Only JSON, JSON5 and TOML are supported.", filename);
139//                                 }
140//                             }
141//                             Err(e) => log::error!("Error in decoding file to UTF-8 {}: {}", filename, e),
142//                         },
143//                         None => {}
144//                     }
145//                 }
146//                 entries
147//             }
148//         }
149//     };
150//     TokenStream::from(expanded)
151// }