Problem with publishing array of [u8] in proc-macro

I am using quote crate to publish the new line of code in my proc-macro.
The below code is the code that I want to publish.

let s= "hello, word!"; pub static DATA: [u8; 12] = *b#s;

But I got unknown prefix error.

I couldn't find a way that convert s to array of [u8] to replace it with this code.
Can you please help me with that?

Thanks!

Macros operate on streams of tokens, not literal text. When you try and stick the b in front of the string literal it produces a different stream of tokens than a byte string does. Specifically an ident token b followed by a normal string literal, as opposed to the single token of a byte string literal.

You just need to create a byte string literal[1] directly before passing it to quote

use proc_macro::TokenStream;
use proc_macro2::Literal;
use quote::quote;

#[proc_macro]
pub fn bytes(_tokens: TokenStream) -> TokenStream {
    let bytes = "hello, world!".as_bytes();
    let s = Literal::byte_string(bytes);
    let len = bytes.len();

    quote! {
        pub static DATA: [u8; #len] = *#s;
    }
    .into()
}

Using that from a binary crate like this

fn main() {
    sample_macro::bytes!();
}

results in this cargo expand output

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
    pub static DATA: [u8; 13usize] = *b"hello, world!";
}

  1. Note that quote allows you to use proc_macro2 types, but not proc_macro types directly. So you'll need to add a dependency on proc_macro2 if you don't already have one ↩ī¸Ž

3 Likes

It worked! thank you so much!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.