-
Notifications
You must be signed in to change notification settings - Fork 0
/
tools.rs
103 lines (84 loc) · 2.5 KB
/
tools.rs
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
use ::rustfmt::{format_input, Input};
use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{Ident, Type, Field, parse_quote, DeriveInput};
use std::{io::Sink, marker::PhantomData};
pub struct TypeDecl<'a> {
original: &'a str,
ident: Ident,
ty: Type,
_marker: PhantomData<fn(&'a ()) -> &'a ()>
}
impl<'a> TypeDecl<'a> {
pub fn new(original: &'a str, ident: Ident, ty: &'a Type) -> Self {
Self {
original,
ident,
ty: ty.clone(),
_marker: PhantomData
}
}
}
impl<'a> ToTokens for TypeDecl<'a> {
fn to_tokens(&self, tokens: &mut TokenStream2) {
let original = self.original;
let ident = &self.ident;
let ty = &self.ty;
let docu = doc_type(ident, ty, original);
let ty_decl = quote!(#[doc = #docu] pub type #ident = #ty;);
tokens.append_all(ty_decl);
}
}
pub fn doc_type(name: &Ident, ty: &Type, original: &str) -> String {
let name = name.to_string();
let ty = ty.to_token_stream().to_string().replace(" ", "");
format!(
include_str!("docs/type.md"),
original = original,
name = name,
ty = ty
)
}
pub fn doc_field(name: &Ident, ty: &Type, parent: &str) -> String {
let name = name.to_string();
let ty = ty.to_token_stream().to_string().replace(" ", "");
format!(
include_str!("docs/field.md"),
parent = parent,
name = name,
ty = ty
)
}
pub fn doc_struct(name: &str, original: &str) -> String {
format!(
include_str!("docs/struct.md"),
name = name,
original = original
)
}
pub fn format_code(orig: String) -> String {
format_input(Input::Text(orig), &<_>::default(), None::<&mut Sink>)
.map(|res| res.1.into_iter().next())
.ok()
.flatten()
.map(|m| m.1.to_string())
.expect("Original input should be formatted")
}
pub fn create_ident(i: usize) -> impl Fn() -> Ident {
move || Ident::new(format!("ty_{i}").as_str(), proc_macro2::Span::call_site())
}
pub fn modify(field: &mut Field, parent: &str, i: usize) -> Ident {
let ident = field.ident.clone().unwrap_or_else(create_ident(i));
let docu = doc_field(
&ident,
&field.ty,
parent,
);
field.vis = parse_quote!(pub);
field.attrs.push(parse_quote!(#[doc = #docu]));
ident
}
pub fn publicify(ast: &mut DeriveInput) {
ast.ident = parse_quote!(ty);
ast.vis = parse_quote!(pub);
}