Skip to content

Commit

Permalink
Add support for starting suffix numbers
Browse files Browse the repository at this point in the history
This commit now allows split to pass split/numeric.sh
  • Loading branch information
andrewbaptist authored and sylvestre committed Oct 5, 2022
1 parent e523a56 commit ddc8609
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 120 deletions.
71 changes: 58 additions & 13 deletions src/uu/split/src/filenames.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use crate::number::DynamicWidthNumber;
use crate::number::FixedWidthNumber;
use crate::number::Number;
use uucore::error::{UResult, USimpleError};

/// The format to use for suffixes in the filename for each output chunk.
#[derive(Clone, Copy)]
Expand Down Expand Up @@ -119,19 +120,28 @@ impl<'a> FilenameIterator<'a> {
additional_suffix: &'a str,
suffix_length: usize,
suffix_type: SuffixType,
) -> FilenameIterator<'a> {
suffix_start: usize,
) -> UResult<FilenameIterator<'a>> {
let radix = suffix_type.radix();
let number = if suffix_length == 0 {
Number::DynamicWidth(DynamicWidthNumber::new(radix))
Number::DynamicWidth(DynamicWidthNumber::new(radix, suffix_start))
} else {
Number::FixedWidth(FixedWidthNumber::new(radix, suffix_length))
Number::FixedWidth(
FixedWidthNumber::new(radix, suffix_length, suffix_start).map_err(|_| {
USimpleError::new(
1,
"numerical suffix start value is too large for the suffix length",
)
})?,
)
};
FilenameIterator {

Ok(FilenameIterator {
prefix,
additional_suffix,
number,
first_iteration: true,
}
})
}
}

Expand Down Expand Up @@ -161,51 +171,86 @@ mod tests {

#[test]
fn test_filename_iterator_alphabetic_fixed_width() {
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Alphabetic);
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Alphabetic, 0).unwrap();
assert_eq!(it.next().unwrap(), "chunk_aa.txt");
assert_eq!(it.next().unwrap(), "chunk_ab.txt");
assert_eq!(it.next().unwrap(), "chunk_ac.txt");

let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Alphabetic);
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Alphabetic, 0).unwrap();
assert_eq!(it.nth(26 * 26 - 1).unwrap(), "chunk_zz.txt");
assert_eq!(it.next(), None);
}

#[test]
fn test_filename_iterator_numeric_fixed_width() {
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Decimal);
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Decimal, 0).unwrap();
assert_eq!(it.next().unwrap(), "chunk_00.txt");
assert_eq!(it.next().unwrap(), "chunk_01.txt");
assert_eq!(it.next().unwrap(), "chunk_02.txt");

let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Decimal);
let mut it = FilenameIterator::new("chunk_", ".txt", 2, SuffixType::Decimal, 0).unwrap();
assert_eq!(it.nth(10 * 10 - 1).unwrap(), "chunk_99.txt");
assert_eq!(it.next(), None);
}

#[test]
fn test_filename_iterator_alphabetic_dynamic_width() {
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Alphabetic);
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Alphabetic, 0).unwrap();
assert_eq!(it.next().unwrap(), "chunk_aa.txt");
assert_eq!(it.next().unwrap(), "chunk_ab.txt");
assert_eq!(it.next().unwrap(), "chunk_ac.txt");

let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Alphabetic);
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Alphabetic, 0).unwrap();
assert_eq!(it.nth(26 * 25 - 1).unwrap(), "chunk_yz.txt");
assert_eq!(it.next().unwrap(), "chunk_zaaa.txt");
assert_eq!(it.next().unwrap(), "chunk_zaab.txt");
}

#[test]
fn test_filename_iterator_numeric_dynamic_width() {
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Decimal);
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Decimal, 0).unwrap();
assert_eq!(it.next().unwrap(), "chunk_00.txt");
assert_eq!(it.next().unwrap(), "chunk_01.txt");
assert_eq!(it.next().unwrap(), "chunk_02.txt");

let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Decimal);
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Decimal, 0).unwrap();
assert_eq!(it.nth(10 * 9 - 1).unwrap(), "chunk_89.txt");
assert_eq!(it.next().unwrap(), "chunk_9000.txt");
assert_eq!(it.next().unwrap(), "chunk_9001.txt");
}

#[test]
fn test_filename_iterator_numeric_suffix_decimal() {
let mut it = FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Decimal, 5).unwrap();
assert_eq!(it.next().unwrap(), "chunk_05.txt");
assert_eq!(it.next().unwrap(), "chunk_06.txt");
assert_eq!(it.next().unwrap(), "chunk_07.txt");
}

#[test]
fn test_filename_iterator_numeric_suffix_hex() {
let mut it =
FilenameIterator::new("chunk_", ".txt", 0, SuffixType::Hexadecimal, 9).unwrap();
assert_eq!(it.next().unwrap(), "chunk_09.txt");
assert_eq!(it.next().unwrap(), "chunk_0a.txt");
assert_eq!(it.next().unwrap(), "chunk_0b.txt");
}

#[test]
fn test_filename_iterator_numeric_suffix_err() {
let mut it = FilenameIterator::new("chunk_", ".txt", 3, SuffixType::Decimal, 999).unwrap();
assert_eq!(it.next().unwrap(), "chunk_999.txt");
assert!(it.next().is_none());

let it = FilenameIterator::new("chunk_", ".txt", 3, SuffixType::Decimal, 1000);
assert!(it.is_err());

let mut it =
FilenameIterator::new("chunk_", ".txt", 3, SuffixType::Hexadecimal, 0xfff).unwrap();
assert_eq!(it.next().unwrap(), "chunk_fff.txt");
assert!(it.next().is_none());

let it = FilenameIterator::new("chunk_", ".txt", 3, SuffixType::Hexadecimal, 0x1000);
assert!(it.is_err());
}
}
Loading

0 comments on commit ddc8609

Please sign in to comment.