cmark_writer_macros/
lib.rs1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::quote;
4use syn::{parse_macro_input, DeriveInput};
5
6#[proc_macro_derive(CommonMarkOnly)]
23pub fn derive_commonmark_only(input: TokenStream) -> TokenStream {
24 let input = parse_macro_input!(input as DeriveInput);
25 let name = &input.ident;
26
27 let expanded = quote! {
28 impl ::cmark_writer::MultiFormat for #name {
29 fn supports_html(&self) -> bool {
30 false
31 }
32
33 fn html_format(&self, writer: &mut ::cmark_writer::HtmlWriter) -> ::cmark_writer::error::WriteResult<()> {
34 writer
35 .raw_html(&format!(
36 "<!-- HTML rendering not implemented for {} -->",
37 std::any::type_name::<Self>()
38 ))
39 .map_err(Into::into)
40 }
41 }
42 };
43
44 TokenStream::from(expanded)
45}
46
47#[proc_macro_attribute]
58pub fn structure_error(attr: TokenStream, item: TokenStream) -> TokenStream {
59 let attr_str = attr.to_string();
60 let input = parse_macro_input!(item as DeriveInput);
61 let name = &input.ident;
62
63 let format = if attr_str.starts_with("format") {
65 let format_str = attr_str
66 .replace("format", "")
67 .replace("=", "")
68 .trim()
69 .trim_matches('"')
70 .to_string();
71 format_str
72 } else {
73 "{}".to_string()
75 };
76
77 let expanded = quote! {
78 #input
79
80 impl #name {
81 pub fn new(message: &'static str) -> Self {
82 Self(message)
83 }
84
85 pub fn into_error(self) -> ::cmark_writer::error::WriteError {
86 let mut error_factory = ::cmark_writer::error::StructureError::new(#format);
87
88 let arg = self.0.to_string();
89 error_factory = error_factory.arg(arg);
90
91 <::cmark_writer::error::StructureError as ::cmark_writer::error::CustomErrorFactory>::create_error(&error_factory)
92 }
93 }
94
95 impl From<#name> for ::cmark_writer::error::WriteError {
96 fn from(factory: #name) -> Self {
97 factory.into_error()
98 }
99 }
100
101 impl ::cmark_writer::error::CustomErrorFactory for #name {
102 fn create_error(&self) -> ::cmark_writer::error::WriteError {
103 let mut error_factory = ::cmark_writer::error::StructureError::new(#format);
104
105 let arg = self.0.to_string();
106 error_factory = error_factory.arg(arg);
107
108 <::cmark_writer::error::StructureError as ::cmark_writer::error::CustomErrorFactory>::create_error(&error_factory)
109 }
110 }
111 };
112
113 TokenStream::from(expanded)
114}
115
116#[proc_macro_attribute]
127pub fn coded_error(_attr: TokenStream, item: TokenStream) -> TokenStream {
128 let input = parse_macro_input!(item as DeriveInput);
129 let name = &input.ident;
130
131 let expanded = quote! {
132 #input
133
134 impl #name {
135 pub fn new(message: &str, code: &str) -> Self {
136 Self(message.to_string(), code.to_string())
137 }
138
139 pub fn into_error(self) -> ::cmark_writer::error::WriteError {
140 let coded_error = ::cmark_writer::error::CodedError::new(self.0, self.1);
141 <::cmark_writer::error::CodedError as ::cmark_writer::error::CustomErrorFactory>::create_error(&coded_error)
142 }
143 }
144
145 impl From<#name> for ::cmark_writer::error::WriteError {
146 fn from(factory: #name) -> Self {
147 factory.into_error()
148 }
149 }
150
151 impl ::cmark_writer::error::CustomErrorFactory for #name {
152 fn create_error(&self) -> ::cmark_writer::error::WriteError {
153 let coded_error = ::cmark_writer::error::CodedError::new(self.0.clone(), self.1.clone());
154 <::cmark_writer::error::CodedError as ::cmark_writer::error::CustomErrorFactory>::create_error(&coded_error)
155 }
156 }
157 };
158
159 TokenStream::from(expanded)
160}