lsp_doc_stable 0.1.0

Embed markdown/text files into Rust documentation attributes for LSP hover/preview
Documentation
use std::fs::read_to_string;

use proc_macro2::TokenTree;
use quote::{quote, ToTokens};

#[proc_macro_attribute]
pub fn lsp_doc(
    attr: proc_macro::TokenStream,
    item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    let attr: proc_macro2::TokenStream = attr.into();
    let item: proc_macro2::TokenStream = item.into();

    let path = attr
        .clone()
        .into_iter()
        .find_map(|tree| {
            if let TokenTree::Literal(lit) = tree {
                let path = lit.to_string();
                Some(path[1..path.len() - 1].to_string())
            } else {
                None
            }
        })
        .expect("The attribute macro should have a path to the file of type `Literal`.");

    let md = read_to_string(&path).expect(format!("Could not find {path:?}").as_str());
    let md = format!("\n\n{}\n\n\n", md.trim());

    let mut new_items = vec![quote! {
        #[doc = #md]
    }];
    for tree in item.into_iter() {
        new_items.push(tree.to_token_stream());
    }

    quote! {
        #(#new_items)*
    }
    .into()
}