aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/xyz/driver')
-rw-r--r--src/main/scala/xyz/driver/core/core.scala25
-rw-r--r--src/main/scala/xyz/driver/core/tagging/tagging.scala62
2 files changed, 66 insertions, 21 deletions
diff --git a/src/main/scala/xyz/driver/core/core.scala b/src/main/scala/xyz/driver/core/core.scala
index 846bed3..2ab4e88 100644
--- a/src/main/scala/xyz/driver/core/core.scala
+++ b/src/main/scala/xyz/driver/core/core.scala
@@ -1,16 +1,15 @@
package xyz.driver
-import scalaz.{Equal, Monad, OptionT}
import eu.timepit.refined.api.{Refined, Validate}
import eu.timepit.refined.collection.NonEmpty
+import scalaz.{Equal, Monad, OptionT}
import xyz.driver.core.rest.errors.ExternalServiceException
+import xyz.driver.core.tagging.Tagged
import scala.concurrent.{ExecutionContext, Future}
// TODO: this package seems too complex, look at all the features we need!
-import scala.language.reflectiveCalls
-import scala.language.higherKinds
-import scala.language.implicitConversions
+import scala.language.{higherKinds, implicitConversions, reflectiveCalls}
package object core {
@@ -29,14 +28,7 @@ package object core {
}
}
- object tagging {
- private[core] trait Tagged[+V, +Tag]
-
- implicit class Taggable[V <: Any](val v: V) extends AnyVal {
- def tagged[Tag]: V @@ Tag = v.asInstanceOf[V @@ Tag]
- }
- }
- type @@[+V, +Tag] = V with tagging.Tagged[V, Tag]
+ type @@[+V, +Tag] = V with Tagged[V, Tag]
implicit class OptionTExtensions[H[_]: Monad, T](optionTValue: OptionT[H, T]) {
@@ -129,13 +121,4 @@ package core {
final case class Base64(value: String)
- trait Trimmed
-
- object Trimmed {
- import tagging._
-
- implicit def string2Trimmed(str: String): String @@ Trimmed = str.trim().tagged[Trimmed]
-
- implicit def name2Trimmed[T](name: Name[T]): Name[T] @@ Trimmed = Name[T](name.value.trim()).tagged[Trimmed]
- }
}
diff --git a/src/main/scala/xyz/driver/core/tagging/tagging.scala b/src/main/scala/xyz/driver/core/tagging/tagging.scala
new file mode 100644
index 0000000..5b6599e
--- /dev/null
+++ b/src/main/scala/xyz/driver/core/tagging/tagging.scala
@@ -0,0 +1,62 @@
+package xyz.driver.core
+
+import scala.collection.generic.CanBuildFrom
+import scala.language.{higherKinds, implicitConversions}
+
+/**
+ * @author sergey
+ * @since 9/11/18
+ */
+package object tagging {
+
+ implicit class Taggable[V <: Any](val v: V) extends AnyVal {
+ def tagged[Tag]: V @@ Tag = v.asInstanceOf[V @@ Tag]
+ }
+
+}
+
+package tagging {
+
+ sealed trait Tagged[+V, +Tag]
+
+ object Tagged {
+ implicit class TaggedOps[V, Tag](val v: V @@ Tag) extends AnyVal {
+ def tagless: V = v
+ }
+
+ implicit def orderingMagnet[V, Tag](implicit ord: Ordering[V]): Ordering[V @@ Tag] =
+ ord.asInstanceOf[Ordering[V @@ Tag]]
+
+ }
+
+ sealed trait Trimmed
+
+ object Trimmed {
+
+ implicit def apply[V](trimmable: V)(implicit ev: CanBeTrimmed[V]): V @@ Trimmed = {
+ ev.trim(trimmable).tagged[Trimmed]
+ }
+
+ sealed trait CanBeTrimmed[T] {
+ def trim(trimmable: T): T
+ }
+
+ implicit object StringCanBeTrimmed extends CanBeTrimmed[String] {
+ def trim(str: String): String = str.trim()
+ }
+
+ implicit def nameCanBeTrimmed[T]: CanBeTrimmed[Name[T]] = new CanBeTrimmed[Name[T]] {
+ def trim(name: Name[T]): Name[T] = Name[T](name.value.trim())
+ }
+
+ implicit def option2Trimmed[V: CanBeTrimmed](option: Option[V]): Option[V @@ Trimmed] =
+ option.map(Trimmed(_))
+
+ implicit def coll2Trimmed[T, C[_] <: Traversable[_]](coll: C[T])(
+ implicit ev: C[T] <:< Traversable[T],
+ tr: CanBeTrimmed[T],
+ bf: CanBuildFrom[Nothing, T @@ Trimmed, C[T @@ Trimmed]]): C[T @@ Trimmed] =
+ ev(coll).map(Trimmed(_)(tr)).to[C]
+ }
+
+}