let mut value_name = String::new();
for (line, line_number) in input.lines().map(|r| r.unwrap()).zip(1..) {
let line = line.trim();
- let tokens = StringScanner::new(&line, Syntax::Interactive, true)
+ let tokens = StringScanner::new(line, Syntax::Interactive, true)
.unwrapped()
.collect::<Vec<_>>();
match &tokens[0] {
let endian = EndianSettings::new(Endian::Big);
for (line, line_number) in input.lines().map(|r| r.unwrap()).zip(1..) {
let line = line.trim();
- let tokens = StringScanner::new(&line, Syntax::Interactive, true)
+ let tokens = StringScanner::new(line, Syntax::Interactive, true)
.unwrapped()
.collect::<Vec<_>>();
match &tokens[0] {
static F: LazyLock<StyleSet> = LazyLock::new(|| {
StyleSet::new(|p| NumberStyle::new("", "", p.decimal, None, p.leading_zero))
});
- &F.get(self)
+ F.get(self)
}
Type::Comma => {
static COMMA: LazyLock<StyleSet> = LazyLock::new(|| {
NumberStyle::new("", "", p.decimal, Some(!p.decimal), p.leading_zero)
})
});
- &COMMA.get(self)
+ COMMA.get(self)
}
Type::Dot => {
static DOT: LazyLock<StyleSet> = LazyLock::new(|| {
NumberStyle::new("", "", !p.decimal, Some(p.decimal), p.leading_zero)
})
});
- &DOT.get(self)
+ DOT.get(self)
}
Type::Dollar => {
static DOLLAR: LazyLock<StyleSet> = LazyLock::new(|| {
StyleSet::new(|p| NumberStyle::new("$", "", p.decimal, Some(!p.decimal), false))
});
- &DOLLAR.get(self)
+ DOLLAR.get(self)
}
Type::Pct => {
static PCT: LazyLock<StyleSet> = LazyLock::new(|| {
StyleSet::new(|p| NumberStyle::new("", "%", p.decimal, None, false))
});
- &PCT.get(self)
+ PCT.get(self)
}
Type::CC(cc) => self.ccs[cc].as_deref().unwrap_or(&DEFAULT),
Type::N
Self::new(format.type_(), format.w())
}
+ #[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
self.0.len()
}
Ok(settings.epoch.apply(year))
}
-fn parse_int<'a, T>(p: &mut StrParser<'_>) -> Result<T, ParseErrorKind>
+fn parse_int<T>(p: &mut StrParser<'_>) -> Result<T, ParseErrorKind>
where
T: FromStr,
{
type_: Type,
}
- impl<'a> DateTester<'a> {
+ impl DateTester<'_> {
fn visit(&self, extra: &str, mut expected: ExpectDate) {
let formatted = format!("{}{extra}", self.formatted);
if !self.template.is_empty() {
type_: Type,
}
- impl<'a> TimeTester<'a> {
+ impl TimeTester<'_> {
fn visit(&self, extra: &str, mut expected: f64, sign: Sign) {
let formatted = format!("{}{extra}", self.formatted);
if !self.template.is_empty() {
next.visit(&format!("{:02}", self.time.minutes), expected, sign);
}
'S' => {
- expected += self.time.seconds as f64;
+ expected += self.time.seconds;
next.visit(&format!("{}", self.time.seconds), expected, sign);
next.visit(&format!("{:02}", self.time.seconds), expected, sign);
}
.as_number()
.unwrap()
.unwrap();
- assert_eq!((parsed * 1000.0).round(), (expected as f64) * 1000.0);
+ assert_eq!((parsed * 1000.0).round(), expected * 1000.0);
}
}
(2, b'L', b'T') => Ok(Self::Lt),
(2, b'L', b'E') => Ok(Self::Le),
(2, b'N', b'E') => Ok(Self::Ne),
- (3, b'N', b'O') if b[2].to_ascii_uppercase() == b'T' => Ok(Self::Not),
+ (3, b'N', b'O') if b[2].eq_ignore_ascii_case(&b'T') => Ok(Self::Not),
(2, b'O', b'R') => Ok(Self::Or),
(2, b'T', b'O') => Ok(Self::To),
- (3, b'A', b'L') if b[2].to_ascii_uppercase() == b'L' => Ok(Self::All),
- (3, b'A', b'N') if b[2].to_ascii_uppercase() == b'D' => Ok(Self::And),
- (4, b'W', b'I')
- if b[2].to_ascii_uppercase() == b'T' && b[3].to_ascii_uppercase() == b'H' =>
- {
- Ok(Self::With)
- }
+ (3, b'A', b'L') if b[2].eq_ignore_ascii_case(&b'L') => Ok(Self::All),
+ (3, b'A', b'N') if b[2].eq_ignore_ascii_case(&b'D') => Ok(Self::And),
+ (4, b'W', b'I') if b[2..4].eq_ignore_ascii_case(b"TH") => Ok(Self::With),
_ => Err(()),
}
}
F: Fn(&Token) -> bool,
{
let mut iter = self.iter();
- if iter.next().map_or(false, |token| f(&token.token)) {
+ if iter.next().is_some_and(|token| f(&token.token)) {
Some(iter.remainder())
} else {
None
dst.push_back(src.pop_front().unwrap());
return;
};
- for ofs in 1.. {
- let token = &src[ofs];
+ for token in src.range(1..) {
if parser.push(&token.token, &self.file.buffer[token.pos.clone()], &|e| {
println!("{e:?}")
}) == ParseStatus::Complete
}
}
let call = parser.finish();
- if call.len() == 0 {
+ if call.is_empty() {
// False alarm: no macro to expand after all.
dst.push_back(src.pop_front().unwrap());
return;
///
/// This performs two different kinds of token merging:
///
- /// - String concatenation, where syntax like `"a" + "b"` is converted into a
+ /// - String concatenation, where syntax like `"a" + "b"` is converted into a
/// single string token. This is definitely needed because the parser relies
/// on it.
///
- /// - Negative number merging, where syntax like `-5` is converted from a pair
- /// of tokens (a dash and a positive number) into a single token (a negative
- /// number). This might not be needed anymore because the segmenter
- /// directly treats a dash followed by a number, with optional intervening
- /// white space, as a negative number. It's only needed if we want
- /// intervening comments to be allowed or for part of the negative number
- /// token to be produced by macro expansion.
+ /// - Negative number merging, where syntax like `-5` is converted from a pair
+ /// of tokens (a dash and a positive number) into a single token (a negative
+ /// number). This might not be needed anymore because the segmenter
+ /// directly treats a dash followed by a number, with optional intervening
+ /// white space, as a negative number. It's only needed if we want
+ /// intervening comments to be allowed or for part of the negative number
+ /// token to be produced by macro expansion.
pub fn merge<'a, F>(get_token: F) -> Result<Option<MergeResult>, Incomplete>
where
F: Fn(usize) -> Result<Option<&'a Token>, Incomplete>,
let Token::String(s) = get_token(i * 2).unwrap().unwrap() else {
unreachable!()
};
- output.push_str(&s);
+ output.push_str(s);
}
Ok(Some(MergeResult::Expand {
n: i * 2 + 1,
}
}
-impl<'a> Iterator for StringScanner<'a> {
+impl Iterator for StringScanner<'_> {
type Item = ScanToken;
fn next(&mut self) -> Option<Self::Item> {
fn check_scan(input: &str, mode: Syntax, expected: &[ScanToken]) {
let tokens = StringScanner::new(input, mode, false).collect::<Vec<_>>();
- if &tokens != expected {
+ if tokens != expected {
for token in &tokens {
match token {
ScanToken::Token(token) => {
//! ignored (e.g. [Segment::Spaces]) or trigger special behavior such as error
//! messages later in tokenization (e.g. [Segment::ExpectedQuote]).
+use std::cmp::Ordering;
+
#[cfg(doc)]
use crate::lex::token::Token;
'/' => {
if let (Some('*'), rest) = take(rest, eof)? {
let rest = skip_comment(rest, eof)?;
- return Ok(Some((rest, Segment::Comment)));
+ Ok(Some((rest, Segment::Comment)))
} else {
self.state.1 = Substate::empty();
- return Ok(Some((rest, Segment::Punct)));
+ Ok(Some((rest, Segment::Punct)))
}
}
'-' => {
None | Some(_) => (),
}
self.state.1 = Substate::empty();
- return Ok(Some((rest, Segment::Punct)));
+ Ok(Some((rest, Segment::Punct)))
}
'(' | ')' | '[' | ']' | '{' | '}' | ',' | '=' | ';' | ':' | '&' | '|' | '+' => {
self.state.1 = Substate::empty();
- return Ok(Some((rest, Segment::Punct)));
+ Ok(Some((rest, Segment::Punct)))
}
'*' => {
if self.state.1.contains(Substate::START_OF_COMMAND) {
input = take(input, eof).unwrap().1;
}
}
- fn check_repeat_command<'a>(&mut self, input: &'a str, eof: bool) -> Result<isize, Incomplete> {
- let input = input.strip_prefix(&['-', '+']).unwrap_or(input);
+ fn check_repeat_command(&mut self, input: &str, eof: bool) -> Result<isize, Incomplete> {
+ let input = input.strip_prefix(['-', '+']).unwrap_or(input);
let (id1, input) = self.next_id_in_command(input, eof)?;
if id_match("DO", id1) && id_match("REPEAT", self.next_id_in_command(input, eof)?.0) {
Ok(1)
return Ok(Some((rest, Segment::Newline)));
}
let rest = self.parse_full_line(input, eof)?;
- let direction = self.check_repeat_command(input, eof)?;
- if direction > 0 {
- if let Some(nest) = self.nest.checked_add(1) {
- self.nest = nest;
- } else {
- self.state.0 = State::DoRepeat4;
+ match self.check_repeat_command(input, eof)?.cmp(&0) {
+ Ordering::Greater => {
+ if let Some(nest) = self.nest.checked_add(1) {
+ self.nest = nest;
+ } else {
+ self.state.0 = State::DoRepeat4;
+ }
}
- } else if direction < 0 {
- self.nest -= 1;
- if self.nest == 0 {
- // Nesting level dropped to 0, so we've finished reading the `DO
- // REPEAT` body.
- self.state = (
- State::General,
- Substate::START_OF_COMMAND | Substate::START_OF_LINE,
- );
- return self.push_rest(input, eof);
+ Ordering::Less => {
+ self.nest -= 1;
+ if self.nest == 0 {
+ // Nesting level dropped to 0, so we've finished reading the `DO
+ // REPEAT` body.
+ self.state = (
+ State::General,
+ Substate::START_OF_COMMAND | Substate::START_OF_LINE,
+ );
+ return self.push_rest(input, eof);
+ }
}
+ Ordering::Equal => (),
}
- return Ok(Some((rest, Segment::DoRepeatCommand)));
+ Ok(Some((rest, Segment::DoRepeatCommand)))
}
fn parse_do_repeat_4<'a>(
&mut self,
}
Ok(Some((rest, segment)))
}
- fn find_enddefine<'a>(mut input: &'a str) -> Option<&'a str> {
+ fn find_enddefine(mut input: &str) -> Option<&str> {
loop {
input = skip_spaces_and_comments(input, true).unwrap();
let (Some(c), rest) = take(input, true).unwrap() else {
}
fn strip_prefix_ignore_ascii_case<'a>(line: &'a str, pattern: &str) -> Option<&'a str> {
- line.get(..pattern.len())
- .map(|prefix| {
- prefix
- .eq_ignore_ascii_case(pattern)
- .then(|| &line[pattern.len()..])
- })
- .flatten()
+ line.get(..pattern.len()).and_then(|prefix| {
+ prefix
+ .eq_ignore_ascii_case(pattern)
+ .then(|| &line[pattern.len()..])
+ })
}
#[cfg(test)]
use super::{Segment, Segmenter, Syntax};
-fn push_segment<'a>(
+fn push_segment(
segmenter: &mut Segmenter,
- input: &'a str,
+ input: &str,
one_byte: bool,
) -> Option<(usize, Segment)> {
if one_byte {
input = rest;
}
- if &segments != expect_segments {
+ if segments != expect_segments {
eprintln!("segments differ from expected:");
let difference = diff::slice(expect_segments, &segments);
for result in difference {
panic!();
}
- if &prompts != expect_prompts {
+ if prompts != expect_prompts {
eprintln!("prompts differ from expected:");
let difference = diff::slice(expect_prompts, &prompts);
for result in difference {
if let Some(input) = input.strip_suffix('\n') {
println!("running {one_byte_name} segmentation test without final newline...");
- let mut expect_segments: Vec<_> = expect_segments.iter().copied().collect();
+ let mut expect_segments: Vec<_> = expect_segments.to_vec();
assert_eq!(expect_segments.pop(), Some((Segment::Newline, "\n")));
while let Some((Segment::SeparateCommands | Segment::EndCommand, "")) =
expect_segments.last()
(Segment::EndCommand, "."),
(Segment::Newline, "\n"),
];
- for i in 1..N {
- expect_output.push((Segment::DoRepeatCommand, &do_repeat[i].trim_end()));
+ for (i, line) in do_repeat.iter().enumerate().take(N).skip(1) {
+ expect_output.push((Segment::DoRepeatCommand, do_repeat[i].trim_end()));
if i >= 255 {
expect_output.push((Segment::DoRepeatOverflow, ""));
}
expect_output.push((Segment::Newline, "\n"));
}
- for i in 0..254 {
- expect_output.push((Segment::DoRepeatCommand, &end_repeat[i].trim_end()));
+ for line in &end_repeat[..254] {
+ expect_output.push((Segment::DoRepeatCommand, line.trim_end()));
expect_output.push((Segment::Newline, "\n"));
}
let comments: Vec<String> = (0..(N - 254)).rev().map(|i| format!("/* {i}")).collect();
}
pub fn matches_keyword(&self, keyword: &str) -> bool {
- self.id().map_or(false, |id| id.matches_keyword(keyword))
+ self.id().is_some_and(|id| id.matches_keyword(keyword))
}
pub fn as_number(&self) -> Option<f64> {
}
}
Token::String(s) => {
- if s.chars().all(|c| is_printable(c)) {
+ if s.chars().all(is_printable) {
if s.contains('"') {
string_representation(s, '\'', f)
} else {
tokens
}
-fn try_unquote_string(input: &String, mode: Syntax) -> Option<String> {
+fn try_unquote_string(input: &str, mode: Syntax) -> Option<String> {
let mut scanner = StringScanner::new(input, mode, true);
let Some(ScanToken::Token(Token::String(unquoted))) = scanner.next() else {
return None;
};
let None = scanner.next() else { return None };
- return Some(unquoted);
+ Some(unquoted)
}
fn unquote_string(input: String, mode: Syntax) -> String {
#[derive(Clone)]
struct MacroTokens<'a>(&'a [MacroToken]);
-impl<'a> MacroTokens<'a> {
+impl MacroTokens<'_> {
fn is_empty(&self) -> bool {
self.0.is_empty()
}
None
}
fn macro_id(&self) -> Option<&Identifier> {
- self.0.get(0).map(|mt| mt.token.macro_id()).flatten()
+ self.0.first().and_then(|mt| mt.token.macro_id())
}
fn take_macro_id(&mut self) -> Option<&Identifier> {
- let result = self.0.get(0).map(|mt| mt.token.macro_id()).flatten();
+ let result = self.0.first().and_then(|mt| mt.token.macro_id());
if result.is_some() {
self.advance();
}
fn from_by(first: f64, last: f64, by: f64) -> Self {
if by > 0.0 && first <= last {
Self::Up { first, last, by }
- } else if by > 0.0 && first <= last {
+ } else if by < 0.0 && first <= last {
Self::Down { first, last, by }
} else {
Self::Empty
}
}
-impl<'a> Expander<'a> {
+impl Expander<'_> {
fn may_expand(&self) -> bool {
*self.expand.borrow()
}
args: None,
..*self
};
- let mut arg_tokens = MacroTokens(&arg);
+ let mut arg_tokens = MacroTokens(arg);
subexpander.expand(&mut arg_tokens, output);
self.stack = subexpander.stack;
self.stack.pop();
(e.error)(MacroError::InvalidBlanks(args[0].clone()));
return None;
};
- Some(std::iter::repeat(' ').take(n).collect())
+ Some(" ".repeat(n))
}
fn expand_concat(e: &mut Expander, args: Vec<String>) -> Option<String> {
fn expand_tail(e: &mut Expander, mut args: Vec<String>) -> Option<String> {
let arg = unquote_string(args.remove(0), e.mode);
let mut output = tokenize_string(&arg, e.mode, e.error);
- Some(
- output
- .pop()
- .map_or_else(|| String::new(), |tail| tail.syntax),
- )
+ Some(output.pop().map_or_else(String::new, |tail| tail.syntax))
}
fn expand_unquote(e: &mut Expander, mut args: Vec<String>) -> Option<String> {
/// quoted string is an important special case.
fn parse_function_arg(&mut self, input: &mut MacroTokens) -> Option<String> {
if let Some(macro_) = self.macro_ {
- match &input.0.get(0)?.token {
+ match &input.0.first()?.token {
Token::Id(id) if id.0.starts_with('!') => {
if let Some(param_idx) = macro_.find_parameter(id) {
input.advance();
..
}),
1,
- ) = (tokens.get(0), tokens.len())
+ ) = (tokens.first(), tokens.len())
else {
(self.error)(MacroError::BadNumericMacroExpression(s));
return None;
input.advance();
}
}
- return None;
+ None
}
fn expand_if(&mut self, orig_input: &mut MacroTokens, output: &mut Vec<MacroToken>) -> bool {
let mut input = orig_input.clone();
if is_macro_keyword(var_name)
|| self
.macro_
- .map(|m| m.find_parameter(var_name))
- .flatten()
+ .and_then(|m| m.find_parameter(var_name))
.is_some()
{
(self.error)(MacroError::BadMacroVarName {
}
}
(self.error)(MacroError::MissingDoEnd);
- return None;
+ None
}
fn expand_do(&mut self, orig_input: &mut MacroTokens, output: &mut Vec<MacroToken>) -> bool {
fn expand__(&mut self, input: &mut MacroTokens, output: &mut Vec<MacroToken>) {
// Recursive macro calls.
if self.may_expand() {
- if let Some(call) = Call::for_tokens(self.macros, &input.0, &self.error) {
+ if let Some(call) = Call::for_tokens(self.macros, input.0, &self.error) {
let vars = RefCell::new(BTreeMap::new());
let mut stack = take(&mut self.stack);
stack.push(Frame {
where
F: Fn(MacroError),
{
- let mut parser = Parser::new(macros, &tokens.get(0)?.token)?;
+ let mut parser = Parser::new(macros, &tokens.first()?.token)?;
for token in tokens[1..].iter().chain(&[MacroToken {
token: Token::End,
syntax: String::from(""),
return Some(parser.finish());
}
}
- return None;
+ None
}
pub fn expand<F>(
pub fn len(&self) -> usize {
self.0.n_tokens
}
+
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
}
let span = match (&a.span, &b.span) {
(None, None) => None,
(Some(r), None) | (None, Some(r)) => Some(r.clone()),
- (Some(ar), Some(br)) => {
- Some(min(ar.start, br.start).clone()..max(ar.end, br.end).clone())
- }
+ (Some(ar), Some(br)) => Some(min(ar.start, br.start)..max(ar.end, br.end)),
};
Some(Self {
file_name: a.file_name,
description,
} in &self.stack
{
- if !!location.is_empty() {
+ if !location.is_empty() {
write!(f, "{location}: ")?;
}
writeln!(f, "{description}")?;
}
fn string_needs_quoting(&self, s: &str) -> bool {
- s.bytes().find(|&b| self.byte_needs_quoting(b)).is_some()
+ s.bytes().any(|b| self.byte_needs_quoting(b))
}
}
}
}
-impl<'a> Display for CsvField<'a> {
+impl Display for CsvField<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if self.options.string_needs_quoting(self.text) {
let quote = self.options.quote as char;
fn start_item(&mut self) {
if self.n_items > 0 {
- write!(&mut self.file, "\n").unwrap();
+ writeln!(&mut self.file).unwrap();
}
self.n_items += 1;
}
}
Details::Table(pivot_table) => {
for layer in pivot_table.layers(true) {
- self.output_table_layer(&*pivot_table, &layer).unwrap();
+ self.output_table_layer(pivot_table, &layer).unwrap();
}
}
Details::PageBreak => {
self.start_item();
- write!(&mut self.file, "\n").unwrap();
+ writeln!(&mut self.file).unwrap();
}
Details::Text(text) => match text.type_ {
TextType::Syntax | TextType::PageTitle => (),
.continuation_text_at_bottom,
continuation: {
let text = table_properties.printing_properties.continuation_text;
- if text == "" {
+ if text.is_empty() {
None
} else {
Some(text)
}
}
-pub trait AsValueOptions {
- fn as_value_options(self) -> ValueOptions;
+pub trait IntoValueOptions {
+ fn into_value_options(self) -> ValueOptions;
}
-impl AsValueOptions for () {
- fn as_value_options(self) -> ValueOptions {
+impl IntoValueOptions for () {
+ fn into_value_options(self) -> ValueOptions {
ValueOptions::default()
}
}
-impl AsValueOptions for &PivotTable {
- fn as_value_options(self) -> ValueOptions {
+impl IntoValueOptions for &PivotTable {
+ fn into_value_options(self) -> ValueOptions {
self.value_options()
}
}
-impl AsValueOptions for &ValueOptions {
- fn as_value_options(self) -> ValueOptions {
+impl IntoValueOptions for &ValueOptions {
+ fn into_value_options(self) -> ValueOptions {
*self
}
}
-impl AsValueOptions for ValueOptions {
- fn as_value_options(self) -> ValueOptions {
+impl IntoValueOptions for ValueOptions {
+ fn into_value_options(self) -> ValueOptions {
self
}
}
impl PivotTable {
fn new(title: Box<Value>, look: Arc<Look>) -> Self {
- let mut this = Self::default();
- this.title = Some(title);
- this.look = look;
- this
+ Self {
+ title: Some(title),
+ look,
+ ..Self::default()
+ }
}
fn cell_index(&self, data_indexes: &[usize]) -> usize {
cell_index(data_indexes, self.dimensions.iter().map(|d| d.len()))
fn axis_dimensions(
&self,
axis: Axis3,
- ) -> impl Iterator<Item = &Dimension> + DoubleEndedIterator + ExactSizeIterator {
+ ) -> impl DoubleEndedIterator<Item = &Dimension> + ExactSizeIterator {
self.axes[axis]
.dimensions
.iter()
}
impl Footnote {
- pub fn display_marker<'a, 'b>(&'a self, options: impl AsValueOptions) -> DisplayMarker<'a> {
+ pub fn display_marker(&self, options: impl IntoValueOptions) -> DisplayMarker<'_> {
DisplayMarker {
footnote: self,
- options: options.as_value_options(),
+ options: options.into_value_options(),
}
}
- pub fn display_content<'a, 'b>(&'a self, options: impl AsValueOptions) -> DisplayValue<'a> {
+ pub fn display_content(&self, options: impl IntoValueOptions) -> DisplayValue<'_> {
self.content.display(options)
}
}
options: ValueOptions,
}
-impl<'a> Display for DisplayMarker<'a> {
+impl Display for DisplayMarker<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if let Some(marker) = &self.footnote.marker {
write!(f, "{}", marker.display(self.options).without_suffixes())
&self,
f: &mut std::fmt::Formatter<'_>,
template: &str,
- args: &Vec<Vec<Value>>,
+ args: &[Vec<Value>],
) -> std::fmt::Result {
let mut iter = template.as_bytes().iter();
while let Some(c) = iter.next() {
let Some(arg) = args.get(index.wrapping_sub(1)) else {
continue;
};
- if let Some(arg) = arg.get(0) {
+ if let Some(arg) = arg.first() {
write!(f, "{}", arg.display(self.options))?;
}
}
Ok(())
}
- fn inner_template<'c>(
+ fn inner_template(
&self,
f: &mut std::fmt::Formatter<'_>,
template: &[u8],
}
}
-impl<'a, 'b> Display for DisplayValue<'a> {
+impl Display for DisplayValue<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.inner {
ValueInner::Number {
{
todo!();
}*/
- f.write_str(&local)
+ f.write_str(local)
}
ValueInner::Template { args, local, .. } => self.template(f, &local, args),
// Returns an object that will format this value, including subscripts and
// superscripts and footnotes. `options` controls whether variable and
// value labels are included.
- pub fn display<'a, 'b>(&'a self, options: impl AsValueOptions) -> DisplayValue<'a> {
- let display = self.inner.display(options.as_value_options());
+ pub fn display(&self, options: impl IntoValueOptions) -> DisplayValue<'_> {
+ let display = self.inner.display(options.into_value_options());
match &self.styling {
- Some(styling) => display.with_styling(&*styling),
+ Some(styling) => display.with_styling(styling),
None => display,
}
}
impl ValueInner {
pub fn is_empty(&self) -> bool {
- match self {
- Self::Empty => true,
- _ => false,
- }
+ matches!(self, Self::Empty)
}
fn show(&self) -> Option<Show> {
match self {
impl ValueInner {
// Returns an object that will format this value. Settings on `options`
// control whether variable and value labels are included.
- pub fn display<'a>(&'a self, options: impl AsValueOptions) -> DisplayValue<'a> {
- let options = options.as_value_options();
+ pub fn display(&self, options: impl IntoValueOptions) -> DisplayValue<'_> {
+ let options = options.into_value_options();
let (show_value, show_label) = if let Some(value_label) = self.value_label() {
interpret_show(
|| Settings::global().show_values,
(true, None)
};
DisplayValue {
- inner: &self,
+ inner: self,
markup: false,
subscripts: &[],
footnotes: &[],
};
use super::{
- Area, AsValueOptions, Axis2, Axis3, Border, BorderStyle, BoxBorder, Color, Coord2, Dimension,
- Footnote, PivotTable, Rect2, RowColBorder, Stroke, Value,
+ Area, Axis2, Axis3, Border, BorderStyle, BoxBorder, Color, Coord2, Dimension, Footnote,
+ IntoValueOptions, PivotTable, Rect2, RowColBorder, Stroke, Value,
};
/// All of the combinations of dimensions along an axis.
fn iter(&self) -> AxisEnumerationIter {
AxisEnumerationIter {
- enumeration: &self,
+ enumeration: self,
position: 0,
}
}
Coord2::new(0, 0),
self.look.areas.clone(),
self.borders(false),
- self.as_value_options(),
+ self.into_value_options(),
);
for (y, row) in rows.enumerate() {
table.put(
stub,
self.look.areas.clone(),
self.borders(printing),
- self.as_value_options(),
+ self.into_value_options(),
);
for h in [Axis2::X, Axis2::Y] {
Some(self.create_aux_table3(Area::Caption, [self.caption.as_ref()?.clone()].into_iter()))
}
- pub fn output_footnotes<'a>(&self, footnotes: &[Arc<Footnote>]) -> Option<Table> {
+ pub fn output_footnotes(&self, footnotes: &[Arc<Footnote>]) -> Option<Table> {
self.create_aux_table_if_nonempty(
Area::Footer,
- footnotes.into_iter().map(|f| {
+ footnotes.iter().map(|f| {
Box::new(Value::new_user_text(format!(
"{}. {}",
f.display_marker(self),
groups: SmallVec<[Arc<Group>; 4]>,
}
-impl<'a> HeadingColumn<'a> {
+impl HeadingColumn<'_> {
pub fn get(&self, y: usize, height: usize) -> Option<&Value> {
if y + 1 == height {
Some(&self.leaf.name)
markup: false,
font: style.font_name.string.clone(),
fg: {
- let fg = style.text_color.into();
+ let fg = style.text_color;
[fg, fg]
},
bg: [bg, bg],
// `rules[Y]` is horizontal rules.
let rules = EnumMap::from_fn(|axis| {
(0..=n[axis])
- .map(|z| measure_rule(&*device, &*table, axis, z))
+ .map(|z| measure_rule(device, &*table, axis, z))
.collect::<Vec<_>>()
});
for cell in table.cells().filter(|cell| cell.col_span() > 1) {
let rect = cell.rect();
- let w = device.measure_cell_width(&DrawCell::new(cell.inner(), &*table));
+ let w = device.measure_cell_width(&DrawCell::new(cell.inner(), &table));
for i in 0..2 {
distribute_spanned_width(
w[i],
let rect = cell.rect();
let w = joined_width(&cp_x, rect[X].clone());
- let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &*table), w);
+ let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &table), w);
let row = &mut unspanned_rows[cell.coord.y()];
if h > *row {
for cell in table.cells().filter(|cell| cell.row_span() > 1) {
let rect = cell.rect();
let w = joined_width(&cp_x, rect[X].clone());
- let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &*table), w);
+ let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &table), w);
distribute_spanned_width(
h,
&unspanned_rows[rect[Y].clone()],
let cp_y = Self::use_row_widths(&rows, &rules[Y]);
// Measure headers. If they are "too big", get rid of them.
- let mut h = table.h.clone();
+ let mut h = table.h;
for (axis, cp) in [(X, cp_x.as_slice()), (Y, cp_y.as_slice())] {
let header_width = axis_width(cp, 0..table.h[axis]);
let max_cell_width = (table.h[axis]..n[axis])
min + extra
})
.collect::<Vec<_>>();
- return Self::use_row_widths(&rows_mid, rules);
+ Self::use_row_widths(&rows_mid, rules)
}
/// Returns the width of `extent` along `axis`.
// An edge is cut off if it was cut off in `self` or if we're trimming
// pixels off that side of the page and there are no headers.
- let mut is_edge_cutoff = self.is_edge_cutoff.clone();
+ let mut is_edge_cutoff = self.is_edge_cutoff;
is_edge_cutoff[a][0] = h[a] == 0 && (pixel0 > 0 || (z0 == 0 && self.is_edge_cutoff[a][0]));
is_edge_cutoff[a][1] = pixel1 > 0 || (z1 == self.n[a] && self.is_edge_cutoff[a][1]);
let cell = self.get_cell(d);
if cell.rect[a].end > z1
|| (cell.rect[a].end == z1 && pixel1 > 0)
- && overflows
- .get(&s.coord_to_subpage(cell.rect.top_left()))
- .is_none()
+ && overflows.contains_key(&s.coord_to_subpage(cell.rect.top_left()))
{
let mut overflow = self.overflows.get(&d).cloned().unwrap_or_default();
overflow[a][1] +=
if rect[a].end > z0 && rect[a].start < z1 {
overflows
.entry(s.coord_to_subpage(rect.top_left()))
- .or_insert(overflow.clone());
+ .or_insert(*overflow);
}
}
let alternate_row =
usize::checked_sub(cell.rect[Y].start, self.h[Y]).is_some_and(|row| row % 2 == 1);
- let draw_cell = DrawCell::new(cell.content.inner(), &*self.table);
+ let draw_cell = DrawCell::new(cell.content.inner(), &self.table);
let valign_offset = match draw_cell.style.cell_style.vert_align {
VertAlign::Top => 0,
VertAlign::Middle => self.extra_height(device, &bb, &draw_cell) / 2,
pub content: &'a Content,
}
-impl<'a> CellRef<'a> {
+impl CellRef<'_> {
pub fn inner(&self) -> &CellInner {
self.content.inner()
}
impl Content {
pub fn inner(&self) -> &CellInner {
match self {
- Content::Value(cell_inner) => &cell_inner,
+ Content::Value(cell_inner) => cell_inner,
Content::Join(cell) => &cell.inner,
}
}
}
pub fn is_top_left(&self, coord: Coord2) -> bool {
- self.joined_rect().map_or(true, |r| coord == r.top_left())
+ self.joined_rect().is_none_or(|r| coord == r.top_left())
}
pub fn span(&self, axis: Axis2) -> usize {
y: usize,
}
-impl<'a> Iterator for XIter<'a> {
+impl Iterator for XIter<'_> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
lines: Vec<TextLine>,
}
+impl Default for TextRenderer {
+ fn default() -> Self {
+ Self::new()
+ }
+}
+
impl TextRenderer {
pub fn new() -> Self {
let width = 80;
});
impl PivotTable {
- pub fn display<'a>(&'a self) -> DisplayPivotTable<'a> {
+ pub fn display(&self) -> DisplayPivotTable<'_> {
DisplayPivotTable::new(self)
}
}
}
}
-impl<'a> Display for DisplayPivotTable<'a> {
+impl Display for DisplayPivotTable<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for line in TextRenderer::new().render(self.pt) {
- write!(f, "{}\n", line)?;
+ writeln!(f, "{}", line)?;
}
Ok(())
}
}
}
-fn new_line_breaks<'a>(
- text: &'a str,
+fn new_line_breaks(
+ text: &str,
width: usize,
-) -> LineBreaks<'a, impl Iterator<Item = (usize, BreakOpportunity)> + Clone + 'a> {
+) -> LineBreaks<'_, impl Iterator<Item = (usize, BreakOpportunity)> + Clone + '_> {
LineBreaks {
text,
max_width: width,
Details::Message(_diagnostic) => todo!(),
Details::PageBreak => (),
Details::Table(pivot_table) => {
- for line in self.renderer.render(&pivot_table) {
+ for line in self.renderer.render(pivot_table) {
writeln!(self.file, "{}", line.str()).unwrap();
}
}
use enum_iterator::Sequence;
use std::{
borrow::Cow,
+ cmp::Ordering,
fmt::{Debug, Display},
ops::Range,
};
/// the current width, extends the line with spaces. If `x` is shorter than
/// the current width, removes trailing characters.
pub fn resize(&mut self, x: usize) {
- if x > self.width {
- self.string.extend((self.width..x).map(|_| ' '));
- } else if x < self.width {
- let pos = self.find_pos(x);
- self.string.truncate(pos.offsets.start);
- if x > pos.offsets.start {
- self.string.extend((pos.offsets.start..x).map(|_| '?'));
+ match x.cmp(&self.width) {
+ Ordering::Greater => self.string.extend((self.width..x).map(|_| ' ')),
+ Ordering::Less => {
+ let pos = self.find_pos(x);
+ self.string.truncate(pos.offsets.start);
+ if x > pos.offsets.start {
+ self.string.extend((pos.offsets.start..x).map(|_| '?'));
+ }
}
+ Ordering::Equal => return,
}
self.width = x;
}
}
}
-impl<'a> Iterator for Widths<'a> {
+impl Iterator for Widths<'_> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
return Some(0);
}
- while let Some((index, c)) = iter.next() {
+ for (index, c) in iter {
if c.width().is_some_and(|width| width > 0) {
self.s = &self.s[index..];
return Some(w);
}
}
- self.s = iter.as_str();
+ self.s = "";
Some(w)
}
}
let layout_code: [u8; 4] = read_bytes(r)?;
let endian = Endian::identify_u32(2, layout_code)
.or_else(|| Endian::identify_u32(2, layout_code))
- .ok_or_else(|| Error::NotASystemFile)?;
+ .ok_or(Error::NotASystemFile)?;
let layout_code = endian.parse(layout_code);
let nominal_case_size: u32 = endian.parse(read_bytes(r)?);