From 38576046b3f813dd6c7bb453d78f3605f8798d72 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Thu, 13 Feb 2014 06:41:34 +1100 Subject: [PATCH] Add some missing Show implementations in libstd --- src/librustdoc/clean.rs | 19 +++++++-- src/librustdoc/html/format.rs | 29 +++++++------- src/libstd/any.rs | 26 ++++++++++++ src/libstd/ascii.rs | 13 +++++- src/libstd/hashmap.rs | 75 +++++++++++++++++++++++++++++++++++ src/libstd/str.rs | 2 + src/libstd/unit.rs | 7 ++++ src/libstd/vec.rs | 42 ++++++++++++++++++++ 8 files changed, 193 insertions(+), 20 deletions(-) diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs index ca7f502a2e82d..eb0b4597e3007 100644 --- a/src/librustdoc/clean.rs +++ b/src/librustdoc/clean.rs @@ -342,7 +342,9 @@ impl Clean for ast::Method { _ => self.decl.inputs.slice_from(1) }; let decl = FnDecl { - inputs: inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.decl.output.clean()), cf: self.decl.cf.clean(), attrs: ~[] @@ -378,7 +380,9 @@ impl Clean for ast::TypeMethod { _ => self.decl.inputs.slice_from(1) }; let decl = FnDecl { - inputs: inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.decl.output.clean()), cf: self.decl.cf.clean(), attrs: ~[] @@ -472,16 +476,23 @@ impl Clean for ast::ClosureTy { #[deriving(Clone, Encodable, Decodable)] pub struct FnDecl { - inputs: ~[Argument], + inputs: Arguments, output: Type, cf: RetStyle, attrs: ~[Attribute] } +#[deriving(Clone, Encodable, Decodable)] +pub struct Arguments { + values: ~[Argument], +} + impl Clean for ast::FnDecl { fn clean(&self) -> FnDecl { FnDecl { - inputs: self.inputs.iter().map(|x| x.clean()).collect(), + inputs: Arguments { + values: self.inputs.iter().map(|x| x.clean()).collect(), + }, output: (self.output.clean()), cf: self.cf.clean(), attrs: ~[] diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 024d010f0b927..3e5afc399b962 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -404,6 +404,19 @@ impl fmt::Show for clean::Type { } } +impl fmt::Show for clean::Arguments { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for (i, input) in self.values.iter().enumerate() { + if i > 0 { if_ok!(write!(f.buf, ", ")); } + if input.name.len() > 0 { + if_ok!(write!(f.buf, "{}: ", input.name)); + } + if_ok!(write!(f.buf, "{}", input.type_)); + } + Ok(()) + } +} + impl fmt::Show for clean::FnDecl { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f.buf, "({args}){arrow, select, yes{ -> {ret}} other{}}", @@ -413,20 +426,6 @@ impl fmt::Show for clean::FnDecl { } } -impl fmt::Show for ~[clean::Argument] { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut args = ~""; - for (i, input) in self.iter().enumerate() { - if i > 0 { args.push_str(", "); } - if input.name.len() > 0 { - args.push_str(format!("{}: ", input.name)); - } - args.push_str(format!("{}", input.type_)); - } - f.buf.write(args.as_bytes()) - } -} - impl<'a> fmt::Show for Method<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let Method(selfty, d) = *self; @@ -448,7 +447,7 @@ impl<'a> fmt::Show for Method<'a> { args.push_str("&self"); } } - for (i, input) in d.inputs.iter().enumerate() { + for (i, input) in d.inputs.values.iter().enumerate() { if i > 0 || args.len() > 0 { args.push_str(", "); } if input.name.len() > 0 { args.push_str(format!("{}: ", input.name)); diff --git a/src/libstd/any.rs b/src/libstd/any.rs index 24da59341ccdd..3f14db14882ec 100644 --- a/src/libstd/any.rs +++ b/src/libstd/any.rs @@ -21,6 +21,7 @@ //! extension traits (`*Ext`) for the full details. use cast::transmute; +use fmt; use option::{Option, Some, None}; use result::{Result, Ok, Err}; use to_str::ToStr; @@ -158,6 +159,18 @@ impl<'a> ToStr for &'a Any { fn to_str(&self) -> ~str { ~"&Any" } } +impl fmt::Show for ~Any { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("~Any") + } +} + +impl<'a> fmt::Show for &'a Any { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("&Any") + } +} + #[cfg(test)] mod tests { use prelude::*; @@ -377,4 +390,17 @@ mod tests { assert!(a.move::<~Test>().is_err()); assert!(b.move::<~uint>().is_err()); } + + #[test] + fn test_show() { + let a = ~8u as ~Any; + let b = ~Test as ~Any; + assert_eq!(format!("{}", a), ~"~Any"); + assert_eq!(format!("{}", b), ~"~Any"); + + let a = &8u as &Any; + let b = &Test as &Any; + assert_eq!(format!("{}", a), ~"&Any"); + assert_eq!(format!("{}", b), ~"&Any"); + } } diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs index 7965127007c1c..651d364dd1b97 100644 --- a/src/libstd/ascii.rs +++ b/src/libstd/ascii.rs @@ -17,6 +17,7 @@ use str::StrSlice; use str::OwnedStr; use container::Container; use cast; +use fmt; use iter::Iterator; use vec::{ImmutableVector, MutableVector, Vector}; use to_bytes::IterBytes; @@ -134,6 +135,12 @@ impl ToStr for Ascii { } } +impl<'a> fmt::Show for Ascii { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + (self.chr as char).fmt(f) + } +} + /// Trait for converting into an ascii type. pub trait AsciiCast { /// Convert to an ascii type, fail on non-ASCII input. @@ -698,5 +705,9 @@ mod tests { assert_eq!(s, ~"t"); } - + #[test] + fn test_show() { + let c = Ascii { chr: 't' as u8 }; + assert_eq!(format!("{}", c), ~"t"); + } } diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index 953cc66a2cbcc..c49294a095f29 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -56,6 +56,7 @@ use container::{Container, Mutable, Map, MutableMap, Set, MutableSet}; use clone::Clone; use cmp::{Eq, Equiv}; use default::Default; +#[cfg(not(stage0))] use fmt; use hash::Hash; use iter; use iter::{Iterator, FromIterator, Extendable}; @@ -65,6 +66,7 @@ use num; use option::{None, Option, Some}; use rand::Rng; use rand; +#[cfg(not(stage0))] use result::{Ok, Err}; use vec::{ImmutableVector, MutableVector, OwnedVector, Items, MutItems}; use vec_ng; use vec_ng::Vec; @@ -595,6 +597,23 @@ impl Clone for HashMap { } } +#[cfg(not(stage0))] +impl fmt::Show for HashMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, r"\{")) + let mut first = true; + for (key, value) in self.iter() { + if first { + first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}: {}", *key, *value)); + } + write!(f.buf, r"\}") + } +} + /// HashMap iterator #[deriving(Clone)] pub struct Entries<'a, K, V> { @@ -857,6 +876,23 @@ impl Clone for HashSet { } } +#[cfg(not(stage0))] +impl fmt::Show for HashSet { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, r"\{")) + let mut first = true; + for x in self.iter() { + if first { + first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}", *x)); + } + write!(f.buf, r"\}") + } +} + impl FromIterator for HashSet { fn from_iterator>(iter: &mut T) -> HashSet { let (lower, _) = iter.size_hint(); @@ -890,6 +926,7 @@ pub type SetAlgebraItems<'a, T> = mod test_map { use prelude::*; use super::*; + use fmt; #[test] fn test_create_capacity_zero() { @@ -1121,6 +1158,30 @@ mod test_map { assert_eq!(map.find(&k), Some(&v)); } } + + struct ShowableStruct { + value: int, + } + + impl fmt::Show for ShowableStruct { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f.buf, r"s{}", self.value) + } + } + + #[test] + fn test_show() { + let mut table: HashMap = HashMap::new(); + let empty: HashMap = HashMap::new(); + + table.insert(3, ShowableStruct { value: 4 }); + table.insert(1, ShowableStruct { value: 2 }); + + let table_str = format!("{}", table); + + assert!(table_str == ~"{1: s2, 3: s4}" || table_str == ~"{3: s4, 1: s2}"); + assert_eq!(format!("{}", empty), ~"{}"); + } } #[cfg(test)] @@ -1346,4 +1407,18 @@ mod test_set { assert_eq!(s1, s2); } + + #[test] + fn test_show() { + let mut set: HashSet = HashSet::new(); + let empty: HashSet = HashSet::new(); + + set.insert(1); + set.insert(2); + + let set_str = format!("{}", set); + + assert!(set_str == ~"{1, 2}" || set_str == ~"{2, 1}"); + assert_eq!(format!("{}", empty), ~"{}"); + } } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index def2557d1abbb..0d263d94ccf0f 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -4163,6 +4163,7 @@ mod tests { assert_eq!(s.len(), 5); assert_eq!(s.as_slice(), "abcde"); assert_eq!(s.to_str(), ~"abcde"); + assert_eq!(format!("{}", s), ~"abcde"); assert!(s.lt(&Owned(~"bcdef"))); assert_eq!(Slice(""), Default::default()); @@ -4170,6 +4171,7 @@ mod tests { assert_eq!(o.len(), 5); assert_eq!(o.as_slice(), "abcde"); assert_eq!(o.to_str(), ~"abcde"); + assert_eq!(format!("{}", o), ~"abcde"); assert!(o.lt(&Slice("bcdef"))); assert_eq!(Owned(~""), Default::default()); diff --git a/src/libstd/unit.rs b/src/libstd/unit.rs index 3aa3e020500ea..b23dafbca6970 100644 --- a/src/libstd/unit.rs +++ b/src/libstd/unit.rs @@ -14,6 +14,7 @@ use default::Default; #[cfg(not(test))] use cmp::{Eq, Equal, Ord, Ordering, TotalEq, TotalOrd}; +use fmt; #[cfg(not(test))] impl Eq for () { @@ -46,3 +47,9 @@ impl Default for () { #[inline] fn default() -> () { () } } + +impl fmt::Show for () { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("()") + } +} diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 0f2e391ab6a5a..c67b19933d37f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -108,6 +108,7 @@ use container::{Container, Mutable}; use cmp::{Eq, TotalOrd, Ordering, Less, Equal, Greater}; use cmp; use default::Default; +#[cfg(not(stage0))] use fmt; use iter::*; use num::{Integer, CheckedAdd, Saturating, checked_next_power_of_two}; use option::{None, Option, Some}; @@ -115,6 +116,7 @@ use ptr::to_unsafe_ptr; use ptr; use ptr::RawPtr; use rt::global_heap::{malloc_raw, realloc_raw, exchange_free}; +#[cfg(not(stage0))] use result::{Ok, Err}; use mem; use mem::size_of; use kinds::marker; @@ -2641,6 +2643,30 @@ impl DeepClone for ~[A] { } } +#[cfg(not(stage0))] +impl<'a, T: fmt::Show> fmt::Show for &'a [T] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if_ok!(write!(f.buf, "[")); + let mut is_first = true; + for x in self.iter() { + if is_first { + is_first = false; + } else { + if_ok!(write!(f.buf, ", ")); + } + if_ok!(write!(f.buf, "{}", *x)) + } + write!(f.buf, "]") + } +} + +#[cfg(not(stage0))] +impl fmt::Show for ~[T] { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.as_slice().fmt(f) + } +} + // This works because every lifetime is a sub-lifetime of 'static impl<'a, A> Default for &'a [A] { fn default() -> &'a [A] { &'a [] } @@ -4050,6 +4076,22 @@ mod tests { assert_eq!(values, [1,4,3,2,5]); } + #[test] + fn test_show() { + macro_rules! test_show_vec( + ($x:expr, $x_str:expr) => ({ + let (x, x_str) = ($x, $x_str); + assert_eq!(format!("{}", x), x_str); + assert_eq!(format!("{}", x.as_slice()), x_str); + }) + ) + let empty: ~[int] = ~[]; + test_show_vec!(empty, ~"[]"); + test_show_vec!(~[1], ~"[1]"); + test_show_vec!(~[1, 2, 3], ~"[1, 2, 3]"); + test_show_vec!(~[~[], ~[1u], ~[1u, 1u]], ~"[[], [1], [1, 1]]"); + } + #[test] fn test_vec_default() { use default::Default;