spread_patterns 0.1.0

Some macros to make it easier to do pattern matching over strings, arrays, etc.
Documentation
use proc_macro::TokenStream;
use proc_macro2::{Literal, Span};
use syn::{parse_macro_input, LitInt, LitStr};
use quote::quote;

fn extract_items(input_val: &str) -> Vec<proc_macro2::TokenStream> {
    let mut items = Vec::with_capacity(input_val.len());

    for ch in input_val.chars() {
        if ch.is_ascii() {
            let item = Literal::byte_character(ch as u8);
            items.push(quote! {#item});
            continue;
        }

        let mut buf = [0; 4];
        ch.encode_utf8(&mut buf);

        for byte in buf.iter() {
            if *byte != 0 {
                let item_str = format!("0x{:x}", *byte);
                let item = LitInt::new(&item_str, Span::call_site());
                items.push(quote! {#item});
            }
        }
    }

    items
}

#[proc_macro]
pub fn has_prefix(ts: TokenStream) -> TokenStream {
    let input = parse_macro_input!(ts as LitStr);
    let input_val = input.value();

    if input_val.is_empty() {
        return TokenStream::from(quote! { [..] });
    }

    let items = extract_items(&input_val);

    TokenStream::from(quote! { [#(#items),*, ..] })
}

#[proc_macro]
pub fn has_suffix(ts: TokenStream) -> TokenStream {
    let input = parse_macro_input!(ts as LitStr);
    let input_val = input.value();

    if input_val.is_empty() {
        return TokenStream::from(quote! { [..] });
    }

    let items = extract_items(&input_val);

    TokenStream::from(quote! { [.., #(#items),*] })
}