Skip to content

Commit

Permalink
started introducing lenses
Browse files Browse the repository at this point in the history
  • Loading branch information
daviddenton committed Sep 11, 2017
1 parent 6ec8c14 commit b2574e6
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/test/scala/lens/LensExtractor.scala
@@ -0,0 +1,17 @@
package lens

trait LensExtractor[IN, OUT] extends Function[IN, OUT] {
/**
* Lens operation to get the value from the target
*
* @throws LensFailure if the value could not be retrieved from the target (missing/invalid etc)
*/
override def apply(target: IN): OUT

/**
* Lens operation to get the value from the target. Synonym for invoke(IN)
*
* @throws LensFailure if the value could not be retrieved from the target (missing/invalid etc)
*/
def extract(target: IN): OUT = apply(target)
}
18 changes: 18 additions & 0 deletions src/test/scala/lens/LensInjector.scala
@@ -0,0 +1,18 @@
package lens

trait LensInjector[IN, OUT] {
/**
* Lens operation to set the value into the target
*/
def apply[R <: IN](value: OUT, target: R): R

/**
* Lens operation to set the value into the target. Synomym for invoke(OUT, IN)
*/
def inject[R <: IN](value: OUT, target: R): R = apply(value, target)

/**
* Bind this Lens to a value, so we can set it into a target
*/
def of[R <: IN](value: OUT): (R) => R = apply(value, _)
}
55 changes: 55 additions & 0 deletions src/test/scala/lens/Lenses.scala
@@ -0,0 +1,55 @@
package lens

import io.fintrospect.parameters.ParamType

class LensGet[IN, MID, OUT] private(private val rootFn: (String, IN) => List[MID], private val fn: (MID) => OUT) {
def map[NEXT](nextFn: (OUT) => NEXT): LensGet[IN, MID, NEXT] = new LensGet[IN, MID, NEXT](rootFn, (i: MID) => nextFn(fn(i)))
}

object LensGet {
def apply[IN, OUT](rootFn: (String, IN) => List[OUT]): LensGet[IN, OUT, OUT] = new LensGet(rootFn, (i: OUT) => i)
}

class LensSet[IN, MID, OUT] private(private val rootFn: (String, List[MID], IN) => IN, private val fn: (OUT) => MID) {
def map[NEXT](nextFn: (NEXT) => OUT): LensSet[IN, MID, NEXT] = new LensSet[IN, MID, NEXT](rootFn, (value: NEXT) => fn(nextFn(value)))
}

object LensSet {
def apply[IN, OUT](rootFn: (String, List[OUT], IN) => IN): LensSet[IN, OUT, OUT] = new LensSet(rootFn, (i: OUT) => i)
}

///**
// * A Lens provides the uni-directional extraction of an entity from a target.
// */
// class Lens[IN, FINAL](val meta: Meta,
//private val get: (IN) =] FINAL) : LensExtractor[IN, FINAL], Iterable[Meta] {
//
// import shapeless.PolyDefns.=]
//
// override defiterator(): Iterator[Meta] = listOf(meta).iterator()
//
// override deftoString(): String = "${if (meta.required) "Required" else "Optional"} ${meta.location} '${meta.name}'"
//
// override definvoke(target: IN): FINAL = try {
// get(target)
//} catch (e: LensFailure) {
// throw e
//} catch (e: Exception) {
// throw LensFailure(Invalid(meta), cause = e)
//}
//}
//
// /**
// * A BiDiLens provides the bi-directional extraction of an entity from a target, or the insertion of an entity
// * into a target.
// */
// class BiDiLens[IN, FINAL](meta: Meta,
// get: (IN) =] FINAL,
// private val set: (FINAL, IN) =] IN) : LensInjector[IN, FINAL], Lens[IN, FINAL](meta, get) {
//
// @Suppress("UNCHECKED_CAST")
// override def[R : IN] invoke(value: FINAL, target: R): R = set(value, target) as R
//}


case class Meta(required: Boolean, location: String, paramMeta: ParamType, name: String, description: Option[String] = null)

0 comments on commit b2574e6

Please sign in to comment.