A Bijection is an invertible function that converts back and forth between two types, with the contract that a round-trip through the Bijection will bring back the original object. Moreover, the inverse has the same property.
See the current API documentation for more information.
Current version is 0.3.0. groupid="com.twitter" artifact="bijection-core_2.9.2".
scala> Bijection[Int, java.lang.Integer](42)
res0: java.lang.Integer = 42In addition to Bijection, we have Injection. An Injection embeds a type A in a larger space of type
B. Every item from A can be round-tripped through B, but not every B can be mapped to A. So
Injection is like a pair of function: A => B, B => Option[A].
import com.twitter.bijection._
scala> Injection[Int, String](100)
res0: String = 100
scala> Injection.invert[Int, String](res0)
res1: Option[Int] = Some(100)If we want to treat an Injection like a Bijection (over a restricted subspace of the larger set),
we use the B @@ Rep[A] syntax, for instance: String @@ Rep[Int]
Bijection[Int, String @@ Rep[Int]](100)
res2: com.twitter.bijection.package.@@[String,com.twitter.bijection.Rep[Int]] = 100Use invert to reverse the transformation:
scala> Bijection.invert[Int, String @@ Rep[Int]](res2)
res3: Int = 100If you import Conversion.asMethod you can use .as[T] to use an available Bijection/Injection to T:
scala> import com.twitter.bijection.Conversion.asMethod
import com.twitter.bijection.Conversion.asMethod
scala> 1.as[java.lang.Integer]
res6: java.lang.Integer = 1Bijections and Injections can also be composed. As with functions, andThen composes forward, compose composes backward.
This example round-trips a long into a GZipped base64-encoded string:
scala> val injection = Injection.long2BigEndian andThen Bijection.bytes2GZippedBase64
injection: com.twitter.bijection.Injection[Long,Array[Byte]] = <function1>
scala> injection(123456789L)
res1: com.twitter.bijection.GZippedBase64String = GZippedBase64String(H4sIAAAAAAAAAGNgYGBgjz4rCgBpa5WLCAAAAA==)
scala> injection.invert(res1)
res2: Option[Long] = Some(123456789)When you have bijections between a path of items you can Bijection.connect or Injection.connect them:
scala> import com.twitter.bijection.Injection.connect
import com.twitter.bijection.Injection.connect
scala> import com.twitter.bijection.Base64String
import com.twitter.bijection.Base64String
scala> import Conversion.asMethod
import Conversion.asMethod
scala> implicit val long2String2Bytes2B64 = connect[Long,String,Array[Byte],Base64String]
string2Long2Bytes2B64: com.twitter.bijection.Bijection[String,com.twitter.bijection.Base64String] = <function1>
scala> 243L.as[Base64String]
res0: com.twitter.bijection.Base64String = Base64String(MjQz)
scala> long2String2Bytes2B64.invert(res5)
res1: Option[Long] = Some(243)Bijection implicitly supplies Bijections between:
- all numeric types <-> their boxed java counterparts
- containers/primitives <-> Json (Injections via bijection-json)
- thrift/protobuf <-> Array[Byte] (Injections via bijection-protobuf/bijection-thrift)
- all numeric types <-> big-endian
Array[Byte]encodings (Injections) - all numeric types <-> String (Injections)
- Bijections for all
asScala,asJavapairs provided by scala.collection.JavaConverters - String <-> utf8 encoded bytes
Array[Byte]<->GZippedBytesArray[Byte]<->Base64StringArray[Byte]<->GZippedBase64StringArray[Byte]<->java.nio.ByteBufferClass[T]<-> String (Injection)A => B<->C => D(function conversion)- Bijection/Injection builders for all tuples. (
(String,Int)<->(Array[Byte], java.lang.Integer)is built automatically, for example.)
Additionally there is a method to generate Bijections between most of Scala's built in types:
Bijection.toContainer[Int,String,List[Int],Vector[String] returns
Bijection[List[Int], Vector[String]
If you see a reversible conversion that is not here and related to types in the standard library of Java or Scala, please contribute!
Bufferable[T] handles putting and getting a type T into a ByteBuffer in a composable way.
Bufferable[T] instances for all primitives/tuples/containers are provided. Bijections and
Injections to any of these types give you binary serialization via Bufferable.
- Oscar Boykin http://twitter.com/posco
- Marius Eriksen http://twitter.com/marius
- Sam Ritchie http://twitter.com/sritchie
Copyright 2012 Twitter, Inc.
Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
