Skip to content

Commit

Permalink
Merge pull request #283 from dtolnay/cstr
Browse files Browse the repository at this point in the history
Implement ToTokens for CStr and CString
  • Loading branch information
dtolnay authored Aug 22, 2024
2 parents ba7a9d0 + 6ac4328 commit 9382c21
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ repository = "https://github.com/dtolnay/quote"
rust-version = "1.56"

[dependencies]
proc-macro2 = { version = "1.0.74", default-features = false }
proc-macro2 = { version = "1.0.80", default-features = false }

[dev-dependencies]
rustversion = "1.0"
Expand Down
13 changes: 13 additions & 0 deletions src/to_tokens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use alloc::borrow::Cow;
use alloc::rc::Rc;
use core::iter;
use proc_macro2::{Group, Ident, Literal, Punct, Span, TokenStream, TokenTree};
use std::ffi::{CStr, CString};

/// Types that can be interpolated inside a `quote!` invocation.
///
Expand Down Expand Up @@ -221,6 +222,18 @@ impl ToTokens for bool {
}
}

impl ToTokens for CStr {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append(Literal::c_string(self));
}
}

impl ToTokens for CString {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append(Literal::c_string(self));
}
}

impl ToTokens for Group {
fn to_tokens(&self, tokens: &mut TokenStream) {
tokens.append(self.clone());
Expand Down
17 changes: 17 additions & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, TokenStreamExt};
use std::borrow::Cow;
use std::collections::BTreeSet;
use std::ffi::{CStr, CString};

struct X;

Expand Down Expand Up @@ -232,6 +233,22 @@ fn test_string() {
assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_c_str() {
let s = CStr::from_bytes_with_nul(b"\x01 a 'b \" c\0").unwrap();
let tokens = quote!(#s);
let expected = "c\"\\u{1} a 'b \\\" c\"";
assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_c_string() {
let s = CString::new(&b"\x01 a 'b \" c"[..]).unwrap();
let tokens = quote!(#s);
let expected = "c\"\\u{1} a 'b \\\" c\"";
assert_eq!(expected, tokens.to_string());
}

#[test]
fn test_interpolated_literal() {
macro_rules! m {
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/not-quotable.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ error[E0277]: the trait bound `Ipv4Addr: ToTokens` is not satisfied
&'a T
&'a mut T
Box<T>
CStr
CString
Cow<'a, T>
Option<T>
Rc<T>
RepInterp<T>
String
and $N others
= note: this error originates in the macro `quote` (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit 9382c21

Please sign in to comment.