Path: blob/main/crates/wasi-preview1-component-adapter/byte-array-literals/src/lib.rs
2459 views
extern crate proc_macro;12use proc_macro::{Delimiter, Group, Literal, Punct, Spacing, TokenStream, TokenTree};34/// Expand a `str` literal into a byte array.5#[proc_macro]6pub fn str(input: TokenStream) -> TokenStream {7let rv = convert_str(input);89vec![TokenTree::Group(Group::new(10Delimiter::Bracket,11rv.into_iter().collect(),12))]13.into_iter()14.collect()15}1617/// The same as `str` but appends a `'\n'`.18#[proc_macro]19pub fn str_nl(input: TokenStream) -> TokenStream {20let mut rv = convert_str(input);2122rv.push(TokenTree::Literal(Literal::u8_suffixed(b'\n')));2324vec![TokenTree::Group(Group::new(25Delimiter::Bracket,26rv.into_iter().collect(),27))]28.into_iter()29.collect()30}3132fn convert_str(input: TokenStream) -> Vec<TokenTree> {33let mut it = input.into_iter();3435let mut tokens = Vec::new();36match it.next() {37Some(TokenTree::Literal(l)) => {38for b in to_string(l).into_bytes() {39tokens.push(TokenTree::Literal(Literal::u8_suffixed(b)));40tokens.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));41}42}43_ => panic!(),44}4546assert!(it.next().is_none());47tokens48}4950fn to_string(lit: Literal) -> String {51let formatted = lit.to_string();5253let mut it = formatted.chars();54assert_eq!(it.next(), Some('"'));5556let mut rv = String::new();57loop {58match it.next() {59Some('"') => match it.next() {60Some(_) => panic!(),61None => break,62},63Some('\\') => match it.next() {64Some('x') => {65let hi = it.next().unwrap().to_digit(16).unwrap();66let lo = it.next().unwrap().to_digit(16).unwrap();67let v = (hi << 16) | lo;68rv.push(v as u8 as char);69}70Some('u') => {71assert_eq!(it.next(), Some('{'));72let mut c = it.next().unwrap();73let mut ch = 0;74while let Some(v) = c.to_digit(16) {75ch *= 16;76ch |= v;77c = it.next().unwrap();78}79assert_eq!(c, '}');80rv.push(::std::char::from_u32(ch).unwrap());81}82Some('0') => rv.push('\0'),83Some('\\') => rv.push('\\'),84Some('\"') => rv.push('\"'),85Some('r') => rv.push('\r'),86Some('n') => rv.push('\n'),87Some('t') => rv.push('\t'),88Some(_) => panic!(),89None => panic!(),90},91Some(c) => rv.push(c),92None => panic!(),93}94}9596rv97}9899100