1use proc_macro2::TokenStream;
2use quote::quote;
3use unsynn::*;
4
5use crate::parse::{SyncDocArg, SyncDocInner};
6use crate::token_processors::TokenProcessor;
7
8pub fn inject_all_docs_impl(
9 args: TokenStream,
10 input: TokenStream,
11) -> core::result::Result<TokenStream, TokenStream> {
12 let (base_path, cfg_attr) = match parse_path_from_args(args) {
13 Ok(result) => result,
14 Err(e) => {
15 let error_msg = e.to_string();
16 return Ok(quote! {
17 compile_error!(#error_msg);
18 #input
19 });
20 }
21 };
22
23 Ok(TokenProcessor::new(input, base_path, cfg_attr).process())
24}
25
26fn parse_path_from_args(
27 args: TokenStream,
28) -> core::result::Result<(String, Option<String>), String> {
29 if args.is_empty() {
31 let call_site = proc_macro2::Span::call_site();
32 if let Some(source_path) = call_site.local_file() {
33 let source_file = source_path.to_string_lossy().to_string();
34 let path = crate::config::get_docs_path(&source_file)
35 .map_err(|e| format!("Failed to get docs path from config: {}", e))?;
36 let cfg_attr = crate::config::get_cfg_attr().ok().flatten();
37 return Ok((path, cfg_attr));
38 } else {
39 return Err("omnidoc requires a path argument".to_string());
40 }
41 }
42
43 let mut args_iter = args.into_token_iter();
44 match args_iter.parse::<SyncDocInner>() {
45 Ok(parsed) => {
46 let mut path = None;
47 let mut cfg_attr = None;
48
49 if let Some(arg_list) = parsed.args {
50 for arg in arg_list.0 {
51 match arg.value {
52 SyncDocArg::Path(path_arg) => {
53 path = Some(path_arg.value.as_str().to_string());
54 }
55 SyncDocArg::CfgAttr(cfg_arg) => {
56 cfg_attr = Some(cfg_arg.value.as_str().to_string());
57 }
58 _ => {}
59 }
60 }
61 }
62
63 let path = if let Some(p) = path {
64 p
65 } else {
66 let call_site = proc_macro2::Span::call_site();
68 if let Some(source_path) = call_site.local_file() {
69 let source_file = source_path.to_string_lossy().to_string();
70 crate::config::get_docs_path(&source_file)
71 .map_err(|e| format!("Failed to get docs path from config: {}", e))?
72 } else {
73 return Err("path argument not found".to_string());
74 }
75 };
76
77 if cfg_attr.is_none() {
79 cfg_attr = crate::config::get_cfg_attr().ok().flatten();
80 }
81
82 Ok((path, cfg_attr))
83 }
84 Err(_e) => Err("Failed to parse arguments".to_string()),
85 }
86}