
com.twitter.jaqen.ntuple.NTuple.scala Maven / Gradle / Ivy
The newest version!
package com.twitter.jaqen.ntuple
import scala.language.experimental.macros
import NTupleMacros._
/**
* A tuple where fields can be accessed by name
*
* @author Julien Le Dem
*/
trait NTuple[T <: NTuple[T]] {
/**
* returns the field named 'key' with the proper type
* if key does not exist, a compilation error will occur
* @param key a literal or a Symbol
* example:
*
* val tuple = t('a -> 1, 'b -> "2")
* tuple('a)
* => 1 (of type Int)
* tuple('b)
* => "2" (of type String)
*
*/
def get(key: Any) = macro applyImp[T]
/** @see get */
def apply(key: Any) = macro applyImp[T]
/**
* adds a pair key -> value to the tuple
* if key already exists, a compilation error will occur
* key must be a literal or a symbol.
* example:
* val tuple = t('a -> 1, 'b -> 2)
* tuple + ('c -> 3)
* => t('a -> 1, 'b -> 2, 'c -> 3)
*
*/
def add(pair: (Any, Any)) = macro plusImpl[T]
/** @see add */
def +(pair: (Any, Any)) = macro plusImpl[T]
/**
* concats another NTuple to this one
* if a key is defined in both tuples a compilation error will occur
*
* val tuple1 = t('a -> 1, 'b -> 2)
* val tuple2 = t('c -> 3, 'd -> 4)
* tuple1 ++ tuple2
* => t('a -> 1, 'b -> 2, 'c -> 3, 'd -> 4)
*
*/
def concat[T2 <: NTuple[T2]](t: T2) = macro plusplusImpl[T,T2]
/** @see concat */
def ++[T2 <: NTuple[T2]](t: T2) = macro plusplusImpl[T,T2]
/**
* removes a key from the tuple
* if key does not exist, a compilation error will occur
*
* val tuple = t('a -> 1, 'b -> 2)
* tuple - 'a
* => t('b -> 2)
*
*/
def remove(key: Any) = macro minusImpl[T]
/** @see remove */
def -(key: Any) = macro minusImpl[T]
/**
* takes a key -> value pair and replaces the existing key with the given value
* if key does not exist, a compilation error will occur
* example:
*
* val tuple = t('a -> 1, 'b -> 2)
* tuple -+ ('a -> 3)
* => t('a -> 3, 'b -> 2)
*
*/
def replace(pair: (Any, Any)) = macro replaceImpl[T]
/** @see replace */
def -+(pair: (Any, Any)) = macro replaceImpl[T]
/**
* prefixes all the key names with the given prefix.
* useful to concatenate 2 tuples
* example:
*
* t('a -> 1, 'b -> 2).prefix("t")
* => t('ta -> 1, 'tb -> 2)
*
*/
def prefix(prefix: String) = macro prefixImpl[T]
/**
* takes a pair (inputs -> output) and a function
* inputs: a tuple of the keys of the values to pass to the function
* output: the key to set with the result
* @returns the resulting tuple with the output key set with the result of the function
* example:
*
* val tuple = t('a -> 1, 'b -> 2)
* tuple.map(('a, 'b) -> 'c) { (a: Int, b: Int) => a + b }
* => t('a -> 1, 'b -> 2, 'c -> 3)
*
*/
def map(pair: Any)(f: Any) = macro mapImpl[T]
/**
* @returns a string representation of this tuple
* example:
*
* t('a -> 1, 'b -> 2).mkString
* (a -> 1, b -> 2)
*
*/
def mkString = macro mkStringImpl[T]
/**
* converts this tuple to a Map.
* @returns an immutable Map
*/
def toMap = macro toMapImpl[T]
}
object NTuple {
/**
* creates a new NTuple from a list of key -> value pairs
* the types of the values are preserved and will be returned accordingly when apply is called
* if a key is defined twice a compilation error will occur
*
* val tuple1 = t('a -> 1, 'b -> "2")
*
*/
def t(pairs: Any*) = macro newTupleImpl
implicit def nTupleToString[T <: NTuple[T]](ntuple: T): String = macro nTupleToStringImpl[T]
implicit def listOfNTupleToRichList[T <: NTuple[T]](list: List[T]) = RichList[T](list)
}
case class RichList[T] (val list: List[T]) {
def nmap(pair: Any)(f: Any) = macro listMapImpl[T]
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy