Skip to content
This repository was archived by the owner on Aug 17, 2019. It is now read-only.

Commit c428b16

Browse files
committed
Better castTo
1 parent 453e7d9 commit c428b16

File tree

3 files changed

+88
-13
lines changed

3 files changed

+88
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.ckkloverdos.manifest
2+
3+
/**
4+
* Work in progress for obtaining a manifest dynamically.
5+
*
6+
* @author Christos KK Loverdos <loverdos@gmail.com>.
7+
*/
8+
object ManifestHelpers {
9+
def manifestOfClass[T](clazz: Class[T]): Manifest[_ <: AnyRef] = {
10+
if(clazz.isArray) {
11+
Manifest.arrayType(manifestOfClass(clazz.getComponentType))
12+
} else {
13+
Manifest.classType(clazz)
14+
}
15+
}
16+
17+
def manifestOfAny[A](any: A): Manifest[_ <: Any] = {
18+
any match {
19+
case byte: Byte =>
20+
Manifest.Byte
21+
case byte: Boolean =>
22+
Manifest.Boolean
23+
case short: Short =>
24+
Manifest.Short
25+
case byte: Char =>
26+
Manifest.Char
27+
case any: Int =>
28+
Manifest.Int
29+
case long: Long =>
30+
Manifest.Long
31+
case float: Float =>
32+
Manifest.Float
33+
case double: Double =>
34+
Manifest.Double
35+
case unit: Unit =>
36+
Manifest.Unit
37+
38+
// case byte: java.lang.Byte =>
39+
// Manifest.Byte
40+
// case byte: java.lang.Boolean =>
41+
// Manifest.Boolean
42+
// case short: java.lang.Short =>
43+
// Manifest.Short
44+
// case byte: java.lang.Character =>
45+
// Manifest.Char
46+
// case any: java.lang.Integer =>
47+
// Manifest.Int
48+
// case long: java.lang.Long =>
49+
// Manifest.Long
50+
// case float: java.lang.Float =>
51+
// Manifest.Float
52+
// case double: java.lang.Double =>
53+
// Manifest.Double
54+
55+
case null =>
56+
Manifest.Null
57+
58+
case anyRef: AnyRef =>
59+
manifestOfClass(anyRef.getClass)
60+
}
61+
}
62+
}

src/main/scala/com/ckkloverdos/maybe/Maybe.scala

+17-10
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package com.ckkloverdos.maybe
1818

1919
import collection.Iterator
20+
import com.ckkloverdos.manifest.ManifestHelpers
2021

2122
/**
2223
* Inspired by Lift's `Box`, Haskell's `Maybe` and Scala's `Option`.
@@ -86,7 +87,7 @@ sealed abstract class Maybe[+A] extends Serializable {
8687
final def foldJust[T](onJust: (A) T)(onOther: T): T =
8788
fold(onJust)(onOther)(f onOther)
8889

89-
def castTo[B <: AnyRef : Manifest]: Maybe[B]
90+
def castTo[B : Manifest]: Maybe[B]
9091

9192
/**
9293
* Flattens two successive maybes to one.
@@ -188,13 +189,19 @@ final case class Just[+A](get: A) extends MaybeOption[A] with MaybeEither[A] {
188189
}
189190
def foreach(f: A Unit) = f(get)
190191

191-
def castTo[B <: AnyRef : Manifest] = get match {
192-
case null NoVal
193-
case value if(manifest[B].erasure.isInstance(value)) this.asInstanceOf[Maybe[B]]
194-
case value Failed(
195-
new ClassCastException("%s -> %s".format(
196-
get.asInstanceOf[AnyRef].getClass.getName,
197-
manifest[B].erasure.getName)))
192+
def castTo[B : Manifest] = get match {
193+
case null
194+
NoVal
195+
case value //if(manifest[B].erasure.isInstance(value)) ⇒ this.asInstanceOf[Maybe[B]]
196+
val ma = ManifestHelpers.manifestOfAny(get)
197+
val mb = manifest[B]
198+
if(mb == ma || mb.erasure.isInstance(get))
199+
this.asInstanceOf[Maybe[B]]
200+
else
201+
Failed(
202+
new ClassCastException("%s -> %s".format(
203+
get.asInstanceOf[AnyRef].getClass.getName,
204+
manifest[B].erasure.getName)))
198205
}
199206

200207
def flatten1[U](implicit ev: A <:< Maybe[U]): Maybe[U] = ev(get)
@@ -228,7 +235,7 @@ case object NoVal extends MaybeOption[Nothing] {
228235

229236
def finallyFlatMap[B](_finally: (Nothing) Unit)(f: (Nothing) Maybe[B]) = this
230237

231-
def castTo[B <: AnyRef : Manifest] = this
238+
def castTo[B : Manifest] = this
232239

233240
def flatten1[U](implicit ev: <:<[Nothing, Maybe[U]]) = this
234241

@@ -266,7 +273,7 @@ final case class Failed(exception: Throwable) extends MaybeEither[Nothing] {
266273

267274
def finallyFlatMap[B](_finally: (Nothing) Unit)(f: (Nothing) Maybe[B]) = this
268275

269-
def castTo[B <: AnyRef : Manifest] = this
276+
def castTo[B : Manifest] = this
270277

271278
def flatten1[U](implicit ev: <:<[Nothing, Maybe[U]]) = this
272279

src/test/scala/com/ckkloverdos/maybe/MaybeTest.scala

+9-3
Original file line numberDiff line numberDiff line change
@@ -99,24 +99,30 @@ class MaybeTest {
9999
}
100100

101101
@Test
102-
def testCastTo: Unit = {
102+
def testCastToCharSequenceSuccess: Unit = {
103103
val help = "Help"
104104
val aJust: Maybe[_] = Just(help)
105105
Assert.assertTrue(aJust.castTo[CharSequence].isJust)
106106
}
107107

108108
@Test
109-
def testCastTo2: Unit = {
109+
def testCastToScalaObjectFailure: Unit = {
110110
val help = "Help"
111111
val aJust: Maybe[_] = Just(help)
112112
Assert.assertTrue(aJust.castTo[ScalaObject].isFailed)
113113
}
114114

115115
@Test
116-
def testCastTo3: Unit = {
116+
def testCastToIntFailure: Unit = {
117117
Assert.assertTrue(Just(1).castTo[String].isFailed)
118118
}
119119

120+
@Test
121+
def testCastToIntSuccess: Unit = {
122+
val cast = Maybe(1).castTo[Int]
123+
Assert.assertTrue(cast.isJust)
124+
}
125+
120126
@Test
121127
def testFinallyMap: Unit = {
122128
var _flag1 = false

0 commit comments

Comments
 (0)