telety-macro 0.3.0

Proc macros for telety. Not intended for public use.
Documentation
use proc_macro2::{Group, TokenStream};
use syn::{
    parse::{Parse, ParseStream},
    parse2, Token,
};
use telety_impl::find_and_replace::SingleToken;

struct FindAndReplaceArgs {
    needle: SingleToken,
    _comma0: Token![,],
    replacement: Group,
    _comma1: Token![,],
    haystack: TokenStream,
}

impl FindAndReplaceArgs {
    pub fn find_and_replace(self) -> TokenStream {
        let Self {
            needle,
            _comma0,
            replacement,
            _comma1,
            haystack,
        } = self;

        telety_impl::find_and_replace::find_and_replace(needle, replacement.stream(), haystack)
    }
}

impl Parse for FindAndReplaceArgs {
    fn parse(input: ParseStream) -> syn::Result<Self> {
        Ok(Self {
            needle: input.parse()?,
            _comma0: input.parse()?,
            replacement: input.parse()?,
            _comma1: input.parse()?,
            haystack: input.parse()?,
        })
    }
}

pub(crate) fn find_and_replace(args: TokenStream) -> syn::Result<TokenStream> {
    let args: FindAndReplaceArgs = parse2(args)?;
    Ok(args.find_and_replace())
}

#[cfg(test)]
mod test {
    use quote::{quote, ToTokens as _};
    use syn::parse_quote;

    use super::*;

    #[test]
    fn test() {
        let args: FindAndReplaceArgs = parse_quote!(
            $,
            [$dollar],
            macro_rules! my_macro {
                ($($tokens:tt)*) => {
                    $($tokens)*
                };
            }
        );

        let output = args.find_and_replace();

        assert_eq!(
            output.to_token_stream().to_string(),
            quote!(
                macro_rules! my_macro {
                    ($dollar ($dollar tokens:tt)*) => {
                        $dollar ($dollar tokens)*
                    };
                }
            )
            .to_string()
        );
    }
}