/// A piece is a portion of the format string which represents the next part
/// to emit. These are emitted as a stream by the `Parser` class.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Piece<'a> {
/// A literal string which should directly be emitted
String(&'a str),
}
/// Representation of an argument specification.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Argument<'a> {
/// Where to find this argument
pub position: Position,
}
/// Specification for the formatting of an argument in the format string.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub struct FormatSpec<'a> {
/// Optionally specified character to fill alignment with.
pub fill: Option<char>,
}
/// Enum describing where an argument for a format can be located.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Position {
/// The argument is implied to be located at an index
ArgumentImplicitlyIs(usize),
}
/// Enum of alignments which are supported.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Alignment {
/// The value will be aligned to the left.
AlignLeft,
/// Various flags which can be applied to format strings. The meaning of these
/// flags is defined by the formatters themselves.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Flag {
/// A `+` will be used to denote positive numbers.
FlagSignPlus,
/// A count is used for the precision and width parameters of an integer, and
/// can reference either an argument or a literal integer.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Count {
/// The count is specified explicitly.
CountIs(usize),
} else {
spec.ty = self.word();
let ty_span_end = self.cur.peek().map(|(pos, _)| *pos);
- let this = self;
- spec.ty_span = ty_span_start
- .and_then(|s| ty_span_end.map(|e| (s, e)))
- .map(|(start, end)| this.to_span_index(start).to(this.to_span_index(end)));
+ if !spec.ty.is_empty() {
+ spec.ty_span = ty_span_start
+ .and_then(|s| ty_span_end.map(|e| (s, e)))
+ .map(|(start, end)| self.to_span_index(start).to(self.to_span_index(end)));
+ }
}
spec
}
fn same(fmt: &'static str, p: &[Piece<'static>]) {
let parser = Parser::new(fmt, None, vec![], false);
- assert!(parser.collect::<Vec<Piece<'static>>>() == p);
+ assert_eq!(parser.collect::<Vec<Piece<'static>>>(), p);
}
fn fmtdflt() -> FormatSpec<'static> {
precision_span: None,
width_span: None,
ty: "",
+ ty_span: None,
};
}
#[test]
fn format_type() {
same(
- "{3:a}",
+ "{3:x}",
&[NextArgument(Argument {
position: ArgumentIs(3),
format: FormatSpec {
width: CountImplied,
precision_span: None,
width_span: None,
- ty: "a",
+ ty: "x",
+ ty_span: None,
},
})]);
}
precision_span: None,
width_span: None,
ty: "",
+ ty_span: None,
},
})]);
same(
precision_span: None,
width_span: None,
ty: "",
+ ty_span: None,
},
})]);
same(
precision_span: None,
width_span: None,
ty: "abcd",
+ ty_span: Some(InnerSpan::new(6, 10)),
},
})]);
}
use syntax_pos::{GLOBALS, Globals, edition};
GLOBALS.set(&Globals::new(edition::DEFAULT_EDITION), || {
same(
- "{:10s}",
+ "{:10x}",
&[NextArgument(Argument {
position: ArgumentImplicitlyIs(0),
format: FormatSpec {
width: CountIs(10),
precision_span: None,
width_span: None,
- ty: "s",
+ ty: "x",
+ ty_span: None,
},
})]);
same(
- "{:10$.10s}",
+ "{:10$.10x}",
&[NextArgument(Argument {
position: ArgumentImplicitlyIs(0),
format: FormatSpec {
width: CountIsParam(10),
precision_span: None,
width_span: Some(InnerSpan::new(3, 6)),
- ty: "s",
+ ty: "x",
+ ty_span: None,
},
})]);
same(
- "{:.*s}",
+ "{:.*x}",
&[NextArgument(Argument {
position: ArgumentImplicitlyIs(1),
format: FormatSpec {
width: CountImplied,
precision_span: Some(InnerSpan::new(3, 5)),
width_span: None,
- ty: "s",
+ ty: "x",
+ ty_span: None,
},
})]);
same(
- "{:.10$s}",
+ "{:.10$x}",
&[NextArgument(Argument {
position: ArgumentImplicitlyIs(0),
format: FormatSpec {
width: CountImplied,
precision_span: Some(InnerSpan::new(3, 7)),
width_span: None,
- ty: "s",
+ ty: "x",
+ ty_span: None,
},
})]);
same(
- "{:a$.b$s}",
+ "{:a$.b$?}",
&[NextArgument(Argument {
position: ArgumentImplicitlyIs(0),
format: FormatSpec {
width: CountIsName(Symbol::intern("a")),
precision_span: None,
width_span: None,
- ty: "s",
+ ty: "?",
+ ty_span: None,
},
})]);
});
precision_span: None,
width_span: None,
ty: "",
+ ty_span: None,
},
})]);
same(
precision_span: None,
width_span: None,
ty: "",
+ ty_span: None,
},
})]);
}
#[test]
fn format_mixture() {
same(
- "abcd {3:a} efg",
+ "abcd {3:x} efg",
&[
String("abcd "),
NextArgument(Argument {
width: CountImplied,
precision_span: None,
width_span: None,
- ty: "a",
+ ty: "x",
+ ty_span: None,
},
}),
String(" efg"),