diff --git a/src/libstd/env.rs b/src/libstd/env.rs index 889ba81e778..287c65e4853 100644 --- a/src/libstd/env.rs +++ b/src/libstd/env.rs @@ -712,7 +712,9 @@ impl DoubleEndedIterator for Args { #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for Args { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("Args { .. }") + f.debug_struct("Args") + .field("inner", &self.inner.inner.inner_debug()) + .finish() } } @@ -737,7 +739,9 @@ impl DoubleEndedIterator for ArgsOs { #[stable(feature = "std_debug", since = "1.16.0")] impl fmt::Debug for ArgsOs { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("ArgsOs { .. }") + f.debug_struct("ArgsOs") + .field("inner", &self.inner.inner_debug()) + .finish() } } @@ -1085,4 +1089,14 @@ mod tests { r#""c:\te;st";c:\"#)); assert!(join_paths([r#"c:\te"st"#].iter().cloned()).is_err()); } + + #[test] + fn args_debug() { + assert_eq!( + format!("Args {{ inner: {:?} }}", args().collect::>()), + format!("{:?}", args())); + assert_eq!( + format!("ArgsOs {{ inner: {:?} }}", args_os().collect::>()), + format!("{:?}", args_os())); } +} diff --git a/src/libstd/sys/redox/args.rs b/src/libstd/sys/redox/args.rs index 212895d7b76..6e44ad705fe 100644 --- a/src/libstd/sys/redox/args.rs +++ b/src/libstd/sys/redox/args.rs @@ -35,6 +35,12 @@ pub struct Args { _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl Args { + pub fn inner_debug(&self) -> &[OsString] { + self.iter.as_slice() + } +} + impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 6e35a472792..bbdcb5d3616 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -35,6 +35,12 @@ pub struct Args { _dont_send_or_sync_me: PhantomData<*mut ()>, } +impl Args { + pub fn inner_debug(&self) -> &[OsString] { + self.iter.as_slice() + } +} + impl Iterator for Args { type Item = OsString; fn next(&mut self) -> Option { self.iter.next() } diff --git a/src/libstd/sys/windows/args.rs b/src/libstd/sys/windows/args.rs index aa61f9adb82..4784633edc1 100644 --- a/src/libstd/sys/windows/args.rs +++ b/src/libstd/sys/windows/args.rs @@ -16,6 +16,7 @@ use slice; use ops::Range; use ffi::OsString; use libc::{c_int, c_void}; +use fmt; pub unsafe fn init(_argc: isize, _argv: *const *const u8) { } @@ -39,6 +40,36 @@ pub struct Args { cur: *mut *mut u16, } +pub struct ArgsInnerDebug<'a> { + args: &'a Args, +} + +impl<'a> fmt::Debug for ArgsInnerDebug<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("[")?; + let mut first = true; + for i in self.args.range.clone() { + if !first { + f.write_str(", ")?; + } + first = false; + + // Here we do allocation which could be avoided. + fmt::Debug::fmt(&unsafe { os_string_from_ptr(*self.args.cur.offset(i)) }, f)?; + } + f.write_str("]")?; + Ok(()) + } +} + +impl Args { + pub fn inner_debug(&self) -> ArgsInnerDebug { + ArgsInnerDebug { + args: self + } + } +} + unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString { let mut len = 0; while *ptr.offset(len) != 0 { len += 1; }