Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove redundant Attempt (in favor of scala.util.Try) #133

Merged
merged 3 commits into from
Jul 9, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ res0: java.lang.Integer = 42

In 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 => Attempt[A]`.
Injection is like a pair of function: `A => B, B => Try[A]`.

```scala
import com.twitter.bijection._
Expand All @@ -28,7 +28,7 @@ scala> Injection[Int, String](100)
res0: String = 100

scala> Injection.invert[Int, String](res0)
res1: Attempt[Int] = Success(100)
res1: Try[Int] = Success(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]`
Expand Down Expand Up @@ -67,7 +67,7 @@ scala> injection(123456789L)
res1: com.twitter.bijection.GZippedBase64String = GZippedBase64String(H4sIAAAAAAAAAGNgYGBgjz4rCgBpa5WLCAAAAA==)

scala> injection.invert(res1)
res2: Attempt[Long] = Success(123456789)
res2: Try[Long] = Success(123456789)
```

When you have bijections between a path of items you can `Bijection.connect` or `Injection.connect` them:
Expand All @@ -89,7 +89,7 @@ scala> 243L.as[Base64String]
res0: com.twitter.bijection.Base64String = Base64String(MjQz)

scala> long2String2Bytes2B64.invert(res5)
res1: Attempt[Long] = Success(243)
res1: Try[Long] = Success(243)
```

## Supported Bijections/Injections
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ trait LowPriorityBijections {
implicit def fromInjection[A, B](implicit inj: Injection[A, B]): Bijection[A, B @@ Rep[A]] =
new AbstractBijection[A, B @@ Rep[A]] {
override def apply(a: A): B @@ Rep[A] = Tag(inj.apply(a))
// This tag promises the Attempt will return something:
// This tag promises the Try will return something:
override def invert(b: B @@ Rep[A]): A = inj.invert(b).get
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import com.twitter.bijection.Inversion.attempt
@implicitNotFound(msg = "Cannot find Bufferable type class for ${T}")
trait Bufferable[T] extends Serializable {
def put(into: ByteBuffer, t: T): ByteBuffer
def get(from: ByteBuffer): Attempt[(ByteBuffer, T)]
def get(from: ByteBuffer): Try[(ByteBuffer, T)]
/** Retrieve the value of get or throw an exception if the operation fails */
def unsafeGet(from: ByteBuffer): (ByteBuffer, T) =
get(from) match {
Expand Down Expand Up @@ -64,7 +64,7 @@ object Bufferable extends GeneratedTupleBufferable with Serializable {
inj.invert(inj(t)).get
}
def put[T](into: ByteBuffer, t: T)(implicit buf: Bufferable[T]): ByteBuffer = buf.put(into, t)
def get[T](from: ByteBuffer)(implicit buf: Bufferable[T]): Attempt[(ByteBuffer, T)] = buf.get(from)
def get[T](from: ByteBuffer)(implicit buf: Bufferable[T]): Try[(ByteBuffer, T)] = buf.get(from)
// get the bytes from a given position to the current position
def getBytes(from: ByteBuffer, start: Int = 0): Array[Byte] = {
val fromd = from.duplicate
Expand Down Expand Up @@ -133,7 +133,7 @@ object Bufferable extends GeneratedTupleBufferable with Serializable {
/** remember: putfn and getfn must call duplicate and not change the input ByteBuffer
* We are duplicating the ByteBuffer state, not the backing array (which IS mutated)
*/
def build[T](putfn: (ByteBuffer,T) => ByteBuffer)(getfn: (ByteBuffer) => Attempt[(ByteBuffer, T)]):
def build[T](putfn: (ByteBuffer,T) => ByteBuffer)(getfn: (ByteBuffer) => Try[(ByteBuffer, T)]):
Bufferable[T] = new AbstractBufferable[T] {
override def put(into: ByteBuffer, t: T) = putfn(into,t)
override def get(from: ByteBuffer) = getfn(from)
Expand Down Expand Up @@ -223,9 +223,9 @@ object Bufferable extends GeneratedTupleBufferable with Serializable {
l.foldLeft(nextBb) { (oldbb, t) => reallocatingPut(oldbb) { buf.put(_, t) } }
}
def getCollection[T,C](initbb: ByteBuffer, builder: Builder[T,C])(implicit buf: Bufferable[T]):
Attempt[(ByteBuffer, C)] = {
Try[(ByteBuffer, C)] = {

val bbOpt: Attempt[ByteBuffer] = Try(initbb.duplicate)
val bbOpt: Try[ByteBuffer] = Try(initbb.duplicate)
val size = bbOpt.get.getInt
// We can't mutate the builder while calling other functions (not safe)
// so we write into this array:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import java.util.concurrent.{ ConcurrentMap => JConcurrentMap }
import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.collection.generic.CanBuildFrom
import scala.util.Success
import scala.util.{ Success, Try }

trait CollectionInjections extends StringInjections {

Expand Down Expand Up @@ -86,7 +86,7 @@ trait CollectionInjections extends StringInjections {
c foreach { builder += inj(_) }
builder.result()
}
override def invert(d: D): Attempt[C] = {
override def invert(d: D): Try[C] = {
val builder = dc()
d foreach { b =>
val thisB = inj.invert(b)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ limitations under the License.
package com.twitter.bijection

import java.io.Serializable
import scala.util.Success
import scala.util.{ Success, Try }

/**
* Convert allows the user to convert an instance of type A to type B given an implicit Conversion
Expand Down Expand Up @@ -52,8 +52,8 @@ trait CrazyLowPriorityConversion extends Serializable {
case _ => None
}
}
implicit def fromInjectionInverse[A,B](implicit inj: Injection[B,A]): Conversion[A,Attempt[B]] =
new Conversion[A,Attempt[B]] {
implicit def fromInjectionInverse[A,B](implicit inj: Injection[B,A]): Conversion[A,Try[B]] =
new Conversion[A,Try[B]] {
def apply(a: A) = inj.invert(a)
}
implicit def fromBijectionInv[A,B](implicit fn: ImplicitBijection[B,A]) = new Conversion[A,B] {
Expand All @@ -80,4 +80,3 @@ object Conversion extends LowPriorityConversion {
def apply(a: A) = fn(a)
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import com.twitter.bijection.Inversion.attempt
@implicitNotFound(msg = "Cannot find Injection type class from ${A} to ${B}")
trait Injection[A, B] extends Serializable { self =>
def apply(a: A): B
def invert(b: B): Attempt[A]
def invert(b: B): Try[A]

/**
* Composes two instances of Injection in a new Injection,
Expand Down Expand Up @@ -75,7 +75,7 @@ private [bijection] class InjectionFn[A, B](inj: Injection[A, B]) extends (A =>
*/
abstract class AbstractInjection[A, B] extends Injection[A, B] {
override def apply(a: A): B
override def invert(b: B): Attempt[A]
override def invert(b: B): Try[A]
}

trait LowPriorityInjections {
Expand All @@ -93,9 +93,9 @@ object Injection extends CollectionInjections
implicit def toFunction[A,B](inj: Injection[A, B]): (A => B) = inj.toFunction

def apply[A, B](a: A)(implicit inj: Injection[A, B]): B = inj(a)
def invert[A, B](b: B)(implicit inj: Injection[A, B]): Attempt[A] = inj.invert(b)
def invert[A, B](b: B)(implicit inj: Injection[A, B]): Try[A] = inj.invert(b)

def build[A, B](to: A => B)(from: B => Attempt[A]): Injection[A, B] =
def build[A, B](to: A => B)(from: B => Try[A]): Injection[A, B] =
new AbstractInjection[A, B] {
override def apply(a: A) = to(a)
override def invert(b: B) = from(b)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ object Inversion {
* The analog of Exception.allCatch either where exceptions
* are wrapped by the InversionFailure type
*/
def attempt[A, B](b: B)(inv: B => A): Attempt[A] =
def attempt[A, B](b: B)(inv: B => A): Try[A] =
Try(inv(b)).recoverWith(partialFailure(b))

/**
* Applies tests for known inversion failure before returning
* a success or failure
*/
def attemptWhen[A, B](b: B)(test: B => Boolean)(inv: B => A): Attempt[A] =
def attemptWhen[A, B](b: B)(test: B => Boolean)(inv: B => A): Try[A] =
if (test(b)) Success(inv(b)) else failedAttempt(b)
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ object InversionFailure {
new InversionFailure(b, new UnsupportedOperationException)

/**
* Produces a failed Attempt
*/
def failedAttempt[A, B](b: B): Attempt[A] =
* Produces a failed Try
*/
def failedAttempt[A, B](b: B): Try[A] =
Failure(apply(b))

/**
* Produces a failed attempt statisfying a partial function defined
* for any non-fatal Throwable
*/
def partialFailure[A, B](b: B): PartialFunction[Throwable, Attempt[A]] = {
def partialFailure[A, B](b: B): PartialFunction[Throwable, Try[A]] = {
case NonFatal(t) => Failure(InversionFailure(b, t))
}
}
Expand Down
11 changes: 0 additions & 11 deletions bijection-core/src/main/scala/com/twitter/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ limitations under the License.

package com.twitter

import scala.util.Try

/**
* Bijection trait with numerous implementations.
*
Expand All @@ -27,15 +25,6 @@ import scala.util.Try
* libraries (Bijection[MyTrait, YourTrait]) and many other purposes.
*/
package object bijection {

/**
* Injections may not be defined for their inverse conversion.
* This type represents the attempted conversion. A failure
* will result in a scala.util.Failure containing the InversionFailure. A success
* will result in a scala.util.Success containing the inverted value.
*/
type Attempt[T] = Try[T]

/**
* Using Injections for serialization is a common pattern. Currying
* the byte array parameter makes it easier to write code like
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ limitations under the License.

package com.twitter.bijection.json

import com.twitter.bijection.{Attempt, Bijection, Injection, InversionFailure, ImplicitBijection}
import com.twitter.bijection.{Bijection, Injection, InversionFailure, ImplicitBijection}
import com.twitter.bijection.Inversion.{ attempt, attemptWhen }
import org.codehaus.jackson.{JsonParser, JsonNode, JsonFactory}
import org.codehaus.jackson.map.ObjectMapper
Expand All @@ -30,7 +30,7 @@ import org.codehaus.jackson.node.{
import scala.collection.generic.CanBuildFrom
import scala.collection.mutable.Builder
import scala.collection.JavaConverters._
import scala.util.Success
import scala.util.{ Success, Try }
import scala.util.control.NonFatal

/**
Expand Down Expand Up @@ -75,7 +75,7 @@ object JsonNodeInjection extends LowPriorityJson with java.io.Serializable {
def toJsonNode[T](t: T)(implicit json: JsonNodeInjection[T]): JsonNode =
json.apply(t)

def fromJsonNode[T](node: JsonNode)(implicit json: JsonNodeInjection[T]): Attempt[T] =
def fromJsonNode[T](node: JsonNode)(implicit json: JsonNodeInjection[T]): Try[T] =
json.invert(node)

implicit val identity = new AbstractJsonNodeInjection[JsonNode] {
Expand Down Expand Up @@ -141,7 +141,7 @@ object JsonNodeInjection extends LowPriorityJson with java.io.Serializable {
l foreach { t => ary.add(jbij(t)) }
ary
}
override def invert(n: JsonNode): Attempt[C] = {
override def invert(n: JsonNode): Try[C] = {
builder.clear
var inCount = 0
n.getElements.asScala.foreach { jn =>
Expand Down Expand Up @@ -181,7 +181,7 @@ object JsonNodeInjection extends LowPriorityJson with java.io.Serializable {
}
obj
}
override def invert(n: JsonNode): Attempt[Map[String,V]] = {
override def invert(n: JsonNode): Try[Map[String,V]] = {
val builder = Map.newBuilder[String, V]
builder.clear
var cnt = 0
Expand Down Expand Up @@ -221,6 +221,6 @@ object JsonInjection {
def toString[T](implicit json: JsonNodeInjection[T]): Injection[T, String] =
UnparsedJson.injection[T] andThen (UnparsedJson.unwrap)

def fromString[T](s: String)(implicit json: JsonNodeInjection[T]): Attempt[T] =
def fromString[T](s: String)(implicit json: JsonNodeInjection[T]): Try[T] =
toString.invert(s)
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ package com.twitter.bijection.json

import com.twitter.bijection.Conversion.asMethod

import com.twitter.bijection.{ Attempt, BaseProperties, Bijection, Injection }
import com.twitter.bijection.{ BaseProperties, Bijection, Injection }
import org.scalacheck.Properties
import org.scalacheck.Prop.forAll
import org.scalacheck.Arbitrary
Expand Down Expand Up @@ -77,7 +77,7 @@ object JsonInjectionLaws extends Properties("JsonInjection") with BaseProperties

val jsonMixed = mixedMap.as[UnparsedJson]

jsonMixed.as[Attempt[Map[String, JsonNode]]].get.map({ kup : (String, JsonNode) =>
jsonMixed.as[Try[Map[String, JsonNode]]].get.map({ kup : (String, JsonNode) =>
val (k, up) = kup
if (k.endsWith("i")) {
fromJsonNode[Int](up).get == fromJsonNode[Int](mixedMap(k)).get
Expand Down