diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8b7a9bf..daa7cc1 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Mon Oct 09 12:41:49 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists +zipStorePath=wrapper/dists \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt index c73f420..6fd495e 100644 --- a/src/main/kotlin/ru/otus/homework/homework/Coffee.kt +++ b/src/main/kotlin/ru/otus/homework/homework/Coffee.kt @@ -21,31 +21,22 @@ class SimpleCoffee : Coffee { } class MilkDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } + // Молоко стоти 50 копеек + override fun cost(): Int = coffee.cost() + 50 - override fun description(): String { - TODO("Not yet implemented") - } + override fun description(): String = coffee.description() + ", молоко" } class SugarDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } + // Сахар стоит 20 копеек + override fun cost(): Int = coffee.cost() + 20 - override fun description(): String { - TODO("Not yet implemented") - } + override fun description(): String = coffee.description() + ", сахар" } class VanillaDecorator(private val coffee: Coffee) : Coffee { - override fun cost(): Int { - TODO("Not yet implemented") - } + //Ваниль стоит 70 копеек + override fun cost(): Int = coffee.cost() + 70 - override fun description(): String { - TODO("Not yet implemented") - } + override fun description(): String = coffee.description() + ", ваниль" } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt b/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt index 568f368..99144e0 100644 --- a/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt +++ b/src/main/kotlin/ru/otus/homework/homework/NonEmptyStringDelegate.kt @@ -2,15 +2,84 @@ package ru.otus.homework.homework import kotlin.reflect.KProperty + + + + /** * Delegate that allows to set non-empty string value */ class NonEmptyStringDelegate() { - operator fun getValue(thisRef: Any?, property: KProperty<*>): String { - TODO("Implement `getValue` function") + private var string: String = "" + + constructor(stringValue: String): this() + { + string = stringValue } + operator fun getValue(thisRef: Any?, property: KProperty<*>): String = string + operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { - TODO("Implement `setValue` function") + if(newValue.isNotBlank()){ + string = newValue + } + } +} + +interface StringDelegate{ + + public operator fun getValue(thisRef: Any?, property: KProperty<*>): String + + public operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) +} + +class StringProperty(private var propertyValue: String): StringDelegate{ + override fun getValue(thisRef: Any?, property: KProperty<*>): String = propertyValue + + override fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { + propertyValue = newValue + } + +} + +abstract class StringDecorator(protected val stringDelegate: StringDelegate): StringDelegate{ + + override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = stringDelegate.getValue(thisRef, property) + + override operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String){ + stringDelegate.setValue(thisRef, property, newValue) + } +} + +class NonEmptyStringDecorator(stringDelegate: StringDelegate): StringDecorator(stringDelegate){ + + override operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String){ + if(newValue.isNotBlank()){ + super.stringDelegate.setValue(thisRef, property, newValue) + } + } +} + +class EmailStringDecorator(stringDelegate: StringDelegate): StringDecorator(stringDelegate) { + companion object{ + val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)") + } + + override operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String){ + if(newValue.isNotBlank() && emailRegex.matches(newValue)){ + super.stringDelegate.setValue(thisRef, property, newValue) + } + } +} + +class LoggingStringDecorator(stringDelegate: StringDelegate, private val log: MutableList): StringDecorator(stringDelegate){ + override operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String){ + val startValue: String = super.stringDelegate.getValue(thisRef, property) + super.stringDelegate.setValue(thisRef, property, newValue) + val finishValue = super.stringDelegate.getValue(thisRef, property) + + if(startValue != finishValue){ + log.add("Changing `${property.name}` from '$startValue' to '$finishValue'") + } } } \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt b/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt index f0fab82..5092830 100644 --- a/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt +++ b/src/main/kotlin/ru/otus/homework/homework/UserProfile.kt @@ -2,6 +2,9 @@ package ru.otus.homework.homework +import kotlin.properties.Delegates +import kotlin.reflect.KProperty + /** * Профиль пользователя */ @@ -37,7 +40,10 @@ interface UserProfile { * Creates user profile with logging */ fun createWithLogging(fullName: String, email: String): UserProfile.Logging { - TODO("Implement `createWithLogging` function") + require(fullName.isNotBlank()) { "Full name should not be empty" } + require(email.isNotBlank() && emailRegex.matches(email)) { "Invalid email" } + + return ProfileWithLoggingImplementation(fullName, email) } } } @@ -50,4 +56,31 @@ private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)") /** * Реализация простого [UserProfile]. */ -private class ProfileImplementation(override var fullName: String, override var email: String): UserProfile \ No newline at end of file +private class ProfileImplementation(initFullName: String, initEmail: String): UserProfile{ + override var fullName: String by NonEmptyStringDelegate(initFullName) + override var email: String by Delegates.vetoable(initEmail){ + property: KProperty<*>, oldValue, newValue -> emailRegex.matches(newValue) + } +} + +private class ProfileWithLoggingImplementation(initFullName: String, initEmail: String): UserProfile.Logging{ + + private val log: MutableList = mutableListOf() + + override var fullName: String by + LoggingStringDecorator( + NonEmptyStringDecorator( + StringProperty(initFullName) + ), + log + ) + + override var email: String by LoggingStringDecorator( + EmailStringDecorator( + StringProperty(initEmail) + ), + log + ) + + override fun getLog(): List = log +} \ No newline at end of file diff --git a/src/main/kotlin/ru/otus/homework/homework/processList.kt b/src/main/kotlin/ru/otus/homework/homework/processList.kt index 6d8ab43..79c8090 100644 --- a/src/main/kotlin/ru/otus/homework/homework/processList.kt +++ b/src/main/kotlin/ru/otus/homework/homework/processList.kt @@ -7,8 +7,8 @@ inline fun processList(list: List, action: (Int) -> Unit) { } fun skipThreeAndPrint(list: List) { - processList(list) { - if (it == 3) return + processList(list) lambda@{ + if (it == 3) return@lambda println("Processing $it") } } diff --git a/src/test/kotlin/ru/otus/homework/homework/ProcessListTest.kt b/src/test/kotlin/ru/otus/homework/homework/ProcessListTest.kt index c44a50e..83f7a57 100644 --- a/src/test/kotlin/ru/otus/homework/homework/ProcessListTest.kt +++ b/src/test/kotlin/ru/otus/homework/homework/ProcessListTest.kt @@ -13,7 +13,7 @@ class ProcessListTest { skipThreeAndPrint(listOf(1, 2, 3, 4)) - val expected = "Processing 1\nProcessing 2\nProcessing 4\n" + val expected = "Processing 1\r\nProcessing 2\r\nProcessing 4\r\n" assertEquals(expected, output.toString()) } }