Remove Monocle dependency (#121)

* Replace Monocle with local SimpleLens implementation

* [domain] SimpleLensTest avoid short variables and remove field imports
This commit is contained in:
Paul Campbell 2019-07-24 09:40:56 +01:00 committed by GitHub
parent ad0585e9a9
commit cad152379e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 113 additions and 34 deletions

View file

@ -16,6 +16,7 @@ The format is based on [[https://keepachangelog.com/en/1.0.0/][Keep a Changelog]
** Changed ** Changed
- Replace cats-effect with zio (#117) - Replace cats-effect with zio (#117)
- Replace Monocle with local SimpleLens implementation (#121)
** Dependencies ** Dependencies

View file

@ -38,12 +38,6 @@ val testDependencies = Seq(
"org.scalamock" %% "scalamock" % "4.3.0" % Test "org.scalamock" %% "scalamock" % "4.3.0" % Test
) )
) )
val domainDependencies = Seq(
libraryDependencies ++= Seq(
"com.github.julien-truffaut" %% "monocle-core" % "1.6.0",
"com.github.julien-truffaut" %% "monocle-macro" % "1.6.0"
)
)
val commandLineParsing = Seq( val commandLineParsing = Seq(
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"com.github.scopt" %% "scopt" % "4.0.0-RC2" "com.github.scopt" %% "scopt" % "4.0.0-RC2"
@ -122,6 +116,5 @@ lazy val console = (project in file("console"))
lazy val domain = (project in file("domain")) lazy val domain = (project in file("domain"))
.settings(commonSettings) .settings(commonSettings)
.settings(domainDependencies)
.settings(assemblyJarName in assembly := "domain.jar") .settings(assemblyJarName in assembly := "domain.jar")
.settings(testDependencies) .settings(testDependencies)

View file

@ -1,7 +1,6 @@
package net.kemitix.thorp.core package net.kemitix.thorp.core
import monocle.Lens import net.kemitix.thorp.domain.SimpleLens
import monocle.macros.GenLens
case class ConfigOptions( case class ConfigOptions(
options: List[ConfigOption] = List() options: List[ConfigOption] = List()
@ -25,6 +24,7 @@ case class ConfigOptions(
} }
object ConfigOptions { object ConfigOptions {
val options: Lens[ConfigOptions, List[ConfigOption]] = val options: SimpleLens[ConfigOptions, List[ConfigOption]] =
GenLens[ConfigOptions](_.options) SimpleLens[ConfigOptions, List[ConfigOption]](_.options,
c => a => c.copy(options = a))
} }

View file

@ -1,7 +1,6 @@
package net.kemitix.thorp.core package net.kemitix.thorp.core
import monocle.Lens import net.kemitix.thorp.domain.SimpleLens
import monocle.macros.GenLens
final case class Counters( final case class Counters(
uploaded: Int = 0, uploaded: Int = 0,
@ -11,8 +10,12 @@ final case class Counters(
) )
object Counters { object Counters {
val uploaded: Lens[Counters, Int] = GenLens[Counters](_.uploaded) val uploaded: SimpleLens[Counters, Int] =
val deleted: Lens[Counters, Int] = GenLens[Counters](_.deleted) SimpleLens[Counters, Int](_.uploaded, b => a => b.copy(uploaded = a))
val copied: Lens[Counters, Int] = GenLens[Counters](_.copied) val deleted: SimpleLens[Counters, Int] =
val errors: Lens[Counters, Int] = GenLens[Counters](_.errors) SimpleLens[Counters, Int](_.deleted, b => a => b.copy(deleted = a))
val copied: SimpleLens[Counters, Int] =
SimpleLens[Counters, Int](_.copied, b => a => b.copy(copied = a))
val errors: SimpleLens[Counters, Int] =
SimpleLens[Counters, Int](_.errors, b => a => b.copy(errors = a))
} }

View file

@ -1,7 +1,6 @@
package net.kemitix.thorp.core package net.kemitix.thorp.core
import net.kemitix.thorp.console._ import net.kemitix.thorp.console._
//import net.kemitix.thorp.console.MyConsole._
import net.kemitix.thorp.domain.StorageQueueEvent.{ import net.kemitix.thorp.domain.StorageQueueEvent.{
CopyQueueEvent, CopyQueueEvent,
DeleteQueueEvent, DeleteQueueEvent,

View file

@ -1,8 +1,5 @@
package net.kemitix.thorp.domain package net.kemitix.thorp.domain
import monocle.Lens
import monocle.macros.GenLens
final case class Config( final case class Config(
bucket: Bucket = Bucket(""), bucket: Bucket = Bucket(""),
prefix: RemoteKey = RemoteKey(""), prefix: RemoteKey = RemoteKey(""),
@ -13,10 +10,16 @@ final case class Config(
) )
object Config { object Config {
val sources: Lens[Config, Sources] = GenLens[Config](_.sources) val sources: SimpleLens[Config, Sources] =
val bucket: Lens[Config, Bucket] = GenLens[Config](_.bucket) SimpleLens[Config, Sources](_.sources, b => a => b.copy(sources = a))
val prefix: Lens[Config, RemoteKey] = GenLens[Config](_.prefix) val bucket: SimpleLens[Config, Bucket] =
val filters: Lens[Config, List[Filter]] = GenLens[Config](_.filters) SimpleLens[Config, Bucket](_.bucket, b => a => b.copy(bucket = a))
val debug: Lens[Config, Boolean] = GenLens[Config](_.debug) val prefix: SimpleLens[Config, RemoteKey] =
val batchMode: Lens[Config, Boolean] = GenLens[Config](_.batchMode) SimpleLens[Config, RemoteKey](_.prefix, b => a => b.copy(prefix = a))
val filters: SimpleLens[Config, List[Filter]] =
SimpleLens[Config, List[Filter]](_.filters, b => a => b.copy(filters = a))
val debug: SimpleLens[Config, Boolean] =
SimpleLens[Config, Boolean](_.debug, b => a => b.copy(debug = a))
val batchMode: SimpleLens[Config, Boolean] =
SimpleLens[Config, Boolean](_.batchMode, b => a => b.copy(batchMode = a))
} }

View file

@ -3,9 +3,6 @@ package net.kemitix.thorp.domain
import java.io.File import java.io.File
import java.nio.file.Path import java.nio.file.Path
import monocle.Lens
import monocle.macros.GenLens
final case class LocalFile( final case class LocalFile(
file: File, file: File,
source: File, source: File,
@ -41,5 +38,7 @@ object LocalFile {
pathToKey(resolvedPath)) pathToKey(resolvedPath))
} }
val remoteKey: Lens[LocalFile, RemoteKey] = GenLens[LocalFile](_.remoteKey) val remoteKey: SimpleLens[LocalFile, RemoteKey] =
SimpleLens[LocalFile, RemoteKey](_.remoteKey,
b => a => b.copy(remoteKey = a))
} }

View file

@ -3,8 +3,6 @@ package net.kemitix.thorp.domain
import java.io.File import java.io.File
import java.nio.file.{Path, Paths} import java.nio.file.{Path, Paths}
import monocle.macros.GenLens
final case class RemoteKey( final case class RemoteKey(
key: String key: String
) { ) {
@ -39,5 +37,6 @@ final case class RemoteKey(
} }
object RemoteKey { object RemoteKey {
val key = GenLens[RemoteKey](_.key) val key: SimpleLens[RemoteKey, String] =
SimpleLens[RemoteKey, String](_.key, b => a => b.copy(key = a))
} }

View file

@ -0,0 +1,18 @@
package net.kemitix.thorp.domain
case class SimpleLens[A, B](field: A => B, update: A => B => A) {
def composeLens[C](other: SimpleLens[B, C]): SimpleLens[A, C] =
SimpleLens[A, C](
a => other.field(field(a)),
a => c => update(a)(other.update(field(a))(c))
)
def ^|->[C](other: SimpleLens[B, C]): SimpleLens[A, C] = composeLens(other)
def set(b: B)(a: A): A = update(a)(b)
def get(a: A): B = field(a)
def modify(f: B => B)(a: A): A = update(a)(f(field(a)))
}

View file

@ -0,0 +1,64 @@
package net.kemitix.thorp.domain
import org.scalatest.FreeSpec
class SimpleLensTest extends FreeSpec {
"lens" - {
val subject = Subject(0, "s")
"modify" in {
val expected = Subject(1, "s")
val result = Subject.anIntLens.modify(_ + 1)(subject)
assertResult(expected)(result)
}
"get" in {
val expected = "s"
val result = Subject.aStringLens.get(subject)
assertResult(expected)(result)
}
"set" in {
val expected = Subject(0, "k")
val result = Subject.aStringLens.set("k")(subject)
assertResult(expected)(result)
}
}
"lens composed" - {
val wrapper = Wrapper(1, Subject(2, "x"))
val subjectStringLens = Wrapper.aSubjectLens ^|-> Subject.aStringLens
"modify" in {
val expected = Wrapper(1, Subject(2, "X"))
val result = subjectStringLens.modify(_.toUpperCase)(wrapper)
assertResult(expected)(result)
}
"get" in {
val expected = "x"
val result = subjectStringLens.get(wrapper)
assertResult(expected)(result)
}
"set" in {
val expected = Wrapper(1, Subject(2, "k"))
val result = subjectStringLens.set("k")(wrapper)
assertResult(expected)(result)
}
}
case class Subject(anInt: Int, aString: String)
object Subject {
val anIntLens: SimpleLens[Subject, Int] =
SimpleLens[Subject, Int](_.anInt, subject => i => subject.copy(anInt = i))
val aStringLens: SimpleLens[Subject, String] =
SimpleLens[Subject, String](_.aString,
subject => str => subject.copy(aString = str))
}
case class Wrapper(anInt: Int, aSubject: Subject)
object Wrapper {
val anIntLens: SimpleLens[Wrapper, Int] =
SimpleLens[Wrapper, Int](_.anInt, wrapper => i => wrapper.copy(anInt = i))
val aSubjectLens: SimpleLens[Wrapper, Subject] =
SimpleLens[Wrapper, Subject](
_.aSubject,
wrapper => subject => wrapper.copy(aSubject = subject))
}
}