Skip to content
New issue

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

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

Already on GitHub? # 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