use crate::{Debug, Formatter, INDENT};
#[must_use = "must eventually call `finish()` on Debug builders"]
pub struct DebugMap<'a> {
fmt: &'a mut Formatter,
has_fields: bool,
has_key: bool,
}
pub(crate) fn new(fmt: &mut Formatter) -> DebugMap<'_> {
fmt.word("{");
fmt.cbox(INDENT);
fmt.zerobreak();
DebugMap {
fmt,
has_fields: false,
has_key: false,
}
}
impl<'a> DebugMap<'a> {
pub fn entry(&mut self, key: &dyn Debug, value: &dyn Debug) -> &mut Self {
self.key(key).value(value)
}
pub fn key(&mut self, key: &dyn Debug) -> &mut Self {
assert!(
!self.has_key,
"attempted to begin a new map entry \
without completing the previous one"
);
if self.has_fields {
self.fmt.trailing_comma_or_space(false);
}
self.fmt.ibox(0);
key.fmt(self.fmt); self.fmt.end();
self.fmt.word(": ");
self.has_key = true;
self
}
pub fn value(&mut self, value: &dyn Debug) -> &mut Self {
assert!(
self.has_key,
"attempted to format a map value before its key"
);
self.fmt.ibox(0);
value.fmt(self.fmt);
self.fmt.end();
self.has_key = false;
self.has_fields = true;
self
}
pub fn entries<K, V, I>(&mut self, entries: I) -> &mut Self
where
K: Debug,
V: Debug,
I: IntoIterator<Item = (K, V)>,
{
for (k, v) in entries {
self.entry(&k, &v);
}
self
}
pub fn finish(&mut self) {
assert!(
!self.has_key,
"attempted to finish a map with a partial entry"
);
if self.has_fields {
self.fmt.trailing_comma(true);
}
self.fmt.offset(-INDENT);
self.fmt.end();
self.fmt.word("}");
}
}