1
1
package travelator.marketing
2
2
3
+ import com.natpryce.Failure
4
+ import com.natpryce.Result
5
+ import com.natpryce.Success
6
+ import com.natpryce.recover
7
+
3
8
fun Sequence<String>.toHighValueCustomerReport (
4
9
onErrorLine : (String ) -> Unit = {}
5
10
): Sequence <String > {
6
11
val valuableCustomers = this
7
12
.withoutHeader()
8
13
.map { line ->
9
- val customerData = line.toCustomerData()
10
- if (customerData == null )
14
+ line.toCustomerData().recover {
11
15
onErrorLine(line)
12
- customerData
16
+ null
17
+ }
13
18
}
14
19
.filterNotNull()
15
20
.filter { it.score >= 10 }
@@ -27,23 +32,33 @@ private fun List<CustomerData>.summarised(): String =
27
32
28
33
private fun Sequence<String>.withoutHeader () = drop(1 )
29
34
30
- internal fun String.toCustomerData (): CustomerData ? =
35
+ internal fun String.toCustomerData (): Result < CustomerData , ParseFailure > =
31
36
split(" \t " ).let { parts ->
32
37
if (parts.size < 4 )
33
- return null
38
+ return Failure ( NotEnoughFieldsFailure ( this ))
34
39
val score = parts[3 ].toIntOrNull() ? :
35
- return null
40
+ return Failure ( ScoreIsNotAnIntFailure ( this ))
36
41
val spend = if (parts.size == 4 ) 0.0 else parts[4 ].toDoubleOrNull() ? :
37
- return null
38
- CustomerData (
39
- id = parts[0 ],
40
- givenName = parts[1 ],
41
- familyName = parts[2 ],
42
- score = score,
43
- spend = spend
42
+ return Failure (SpendIsNotADoubleFailure (this ))
43
+ Success (
44
+ CustomerData (
45
+ id = parts[0 ],
46
+ givenName = parts[1 ],
47
+ familyName = parts[2 ],
48
+ score = score,
49
+ spend = spend
50
+ )
44
51
)
45
52
}
46
53
54
+ sealed class ParseFailure (open val line : String )
55
+ data class NotEnoughFieldsFailure (override val line : String ) :
56
+ ParseFailure (line)
57
+ data class ScoreIsNotAnIntFailure (override val line : String ) :
58
+ ParseFailure (line)
59
+ data class SpendIsNotADoubleFailure (override val line : String ) :
60
+ ParseFailure (line)
61
+
47
62
private val CustomerData .outputLine: String
48
63
get() = " $id \t $marketingName \t ${spend.toMoneyString()} "
49
64
0 commit comments