-
Notifications
You must be signed in to change notification settings - Fork 448
/
optional.kt
55 lines (47 loc) · 2.14 KB
/
optional.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package arrow.optics.plugin.internals
import arrow.optics.plugin.OpticsProcessorOptions
internal fun OpticsProcessorOptions.generateOptionals(ele: ADT, target: OptionalTarget) =
Snippet(
`package` = ele.packageName,
name = ele.simpleName,
imports =
setOf("import arrow.core.left", "import arrow.core.right", "import arrow.core.toOption"),
content = processElement(ele, target.foci),
)
private fun OpticsProcessorOptions.processElement(ele: ADT, foci: List<Focus>): String =
foci.joinToString(separator = "\n") { focus ->
val targetClassName = when (focus) {
is NullableFocus -> focus.nonNullClassName
is OptionFocus -> focus.nestedClassName
is NonNullFocus -> return@joinToString ""
}
val sourceClassNameWithParams = "${ele.sourceClassName}${ele.angledTypeParameters}"
val firstLine = when {
ele.typeParameters.isEmpty() ->
"${ele.visibilityModifierName} $inlineText val ${ele.sourceClassName}.Companion.${focus.paramName}: $Optional<${ele.sourceClassName}, $targetClassName> $inlineText get()"
else ->
"${ele.visibilityModifierName} $inlineText fun ${ele.angledTypeParameters} ${ele.sourceClassName}.Companion.${focus.paramName}(): $Optional<$sourceClassNameWithParams, $targetClassName>"
}
fun getOrModifyF(toNullable: String = "") =
"{ ${ele.sourceName}: $sourceClassNameWithParams -> ${ele.sourceName}.${
focus.paramName.plusIfNotBlank(
prefix = "`",
postfix = "`",
)
}$toNullable?.right() ?: ${ele.sourceName}.left() }"
fun setF(fromNullable: String = "") =
"${ele.sourceName}.copy(${focus.paramName.plusIfNotBlank(prefix = "`", postfix = "`")} = value$fromNullable)"
val (getOrModify, set) =
when (focus) {
is NullableFocus -> Pair(getOrModifyF(), setF())
is OptionFocus -> Pair(getOrModifyF(".orNull()"), setF(".toOption()"))
is NonNullFocus -> return@joinToString ""
}
"""
|$firstLine = $Optional(
| getOrModify = $getOrModify,
| set = { ${ele.sourceName}: $sourceClassNameWithParams, value: $targetClassName -> $set }
|)
|
""".trimMargin()
}