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

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

The newest version!
package org.specs2
package control

import Exceptions._

/**
 * 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
  /** 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): Either[T, R] = optionalValue.toLeft(right)
  /** option-like toRight */
  def toRight[L](left: L): Either[L, T] = optionalValue.toRight(left)
  /** to a list */
  def toList = optionalValue.toList
  
  /** @return execute the property */
  private def execute: Property[T] =
    if (!evaluated) copy(value, evaluated = true, evaluatedValue = value())
    else            this

  override def equals(other: Any) =
    tryCollect(other) { case o: Property[_] => o.optionalValue == optionalValue }

  override def hashCode =
    tryOr(optionalValue.hashCode)((_:Throwable).hashCode)

  override def toString = optionalValue.fold("")(_.toString)
}

/**
 * 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)
}

trait Properties {
  implicit def aProperty[T](t: T) = Property(t)
}

object Properties extends Properties




© 2015 - 2024 Weber Informatics LLC | Privacy Policy