Skip to content

Commit

Permalink
Center alignment for fmt
Browse files Browse the repository at this point in the history
Use '^' to specify center alignment in format strings.

fmt!( "[{:^5s}]", "Hi" ) -> "[ Hi  ]"
fmt!( "[{:^5s}]", "H" )  -> "[  H  ]"
fmt!( "[{:^5d}]", 1i )   -> "[  1  ]"
fmt!( "[{:^5d}]", -1i )  -> "[ -1  ]"
fmt!( "[{:^6d}]", 1i )   -> "[  1   ]"
fmt!( "[{:^6d}]", -1i )  -> "[  -1  ]"

If the padding is odd then the padding on the right will be one
character longer than the padding on the left.

Tuples squashed
  • Loading branch information
wickerwaka committed Sep 4, 2014
1 parent 6d8b5c9 commit 2bc4a5e
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 9 deletions.
23 changes: 16 additions & 7 deletions src/libcore/fmt/mod.rs
Expand Up @@ -461,19 +461,28 @@ impl<'a> Formatter<'a> {
use char::Char;
let align = match self.align {
rt::AlignUnknown => default,
rt::AlignLeft | rt::AlignRight => self.align
_ => self.align
};
if align == rt::AlignLeft {
try!(f(self));
}

let (pre_pad, post_pad) = match align {
rt::AlignLeft => (0u, padding),
rt::AlignRight | rt::AlignUnknown => (padding, 0u),
rt::AlignCenter => (padding / 2, (padding + 1) / 2),
};

let mut fill = [0u8, ..4];
let len = self.fill.encode_utf8(fill).unwrap_or(0);
for _ in range(0, padding) {

for _ in range(0, pre_pad) {
try!(self.buf.write(fill.slice_to(len)));
}
if align == rt::AlignRight {
try!(f(self));

try!(f(self));

for _ in range(0, post_pad) {
try!(self.buf.write(fill.slice_to(len)));
}

Ok(())
}

Expand Down
2 changes: 2 additions & 0 deletions src/libcore/fmt/rt.rs
Expand Up @@ -43,6 +43,8 @@ pub enum Alignment {
AlignLeft,
/// Indication that contents should be right-aligned.
AlignRight,
/// Indication that contents should be center-aligned.
AlignCenter,
/// No alignment was requested.
AlignUnknown,
}
Expand Down
6 changes: 5 additions & 1 deletion src/libfmt_macros/lib.rs
Expand Up @@ -81,6 +81,8 @@ pub enum Alignment {
AlignLeft,
/// The value will be aligned to the right.
AlignRight,
/// The value will be aligned in the center.
AlignCenter,
/// The value will take on a default alignment.
AlignUnknown,
}
Expand Down Expand Up @@ -279,7 +281,7 @@ impl<'a> Parser<'a> {
match self.cur.clone().next() {
Some((_, c)) => {
match self.cur.clone().skip(1).next() {
Some((_, '>')) | Some((_, '<')) => {
Some((_, '>')) | Some((_, '<')) | Some((_, '^')) => {
spec.fill = Some(c);
self.cur.next();
}
Expand All @@ -293,6 +295,8 @@ impl<'a> Parser<'a> {
spec.align = AlignLeft;
} else if self.consume('>') {
spec.align = AlignRight;
} else if self.consume('^') {
spec.align = AlignCenter;
}
// Sign flags
if self.consume('+') {
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/fmt.rs
Expand Up @@ -333,7 +333,7 @@ argument := integer | identifier
format_spec := [[fill]align][sign]['#'][0][width]['.' precision][type]
fill := character
align := '<' | '>'
align := '<' | '^' | '>'
sign := '+' | '-'
width := count
precision := count | '*'
Expand All @@ -357,6 +357,7 @@ parameter. This indicates that if the value being formatted is smaller than
are specified by `fill`, and the alignment can be one of two options:
* `<` - the argument is left-aligned in `width` columns
* `^` - the argument is center-aligned in `width` columns
* `>` - the argument is right-aligned in `width` columns
### Sign/#/0
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/ext/format.rs
Expand Up @@ -430,6 +430,9 @@ impl<'a, 'b> Context<'a, 'b> {
parse::AlignRight => {
self.ecx.path_global(sp, self.rtpath("AlignRight"))
}
parse::AlignCenter => {
self.ecx.path_global(sp, self.rtpath("AlignCenter"))
}
parse::AlignUnknown => {
self.ecx.path_global(sp, self.rtpath("AlignUnknown"))
}
Expand Down
5 changes: 5 additions & 0 deletions src/test/run-pass/ifmt.rs
Expand Up @@ -90,11 +90,16 @@ pub fn main() {
t!(format!("{:4s}", "a"), "a ");
t!(format!("{:>4s}", "a"), " a");
t!(format!("{:<4s}", "a"), "a ");
t!(format!("{:^5s}", "a"), " a ");
t!(format!("{:^5s}", "aa"), " aa ");
t!(format!("{:^4s}", "a"), " a ");
t!(format!("{:^4s}", "aa"), " aa ");
t!(format!("{:.4s}", "a"), "a");
t!(format!("{:4.4s}", "a"), "a ");
t!(format!("{:4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
t!(format!("{:<4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
t!(format!("{:>4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
t!(format!("{:^4.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
t!(format!("{:>10.4s}", "aaaaaaaaaaaaaaaaaa"), "aaaa");
t!(format!("{:2.4s}", "aaaaa"), "aaaa");
t!(format!("{:2.4s}", "aaaa"), "aaaa");
Expand Down

5 comments on commit 2bc4a5e

@bors
Copy link
Contributor

@bors bors commented on 2bc4a5e Sep 4, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from alexcrichton
at wickerwaka@2bc4a5e

@bors
Copy link
Contributor

@bors bors commented on 2bc4a5e Sep 4, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging wickerwaka/rust/fmt-center = 2bc4a5e into auto

@bors
Copy link
Contributor

@bors bors commented on 2bc4a5e Sep 4, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wickerwaka/rust/fmt-center = 2bc4a5e merged ok, testing candidate = 4a5a9c5

@bors
Copy link
Contributor

@bors bors commented on 2bc4a5e Sep 4, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 4a5a9c5

Please sign in to comment.