1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::fmt;
use std::ops::Deref;
use Argdata;
use ArgdataRef;
use ReadError;
use Value;

struct FmtError<T>(Result<T, ReadError>);

impl<T: fmt::Debug> fmt::Debug for FmtError<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		match self.0 {
			Ok(ref value) => value.fmt(f),
			Err(ref err) => write!(f, "error(\"{:?}\")", err),
		}
	}
}

impl<'a, 'd> fmt::Debug for ArgdataRef<'a, 'd> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		self.deref().fmt(f)
	}
}

impl<'a, 'd> fmt::Debug for Argdata<'d> + 'a {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		FmtError(self.read()).fmt(f)
	}
}

impl<'a, 'd> fmt::Debug for Value<'a, 'd> {
	fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
		match self {
			Value::Null => write!(f, "null"),
			Value::Binary(val) => write!(f, "binary({:?})", val),
			Value::Bool(val) => val.fmt(f),
			Value::Fd(fd) => write!(f, "fd({})", fd.raw_encoded_number()),
			Value::Float(val) => fmt::Debug::fmt(val, f),
			Value::Int(val) => fmt::Debug::fmt(val, f),
			Value::Str(val) => fmt::Debug::fmt(&FmtError(val.as_str().map_err(Into::into)), f),
			Value::Timestamp(val) => write!(f, "timestamp({}, {})", val.sec, val.nsec),
			Value::Map(val) => {
				let it = val.iter_map().map(|x| match x {
					Ok((k, v)) => (FmtError(Ok(k)), FmtError(Ok(v))),
					Err(e) => (FmtError(Err(e)), FmtError(Err(e))),
				});
				f.debug_map().entries(it).finish()
			}
			Value::Seq(val) => {
				let it = val.iter_seq().map(FmtError);
				f.debug_list().entries(it).finish()
			}
		}
	}
}

#[test]
fn debug_fmt() {
	let argdata = ::encoded(
		&b"\x06\x87\x08Hello\x00\x87\x08World\x00\x81\x02\x82\x02\x01\x86\x09\
		\x70\xF1\x80\x29\x15\x84\x05\x58\xe5\xd9\x80\x83\x06\x80\x80"[..],
	);

	assert_eq!(
		format!("{:?}", &argdata as &Argdata),
		"{\"Hello\": \"World\", false: true, timestamp(485, 88045333): 5826009, null: {null: null}}"
	);

	let argdata = ::encoded(&b"\x07\x81\x02\x82\x02\x01\x80\x87\x08Hello\x00\x81\x06\x81\x07"[..]);

	assert_eq!(
		format!("{:?}", &argdata as &Argdata),
		"[false, true, null, \"Hello\", {}, []]"
	);
}