syncdoc_core/
omnibus.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3use unsynn::*;
4
5use crate::parse::{DocStubArg, DocStubInner};
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    // Parse the path argument
13    let base_path = match parse_path_from_args(args) {
14        Ok(path) => path,
15        Err(e) => {
16            let error_msg = e.to_string();
17            // Return both the error and the original input to avoid syntax errors
18            return Ok(quote! {
19                compile_error!(#error_msg);
20                #input
21            });
22        }
23    };
24
25    // Process the input with the base path
26    Ok(TokenProcessor::new(input, base_path).process())
27}
28
29fn parse_path_from_args(args: TokenStream) -> core::result::Result<String, String> {
30    // If no args provided, try to get from config (only if span info available)
31    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            return crate::config::get_docs_path(&source_file)
36                .map_err(|e| format!("Failed to get docs path from config: {}", e));
37        } else {
38            return Err("omnidoc requires a path argument".to_string());
39        }
40    }
41
42    let mut args_iter = args.into_token_iter();
43    match args_iter.parse::<DocStubInner>() {
44        Ok(parsed) => {
45            if let Some(arg_list) = parsed.args {
46                for arg in arg_list.0 {
47                    if let DocStubArg::Path(path_arg) = arg.value {
48                        return Ok(path_arg.value.as_str().to_string());
49                    }
50                }
51            }
52            // If parsed but no path found, try config (only if span info available)
53            let call_site = proc_macro2::Span::call_site();
54            if let Some(source_path) = call_site.local_file() {
55                let source_file = source_path.to_string_lossy().to_string();
56                crate::config::get_docs_path(&source_file)
57                    .map_err(|e| format!("Failed to get docs path from config: {}", e))
58            } else {
59                Err("path argument not found".to_string())
60            }
61        }
62        Err(_e) => Err("Failed to parse arguments".to_string()),
63    }
64}