#![doc = include_str!("../Readme.md")]
#[macro_export]
macro_rules! concat_str {
(
@pre {$($pre:stmt,)*},
@strname $strname:ident,
@len $($len:expr)?,
@appends {$($appends:expr,)*},
$head:literal $(, $($tail:tt)*)?
) => {
$crate::concat_str!(
@pre {$($pre, )*
let tmp_res = $head
,},
@strname $strname,
@len $($len +)? tmp_res.len(),
@appends {
$($appends,)*
$strname.push_str(tmp_res),
},
$($($tail)*)?
)
};
(
@pre {$($pre:stmt,)*},
@strname $strname:ident,
@len $($len:expr)?,
@appends {$($appends:expr,)*},
$head:ident $(, $($tail:tt)*)?
) => {
$crate::concat_str!(
@pre {$($pre, )*},
@strname $strname,
@len $($len +)? $head.len(),
@appends {
$($appends,)*
$strname.push_str($head),
},
$($($tail)*)?
)
};
(
@pre {$($pre:stmt,)*},
@strname $strname:ident,
@len $($len:expr)?,
@appends {$($appends:expr,)*},
$head:expr $(, $($tail:tt)*)?
) => {
$crate::concat_str!(
@pre {$($pre, )*
let tmp_res = $head
,},
@strname $strname,
@len $($len +)? tmp_res.len(),
@appends {
$($appends,)*
$strname.push_str(tmp_res),
},
$($($tail)*)?
)
};
(
@pre {$($pre:stmt,)*},
@strname $strname:ident,
@len $len:expr,
@appends {$($appends:expr,)*},
) => {
{
$($pre)*
let mut $strname = String::with_capacity($len);
$($appends;)*
$strname
}
};
($($tt:tt)+) => {
$crate::concat_str!(@pre {}, @strname res_string, @len, @appends {}, $($tt)+)
};
}
#[cfg(test)]
mod tests {
#[test]
fn rtest() {
let a = "test";
let b = "local".to_string();
let c = "focal".to_string();
let i = 3;
assert_eq!(
concat_str!("", ""),
""
);
assert_eq!(
concat_str!("so, ", a, "test"),
"so, testtest"
);
assert_eq!(
concat_str!("so, ", &b, " ", &c),
"so, local focal"
);
assert_eq!(
concat_str!("so, ", &i.to_string(), " ", &c),
"so, 3 focal"
);
let repeat = "repeat?";
let repeat_o = "repeat?".to_string();
assert_eq!(
concat_str!(
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
),
"repeat?".repeat(100)
);
}
#[test]
fn explicit_failure_test() {
let short_str = "1".to_string();
let long_str = "long_string".to_string();
assert_eq!(
concat_str!(&short_str, " ", &long_str),
"1 long_string"
);
}
#[cfg(feature="count-allocations")]
#[test]
fn test_single_alloc() {
let repeat = "repeat?";
let repeat_o = "repeat?".to_string();
let alloc_count = allocation_counter::measure(|| {
let _ = concat_str!(
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
"repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, "repeat?", repeat, &repeat_o, repeat,
);
});
assert_eq!(alloc_count.count_total, 1);
}
}