diff options
-rw-r--r-- | Cargo.toml | 22 | ||||
-rw-r--r-- | src/lib.rs | 57 |
2 files changed, 79 insertions, 0 deletions
diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..3fa7044 --- /dev/null +++ b/Cargo.toml | |||
@@ -0,0 +1,22 @@ | |||
1 | [package] | ||
2 | name = "confondant" | ||
3 | version = "0.1.0" | ||
4 | authors = ["Akshay <[email protected]>"] | ||
5 | edition = "2018" | ||
6 | |||
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
8 | |||
9 | [dependencies] | ||
10 | quote = "1.0" | ||
11 | toml = "^0.5" | ||
12 | |||
13 | [dependencies.serde] | ||
14 | version = "1.0.103" | ||
15 | features = ["derive"] | ||
16 | |||
17 | [dependencies.syn] | ||
18 | version = "1.0" | ||
19 | features = ["full"] | ||
20 | |||
21 | [lib] | ||
22 | proc-macro = true | ||
diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..bd6ed2b --- /dev/null +++ b/src/lib.rs | |||
@@ -0,0 +1,57 @@ | |||
1 | extern crate proc_macro; | ||
2 | |||
3 | use std::path::{Path, PathBuf}; | ||
4 | |||
5 | use proc_macro::TokenStream; | ||
6 | use quote::quote; | ||
7 | use syn::{parse_macro_input, AttrStyle, Attribute, DeriveInput, Lit, Meta, MetaNameValue}; | ||
8 | |||
9 | use serde::{de::DeserializeOwned, Serialize}; | ||
10 | |||
11 | trait Config<T> | ||
12 | where | ||
13 | T: Serialize + DeserializeOwned + Default, | ||
14 | { | ||
15 | fn load() -> Result<T, String>; | ||
16 | fn store() -> Result<(), String>; | ||
17 | } | ||
18 | |||
19 | fn is_outer_attribute(a: &Attribute) -> bool { | ||
20 | match a.style { | ||
21 | AttrStyle::Outer => true, | ||
22 | _ => false, | ||
23 | } | ||
24 | } | ||
25 | |||
26 | #[proc_macro_derive(Config, attributes(filename, filetype))] | ||
27 | pub fn config_attribute(item: TokenStream) -> TokenStream { | ||
28 | let mut ast: DeriveInput = syn::parse(item).unwrap(); | ||
29 | |||
30 | let mut filename: Option<PathBuf> = None; | ||
31 | let mut filetype: Option<PathBuf> = None; | ||
32 | |||
33 | for option in ast.attrs.into_iter() { | ||
34 | let option = option.parse_meta().unwrap(); | ||
35 | match option { | ||
36 | Meta::NameValue(MetaNameValue { | ||
37 | ref path, ref lit, .. | ||
38 | }) if path.is_ident("filename") => { | ||
39 | if let Lit::Str(f) = lit { | ||
40 | filename = Some(PathBuf::from(f.value())); | ||
41 | } | ||
42 | } | ||
43 | Meta::NameValue(MetaNameValue { | ||
44 | ref path, ref lit, .. | ||
45 | }) if path.is_ident("filetype") => { | ||
46 | if let Lit::Str(f) = lit { | ||
47 | filetype = Some(PathBuf::from(f.value())); | ||
48 | } | ||
49 | } | ||
50 | _ => {} | ||
51 | } | ||
52 | } | ||
53 | |||
54 | println!("{:?} {:?}", filename, filetype); | ||
55 | |||
56 | TokenStream::new() | ||
57 | } | ||