All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.specs2.control.Property.scala Maven / Gradle / Ivy

There is a newer version: 3.7
Show newest version
package org.specs2
package control


/**
 * This class represents values which are evaluated lazily and which may even be missing.
 * 
 * It has Option-like function and can be also converted to an Either object
 */
case class Property[T](value: () => Option[T], evaluated: Boolean = false, evaluatedValue: Option[T] = None) {
  /** change the value */
  def updateValue(init: =>Option[T]) = new Property(value = () => init)
  /** change the value */
  def withValue(init: =>T) = Property(init)
  /** @return the option(value) */
  def optionalValue: Option[T] = execute.evaluatedValue
  /** alias for optionalValue */
  def toOption: Option[T] = optionalValue
  /** @return a value */
  def get: T = optionalValue.get
  /** alias for get */
  def apply(): T = get
  /** update the value */
  def update(newValue: =>T) = withValue(newValue)
  /** alial for update */
  def apply(newValue: =>T) = update(newValue)
  /** @return an iterator containing the value if present */
  def iterator = optionalValue.iterator
  /** return the property with the value being filtered according to a predicate */
  def filter(p: T => Boolean) = new Property(() => value().filter(p))
  /** option-like flatMap */
  def flatMap[U](f: T => Option[U]): Property[U] = new Property(() => optionalValue.flatMap(f))
  /** option-like foreach */
  def foreach(f: T => Unit): Unit = optionalValue.foreach(f)
  /** option-like getOrElse */
  def getOrElse[U >: T](other: U): U = optionalValue.getOrElse(other)
  /** option-like isDefined */
  def isDefined = optionalValue.isDefined
  /** option-like isEmpty */
  def isEmpty = optionalValue.isEmpty
  /** option-like map */
  def map[U](f: T => U): Property[U] = new Property(() => optionalValue.map(f(_)))
  /** option-like orElse */
  def orElse[U >: T](other: => Property[U]): Property[U] = new Property(() => optionalValue.orElse(other.optionalValue))
  /** option-like toLeft */
  def toLeft[R](right: R) = optionalValue.toLeft(right)
  /** option-like toRight */
  def toRight[L](left: L) = optionalValue.toRight(left)
  /** to a list */
  def toList = optionalValue.toList
  
  /** @return execute the property */
  private def execute: Property[T] = {
    if (!evaluated)
      copy(value, true, evaluatedValue = value())
    else 
      this
  }
  
  override def equals(other: Any) = {
    try {
      other match {
        case o: Property[_] => o.optionalValue == optionalValue
        case _ => false
      }
    } catch {
      case e: Exception => false
    }
  }
  override def hashCode =
    try {
      optionalValue.hashCode
    } catch {
      case e: Exception => e.hashCode
    }
  /** @return an Option-like representation */
  override def toString = try {
    optionalValue.toString
  } catch {
    case e: Exception => "Evaluation error " + e.getMessage
  }
}
/**
 * Companion object to create properties with possibly no initial value
 */
object Property {
  def apply[T](i: =>T) = new Property(() => Some(i))
  def apply[T]() = new Property[T](() => None)
}
private[specs2]
trait Properties {
  implicit def aProperty[T](t: T) = Property(t)
}
private[specs2]
object Properties extends Properties




© 2015 - 2024 Weber Informatics LLC | Privacy Policy