Skip to content

Commit

Permalink
Conditional modifications
Browse files Browse the repository at this point in the history
  • Loading branch information
adamw committed Oct 19, 2016
1 parent d0388a6 commit 4519cb5
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ person
.modify(_.age).using(_ - 1)
````

**Modify conditionally:**

````scala
person.modify(_.address.street.name).setToIfDefined(Some("3 00 Ln."))
person.modify(_.address.street.name).setToIf(shouldChangeAddress)("3 00 Ln.")
````

**Modify several fields in one go:**

````scala
Expand Down Expand Up @@ -183,7 +190,7 @@ Read [the blog](http://www.warski.org/blog/2015/02/quicklens-modify-deeply-neste
Available in Maven Central:

````scala
val quicklens = "com.softwaremill.quicklens" %% "quicklens" % "1.4.7"
val quicklens = "com.softwaremill.quicklens" %% "quicklens" % "1.4.8"
````

Also available for [Scala.js](http://www.scala-js.org)!
2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import sbt._
object BuildSettings {
val buildSettings = Defaults.coreDefaultSettings ++ Seq (
organization := "com.softwaremill.quicklens",
version := "1.4.7",
version := "1.4.8",
scalaVersion := "2.11.8",
crossScalaVersions := Seq("2.11.8", "2.12.0-RC1"),
// Sonatype OSS deployment
Expand Down
19 changes: 19 additions & 0 deletions quicklens/src/main/scala/com/softwaremill/quicklens/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,30 @@ package object quicklens {
* @return A copy of the root object with the (deeply nested) field(s) modified.
*/
def using(mod: U => U): T = doModify(obj, mod)
/**
* Transform the value of the field(s) using the given function, if the condition is true. Otherwise, returns the
* original object unchanged.
* @return A copy of the root object with the (deeply nested) field(s) modified, if `condition` is true.
*/
def usingIf(condition: Boolean)(mod: U => U): T = if (condition) doModify(obj, mod) else obj
/**
* Set the value of the field(s) to a new value.
* @return A copy of the root object with the (deeply nested) field(s) set to the new value.
*/
def setTo(v: U): T = doModify(obj, _ => v)
/**
* Set the value of the field(s) to a new value, if it is defined. Otherwise, returns the original object
* unchanged.
* @return A copy of the root object with the (deeply nested) field(s) set to the new value, if it is defined.
*/
def setToIfDefined(v: Option[U]): T = v.fold(obj)(setTo)
/**
* Set the value of the field(s) to a new value, if the condition is true. Otherwise, returns the original object
* unchanged.
* @return A copy of the root object with the (deeply nested) field(s) set to the new value, if `condition` is
* true.
*/
def setToIf(condition: Boolean)(v: => U): T = if (condition) setTo(v) else obj
}

implicit class AbstractPathModifyPimp[T, U](f1: T => PathModify[T, U]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,12 @@ class ModifySimpleTest extends FlatSpec with Matchers {
it should "modify several fields" in {
modifyAll(b1)(_.b2, _.b3.each).using(duplicate) should be (b1dupdup)
}

it should "modify a case class field if the condition is true" in {
modify(a5)(_.name).usingIf(true)(duplicate) should be (a5dup)
}

it should "leave a case class unchanged if the condition is flase" in {
modify(a5)(_.name).usingIf(false)(duplicate) should be (a5)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,20 @@ class SetToSimpleTest extends FlatSpec with Matchers {
it should "set a new value of a single-nested case class field" in {
modify(a1)(_.a2.a3.a4.a5.name).setTo("mod") should be (a1mod)
}

it should "set a new value in a case class if the condition is true" in {
modify(a1)(_.a2.a3.a4.a5.name).setToIf(true)("mod") should be (a1mod)
}

it should "leave a case class unchanged if the condition is false" in {
modify(a1)(_.a2.a3.a4.a5.name).setToIf(false)("mod") should be (a1)
}

it should "set a new value in a case class if it is defined" in {
modify(a1)(_.a2.a3.a4.a5.name).setToIfDefined(Some("mod")) should be (a1mod)
}

it should "leave a case class unchanged if the value is not defined" in {
modify(a1)(_.a2.a3.a4.a5.name).setToIfDefined(None) should be (a1)
}
}

0 comments on commit 4519cb5

Please sign in to comment.