Skip to content

Commit 17cfa6f

Browse files
committed
implement FieldModifiers#modify(Function<String, String>)
1 parent 2f0aae4 commit 17cfa6f

File tree

7 files changed

+92
-25
lines changed

7 files changed

+92
-25
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
### Added
10+
- `FieldModifiers#modify(Function<String, String>)` to simply modify fields via functional interface
11+
12+
### Deprecated
13+
- `SimpleFieldModifier` interface
14+
- `FieldModifiers#lower` and `FieldModifiers#upper` methods
15+
816
## [3.6.0] - 2025-03-04
917
### Added
1018
- Configuration of maximum fields, maximum field size, and maximum record size via record handler
@@ -154,6 +162,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
154162

155163
- Initial release
156164

165+
[Unreleased]: https://github.com/osiegmar/FastCSV/compare/v3.6.0...HEAD
157166
[3.6.0]: https://github.com/osiegmar/FastCSV/compare/v3.5.0...v3.6.0
158167
[3.5.0]: https://github.com/osiegmar/FastCSV/compare/v3.4.0...v3.5.0
159168
[3.4.0]: https://github.com/osiegmar/FastCSV/compare/v3.3.1...v3.4.0

example/src/main/java/example/ExampleCsvReaderWithFieldModifier.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,27 @@ public static void main(final String[] args) {
2525

2626
System.out.println("Custom modifier (trim/lowercase on first record):");
2727
CsvReader.builder()
28-
.build(CsvRecordHandler.of(c -> c.fieldModifier(customModifier())), DATA)
28+
.build(CsvRecordHandler.of(c -> c.fieldModifier(new CustomModifier())), DATA)
2929
.forEach(System.out::println);
3030
}
3131

3232
private static FieldModifier combinedModifier() {
3333
return FieldModifiers.TRIM
34-
.andThen(FieldModifiers.lower(Locale.ENGLISH));
34+
.andThen(FieldModifiers.modify(field -> field.toLowerCase(Locale.ENGLISH)));
3535
}
3636

