| mod debug_struct { |
| use std::fmt; |
| |
| #[test] |
| fn test_empty() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo").finish() |
| } |
| } |
| |
| assert_eq!("Foo", format!("{Foo:?}")); |
| assert_eq!("Foo", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_single() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo").field("bar", &true).finish() |
| } |
| } |
| |
| assert_eq!("Foo { bar: true }", format!("{Foo:?}")); |
| assert_eq!( |
| "Foo { |
| bar: true, |
| }", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_multiple() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo") |
| .field("bar", &true) |
| .field("baz", &format_args!("{}/{}", 10, 20)) |
| .finish() |
| } |
| } |
| |
| assert_eq!("Foo { bar: true, baz: 10/20 }", format!("{Foo:?}")); |
| assert_eq!( |
| "Foo { |
| bar: true, |
| baz: 10/20, |
| }", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo") |
| .field("bar", &true) |
| .field("baz", &format_args!("{}/{}", 10, 20)) |
| .finish() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Bar").field("foo", &Foo).field("hello", &"world").finish() |
| } |
| } |
| |
| assert_eq!( |
| "Bar { foo: Foo { bar: true, baz: 10/20 }, hello: \"world\" }", |
| format!("{Bar:?}") |
| ); |
| assert_eq!( |
| "Bar { |
| foo: Foo { |
| bar: true, |
| baz: 10/20, |
| }, |
| hello: \"world\", |
| }", |
| format!("{Bar:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_only_non_exhaustive() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo").finish_non_exhaustive() |
| } |
| } |
| |
| assert_eq!("Foo { .. }", format!("{Foo:?}")); |
| assert_eq!("Foo { .. }", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_multiple_and_non_exhaustive() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo") |
| .field("bar", &true) |
| .field("baz", &format_args!("{}/{}", 10, 20)) |
| .finish_non_exhaustive() |
| } |
| } |
| |
| assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{Foo:?}")); |
| assert_eq!( |
| "Foo { |
| bar: true, |
| baz: 10/20, |
| .. |
| }", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested_non_exhaustive() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Foo") |
| .field("bar", &true) |
| .field("baz", &format_args!("{}/{}", 10, 20)) |
| .finish_non_exhaustive() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_struct("Bar") |
| .field("foo", &Foo) |
| .field("hello", &"world") |
| .finish_non_exhaustive() |
| } |
| } |
| |
| assert_eq!( |
| "Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", |
| format!("{Bar:?}") |
| ); |
| assert_eq!( |
| "Bar { |
| foo: Foo { |
| bar: true, |
| baz: 10/20, |
| .. |
| }, |
| hello: \"world\", |
| .. |
| }", |
| format!("{Bar:#?}") |
| ); |
| } |
| } |
| |
| mod debug_tuple { |
| use std::fmt; |
| |
| #[test] |
| fn test_empty() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_tuple("Foo").finish() |
| } |
| } |
| |
| assert_eq!("Foo", format!("{Foo:?}")); |
| assert_eq!("Foo", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_single() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_tuple("Foo").field(&true).finish() |
| } |
| } |
| |
| assert_eq!("Foo(true)", format!("{Foo:?}")); |
| assert_eq!( |
| "Foo( |
| true, |
| )", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_multiple() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| assert_eq!("Foo(true, 10/20)", format!("{Foo:?}")); |
| assert_eq!( |
| "Foo( |
| true, |
| 10/20, |
| )", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_tuple("Foo").field(&true).field(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_tuple("Bar").field(&Foo).field(&"world").finish() |
| } |
| } |
| |
| assert_eq!("Bar(Foo(true, 10/20), \"world\")", format!("{Bar:?}")); |
| assert_eq!( |
| "Bar( |
| Foo( |
| true, |
| 10/20, |
| ), |
| \"world\", |
| )", |
| format!("{Bar:#?}") |
| ); |
| } |
| } |
| |
| mod debug_map { |
| use std::fmt; |
| |
| #[test] |
| fn test_empty() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().finish() |
| } |
| } |
| |
| assert_eq!("{}", format!("{Foo:?}")); |
| assert_eq!("{}", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_single() { |
| struct Entry; |
| |
| impl fmt::Debug for Entry { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().entry(&"bar", &true).finish() |
| } |
| } |
| |
| struct KeyValue; |
| |
| impl fmt::Debug for KeyValue { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().key(&"bar").value(&true).finish() |
| } |
| } |
| |
| assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}")); |
| assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}")); |
| |
| assert_eq!("{\"bar\": true}", format!("{Entry:?}")); |
| assert_eq!( |
| "{ |
| \"bar\": true, |
| }", |
| format!("{Entry:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_multiple() { |
| struct Entry; |
| |
| impl fmt::Debug for Entry { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map() |
| .entry(&"bar", &true) |
| .entry(&10, &format_args!("{}/{}", 10, 20)) |
| .finish() |
| } |
| } |
| |
| struct KeyValue; |
| |
| impl fmt::Debug for KeyValue { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map() |
| .key(&"bar") |
| .value(&true) |
| .key(&10) |
| .value(&format_args!("{}/{}", 10, 20)) |
| .finish() |
| } |
| } |
| |
| assert_eq!(format!("{Entry:?}"), format!("{KeyValue:?}")); |
| assert_eq!(format!("{Entry:#?}"), format!("{KeyValue:#?}")); |
| |
| assert_eq!("{\"bar\": true, 10: 10/20}", format!("{Entry:?}")); |
| assert_eq!( |
| "{ |
| \"bar\": true, |
| 10: 10/20, |
| }", |
| format!("{Entry:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map() |
| .entry(&"bar", &true) |
| .entry(&10, &format_args!("{}/{}", 10, 20)) |
| .finish() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().entry(&"foo", &Foo).entry(&Foo, &"world").finish() |
| } |
| } |
| |
| assert_eq!( |
| "{\"foo\": {\"bar\": true, 10: 10/20}, \ |
| {\"bar\": true, 10: 10/20}: \"world\"}", |
| format!("{Bar:?}") |
| ); |
| assert_eq!( |
| "{ |
| \"foo\": { |
| \"bar\": true, |
| 10: 10/20, |
| }, |
| { |
| \"bar\": true, |
| 10: 10/20, |
| }: \"world\", |
| }", |
| format!("{Bar:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_entry_err() { |
| // Ensure errors in a map entry don't trigger panics (#65231) |
| use std::fmt::Write; |
| |
| struct ErrorFmt; |
| |
| impl fmt::Debug for ErrorFmt { |
| fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { |
| Err(fmt::Error) |
| } |
| } |
| |
| struct KeyValue<K, V>(usize, K, V); |
| |
| impl<K, V> fmt::Debug for KeyValue<K, V> |
| where |
| K: fmt::Debug, |
| V: fmt::Debug, |
| { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| let mut map = fmt.debug_map(); |
| |
| for _ in 0..self.0 { |
| map.entry(&self.1, &self.2); |
| } |
| |
| map.finish() |
| } |
| } |
| |
| let mut buf = String::new(); |
| |
| assert!(write!(&mut buf, "{:?}", KeyValue(1, ErrorFmt, "bar")).is_err()); |
| assert!(write!(&mut buf, "{:?}", KeyValue(1, "foo", ErrorFmt)).is_err()); |
| |
| assert!(write!(&mut buf, "{:?}", KeyValue(2, ErrorFmt, "bar")).is_err()); |
| assert!(write!(&mut buf, "{:?}", KeyValue(2, "foo", ErrorFmt)).is_err()); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_invalid_key_when_entry_is_incomplete() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().key(&"bar").key(&"invalid").finish() |
| } |
| } |
| |
| format!("{Foo:?}"); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_invalid_finish_incomplete_entry() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().key(&"bar").finish() |
| } |
| } |
| |
| format!("{Foo:?}"); |
| } |
| |
| #[test] |
| #[should_panic] |
| fn test_invalid_value_before_key() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_map().value(&"invalid").key(&"bar").finish() |
| } |
| } |
| |
| format!("{Foo:?}"); |
| } |
| } |
| |
| mod debug_set { |
| use std::fmt; |
| |
| #[test] |
| fn test_empty() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_set().finish() |
| } |
| } |
| |
| assert_eq!("{}", format!("{Foo:?}")); |
| assert_eq!("{}", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_single() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_set().entry(&true).finish() |
| } |
| } |
| |
| assert_eq!("{true}", format!("{Foo:?}")); |
| assert_eq!( |
| "{ |
| true, |
| }", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_multiple() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| assert_eq!("{true, 10/20}", format!("{Foo:?}")); |
| assert_eq!( |
| "{ |
| true, |
| 10/20, |
| }", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_set().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_set().entry(&Foo).entry(&"world").finish() |
| } |
| } |
| |
| assert_eq!("{{true, 10/20}, \"world\"}", format!("{Bar:?}")); |
| assert_eq!( |
| "{ |
| { |
| true, |
| 10/20, |
| }, |
| \"world\", |
| }", |
| format!("{Bar:#?}") |
| ); |
| } |
| } |
| |
| mod debug_list { |
| use std::fmt; |
| |
| #[test] |
| fn test_empty() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_list().finish() |
| } |
| } |
| |
| assert_eq!("[]", format!("{Foo:?}")); |
| assert_eq!("[]", format!("{Foo:#?}")); |
| } |
| |
| #[test] |
| fn test_single() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_list().entry(&true).finish() |
| } |
| } |
| |
| assert_eq!("[true]", format!("{Foo:?}")); |
| assert_eq!( |
| "[ |
| true, |
| ]", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_multiple() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| assert_eq!("[true, 10/20]", format!("{Foo:?}")); |
| assert_eq!( |
| "[ |
| true, |
| 10/20, |
| ]", |
| format!("{Foo:#?}") |
| ); |
| } |
| |
| #[test] |
| fn test_nested() { |
| struct Foo; |
| |
| impl fmt::Debug for Foo { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_list().entry(&true).entry(&format_args!("{}/{}", 10, 20)).finish() |
| } |
| } |
| |
| struct Bar; |
| |
| impl fmt::Debug for Bar { |
| fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
| fmt.debug_list().entry(&Foo).entry(&"world").finish() |
| } |
| } |
| |
| assert_eq!("[[true, 10/20], \"world\"]", format!("{Bar:?}")); |
| assert_eq!( |
| "[ |
| [ |
| true, |
| 10/20, |
| ], |
| \"world\", |
| ]", |
| format!("{Bar:#?}") |
| ); |
| } |
| } |
| |
| #[test] |
| fn test_formatting_parameters_are_forwarded() { |
| use std::collections::{BTreeMap, BTreeSet}; |
| #[derive(Debug)] |
| #[allow(dead_code)] |
| struct Foo { |
| bar: u32, |
| baz: u32, |
| } |
| let struct_ = Foo { bar: 1024, baz: 7 }; |
| let tuple = (1024, 7); |
| let list = [1024, 7]; |
| let mut map = BTreeMap::new(); |
| map.insert("bar", 1024); |
| map.insert("baz", 7); |
| let mut set = BTreeSet::new(); |
| set.insert(1024); |
| set.insert(7); |
| |
| assert_eq!(format!("{struct_:03?}"), "Foo { bar: 1024, baz: 007 }"); |
| assert_eq!(format!("{tuple:03?}"), "(1024, 007)"); |
| assert_eq!(format!("{list:03?}"), "[1024, 007]"); |
| assert_eq!(format!("{map:03?}"), r#"{"bar": 1024, "baz": 007}"#); |
| assert_eq!(format!("{set:03?}"), "{007, 1024}"); |
| assert_eq!( |
| format!("{struct_:#03?}"), |
| " |
| Foo { |
| bar: 1024, |
| baz: 007, |
| } |
| " |
| .trim() |
| ); |
| assert_eq!( |
| format!("{tuple:#03?}"), |
| " |
| ( |
| 1024, |
| 007, |
| ) |
| " |
| .trim() |
| ); |
| assert_eq!( |
| format!("{list:#03?}"), |
| " |
| [ |
| 1024, |
| 007, |
| ] |
| " |
| .trim() |
| ); |
| assert_eq!( |
| format!("{map:#03?}"), |
| r#" |
| { |
| "bar": 1024, |
| "baz": 007, |
| } |
| "# |
| .trim() |
| ); |
| assert_eq!( |
| format!("{set:#03?}"), |
| " |
| { |
| 007, |
| 1024, |
| } |
| " |
| .trim() |
| ); |
| } |