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