Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
27 changes: 9 additions & 18 deletions src/main/kotlin/ru/otus/homework/homework/Coffee.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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() + ", ваниль"
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<String>): 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'")
}
}
}
37 changes: 35 additions & 2 deletions src/main/kotlin/ru/otus/homework/homework/UserProfile.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

package ru.otus.homework.homework

import kotlin.properties.Delegates
import kotlin.reflect.KProperty

/**
* Профиль пользователя
*/
Expand Down Expand Up @@ -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)
}
}
}
Expand All @@ -50,4 +56,31 @@ private val emailRegex = Regex("^[A-Za-z](.*)([@])(.+)(\\.)(.+)")
/**
* Реализация простого [UserProfile].
*/
private class ProfileImplementation(override var fullName: String, override var email: String): UserProfile
private class ProfileImplementation(initFullName: String, initEmail: String): UserProfile{
override var fullName: String by NonEmptyStringDelegate(initFullName)
override var email: String by Delegates.vetoable<String>(initEmail){
property: KProperty<*>, oldValue, newValue -> emailRegex.matches(newValue)
}
}

private class ProfileWithLoggingImplementation(initFullName: String, initEmail: String): UserProfile.Logging{

private val log: MutableList<String> = 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<String> = log
}
4 changes: 2 additions & 2 deletions src/main/kotlin/ru/otus/homework/homework/processList.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ inline fun processList(list: List<Int>, action: (Int) -> Unit) {
}

fun skipThreeAndPrint(list: List<Int>) {
processList(list) {
if (it == 3) return
processList(list) lambda@{
if (it == 3) return@lambda
println("Processing $it")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}