Byte string parsing
diff --git a/src/lit.rs b/src/lit.rs
index 6f1b903..c7a647f 100644
--- a/src/lit.rs
+++ b/src/lit.rs
@@ -60,7 +60,8 @@
named!(pub lit -> Lit, alt!(
string
- // TODO: ByteStr
+ |
+ byte_string
// TODO: Byte
// TODO: Char
|
@@ -82,6 +83,19 @@
) => { |(s, n)| Lit::Str(s, StrStyle::Raw(n)) }
));
+ named!(byte_string -> Lit, alt!(
+ delimited!(
+ punct!("b\""),
+ cooked_string,
+ tag!("\"")
+ ) => { |s: String| Lit::ByteStr(s.into_bytes()) }
+ |
+ preceded!(
+ punct!("br"),
+ raw_string
+ ) => { |(s, _): (String, _)| Lit::ByteStr(s.into_bytes()) }
+ ));
+
named!(pub int -> (u64, IntTy), tuple!(
preceded!(
option!(whitespace),
@@ -145,6 +159,7 @@
mod printing {
use super::*;
use quote::{Tokens, ToTokens};
+ use std::{ascii, iter};
use std::fmt::{self, Display};
impl ToTokens for Lit {
@@ -152,17 +167,17 @@
match *self {
Lit::Str(ref s, StrStyle::Cooked) => s.to_tokens(tokens),
Lit::Str(ref s, StrStyle::Raw(n)) => {
- let mut tok = "r".to_string();
- for _ in 0..n {
- tok.push('#');
+ tokens.append(&format!("r{delim}\"{string}\"{delim}",
+ delim = iter::repeat("#").take(n).collect::<String>(),
+ string = s));
+ }
+ Lit::ByteStr(ref v) => {
+ let mut escaped = "b\"".to_string();
+ for &ch in v.iter() {
+ escaped.extend(ascii::escape_default(ch).map(|c| c as char));
}
- tok.push('"');
- tok.push_str(s);
- tok.push('"');
- for _ in 0..n {
- tok.push('#');
- }
- tokens.append(&tok);
+ escaped.push('"');
+ tokens.append(&escaped);
}
Lit::Int(value, ty) => tokens.append(&format!("{}{}", value, ty)),
_ => unimplemented!(),