37-
private static FieldModifier customModifier() {
38-
return new FieldModifier() {
39-
@Override
40-
public String modify(final long startingLineNumber,
41-
final int fieldIdx,
42-
final boolean quoted,
43-
final String field) {
44-
return startingLineNumber == 1
45-
? field.trim().toLowerCase(Locale.ENGLISH)
46-
: field;
37+
private static class CustomModifier implements FieldModifier {
38+
39+
@Override
40+
public String modify(final long startingLineNumber, final int fieldIdx,
41+
final boolean quoted, final String field) {
42+
if (startingLineNumber == 1) {
43+
return field.trim().toLowerCase(Locale.ENGLISH);
4744
}
48-
};
45+
46+
return field;
47+
}
48+
4949
}
5050

5151
}

lib/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ plugins {
1313
}
1414

1515
group = "de.siegmar"
16-
version = "3.6.0"
16+
version = "3.7.0-SNAPSHOT"
1717

1818
project.base.archivesName = "fastcsv"
1919

lib/src/intTest/java/blackbox/reader/FieldModifierTest.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,45 @@ void strip() {
5656
.containsExactly("foo", "bar", "baz");
5757
}
5858

59+
@SuppressWarnings("removal")
60+
@Test
61+
void lower() {
62+
final CsvRecordHandler cbh = CsvRecordHandler.of(c -> c.fieldModifier(FieldModifiers.lower(Locale.ROOT)));
63+
64+
assertThat(crb.build(cbh, "FOO,BAR").stream())
65+
.singleElement(CsvRecordAssert.CSV_RECORD)
66+
.fields()
67+
.containsExactly("foo", "bar");
68+
}
69+
70+
@SuppressWarnings("removal")
71+
@Test
72+
void upper() {
73+
final CsvRecordHandler cbh = CsvRecordHandler.of(c -> c.fieldModifier(FieldModifiers.upper(Locale.ROOT)));
74+
75+
assertThat(crb.build(cbh, "foo,bar").stream())
76+
.singleElement(CsvRecordAssert.CSV_RECORD)
77+
.fields()
78+
.containsExactly("FOO", "BAR");
79+
}
80+
81+
@SuppressWarnings("removal")
82+
@Test
83+
void simple() {
84+
final CsvRecordHandler cbh = CsvRecordHandler.of(c -> c
85+
.fieldModifier((SimpleFieldModifier) field -> "<" + field + ">"));
86+
87+
assertThat(crb.build(cbh, "foo,bar").stream())
88+
.singleElement(CsvRecordAssert.CSV_RECORD)
89+
.fields()
90+
.containsExactly("<foo>", "<bar>");
91+
}
92+
5993
@Test
6094
void combination() {
6195
crb.commentStrategy(CommentStrategy.READ);
6296

63-
final SimpleFieldModifier addSpaces = field -> " " + field + " ";
64-
final FieldModifier modifier = addSpaces
65-
.andThen(FieldModifiers.upper(Locale.ROOT))
66-
.andThen(FieldModifiers.lower(Locale.ROOT))
97+
final FieldModifier modifier = FieldModifiers.modify(field -> field.toLowerCase(Locale.ROOT))
6798
.andThen(FieldModifiers.TRIM);
6899

69100
final CsvRecordHandler cbh = CsvRecordHandler.of(c -> c.fieldModifier(modifier));

lib/src/main/java/de/siegmar/fastcsv/reader/FieldModifier.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
/// a CSV record before storing them in the resulting object.
55
///
66
/// @see FieldModifiers
7-
/// @see SimpleFieldModifier
87
public interface FieldModifier {
98

109
/// Gets called for every single field (that is not a comment).

lib/src/main/java/de/siegmar/fastcsv/reader/FieldModifiers.java

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package de.siegmar.fastcsv.reader;
22

33
import java.util.Locale;
4+
import java.util.Objects;
5+
import java.util.function.Function;
46

57
/// Provides some common [FieldModifier] implementations.
68
///
79
/// Example usage:
810
/// ```
9-
/// FieldModifier modifier = FieldModifiers.TRIM.andThen(FieldModifiers.upper(Locale.ENGLISH));
11+
/// FieldModifier modifier = FieldModifiers.TRIM
12+
/// .andThen(FieldModifiers.modify(field -> field.toLowerCase(Locale.ENGLISH)));
1013
/// CsvRecordHandler handler = CsvRecordHandler.of(c -> c.fieldModifier(modifier));
1114
/// List<CsvRecord> records = CsvReader.builder()
1215
/// .build(handler, " foo , bar")
@@ -18,15 +21,15 @@
1821
public final class FieldModifiers {
1922

2023
/// Modifier that does not modify anything.
21-
public static final FieldModifier NOP = (SimpleFieldModifier) field -> field;
24+
public static final FieldModifier NOP = new FieldModifier() { };
2225

2326
/// Modifier that modifies the field value with [String#trim()].
2427
/// Comments are not modified.
25-
public static final FieldModifier TRIM = (SimpleFieldModifier) String::trim;
28+
public static final FieldModifier TRIM = modify(String::trim);
2629

2730
/// Modifier that modifies the field value with [String#strip()].
2831
/// Comments are not modified.
29-
public static final FieldModifier STRIP = (SimpleFieldModifier) String::strip;
32+
public static final FieldModifier STRIP = modify(String::strip);
3033

3134
private FieldModifiers() {
3235
// Utility class
@@ -37,17 +40,40 @@ private FieldModifiers() {
3740
///
3841
/// @param locale use the case transformation rules for this locale
3942
/// @return a new field modifier that converts the input to lower-case.
43+
/// @deprecated Use [#modify(Function)] instead.
44+
@Deprecated(since = "3.7.0", forRemoval = true)
4045
public static FieldModifier lower(final Locale locale) {
41-
return (SimpleFieldModifier) field -> field.toLowerCase(locale);
46+
return modify(field -> field.toLowerCase(locale));
4247
}
4348

4449
/// Builds modifier that modifies the field value with [String#toUpperCase(Locale)].
4550
/// Comments are not modified.
4651
///
4752
/// @param locale use the case transformation rules for this locale
4853
/// @return a new field modifier that converts the input to upper-case.
54+
/// @deprecated Use [#modify(Function)] instead.
55+
@Deprecated(since = "3.7.0", forRemoval = true)
4956
public static FieldModifier upper(final Locale locale) {
50-
return (SimpleFieldModifier) field -> field.toUpperCase(locale);
57+
return modify(field -> field.toUpperCase(locale));
58+
}
59+
60+
/// Builds a modifier that modifies the field value using the provided function.
61+
/// Comments are not modified.
62+
///
63+
/// @param function the function to modify the field value. The contract of
64+
/// [FieldModifier#modify(long, int, boolean, String)] applies:
65+
/// the value passed to the function is never `null` and the return value must not be `null`.
66+
/// @return a new field modifier that applies the function to the field value
67+
/// @throws NullPointerException if the function is `null`
68+
public static FieldModifier modify(final Function<? super String, String> function) {
69+
Objects.requireNonNull(function, "function must not be null");
70+
return new FieldModifier() {
71+
@Override
72+
public String modify(final long startingLineNumber, final int fieldIdx,
73+
final boolean quoted, final String field) {
74+
return function.apply(field);
75+
}
76+
};
5177
}
5278

5379
}

lib/src/main/java/de/siegmar/fastcsv/reader/SimpleFieldModifier.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
/// When implementing this interface, comments are ignored (not modified), by default.
66
///
77
/// @see FieldModifiers
8+
/// @deprecated Use [FieldModifiers#modify(java.util.function.Function)] instead.
9+
@Deprecated(since = "3.7.0", forRemoval = true)
810
@FunctionalInterface
911
public interface SimpleFieldModifier extends FieldModifier {
1012

0 commit comments

Comments
 (0)