Skip to main content

format_like

Macro format_like 

Source
format_like!() { /* proc-macro */ }
Expand description

A macro for creating format-like macros

#![feature(decl_macro)]
use format_like::format_like;

#[derive(Debug, PartialEq)]
struct CommentedString(String, Vec<(usize, String)>);

let comment = "there is an error in this word";
let text = "text";
let range = 0..usize::MAX;

let commented_string = commented_string!(
    "This is <comment>worng {}, and this is the end of the range {range.end}",
    text
);

assert_eq!(
    commented_string,
    CommentedString(
        "This is worng text, and this is the end of the range 18446744073709551615".to_string(),
        vec![(8, "there is an error in this word".to_string())]
    )
);

macro commented_string($($parts:tt)*) {
    format_like!(
        parse_str,
        [('{', parse_interpolation, false), ('<', parse_comment, true)],
        CommentedString(String::new(), Vec::new()),
        $($parts)*
    )
}

macro parse_str($value:expr, $str:literal) {{
    let mut commented_string = $value;
    commented_string.0.push_str($str);
    commented_string
}}

macro parse_interpolation($value:expr, $modif:literal, $added:expr) {{
    let CommentedString(string, comments) = $value;
    let string = format!(concat!("{}{", $modif, "}"), string, $added);
    CommentedString(string, comments)
}}

macro parse_comment($value:expr, $_modif:literal, $added:expr) {{
    let mut commented_string = $value;
    commented_string.1.push((commented_string.0.len(), $added.to_string()));
    commented_string
}}