Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import com.github.nscala_time.time.StaticInterval
- import com.twitter.algebird.Monoid
- import shapeless._, record._, syntax.singleton._
- import shapeless.ops.record.SelectAll
- /** Represents a path component generator, basically a function keysTemplate.type -> Set[Seq[String]]
- *
- */
- trait PathPattern {
- val keysTemplate: HList
- val w: Witness
- def apply[L <: HList](keys: keysTemplate.type)
- (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]]
- }
- /** A path component generator taking a Joda Time Interval and generating a list of path components,
- * one for each hour contained in the interval
- */
- case object HourlyIntervalPathPattern extends PathPattern {
- override val keysTemplate: HList = ("interval" ->> StaticInterval.lastHour) :: HNil
- override val w = Witness("interval")
- override def apply(keys: keysTemplate.type)
- (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]] =
- keys("interval").by[Set](1.hour).map(date =>
- Seq(date.toString("YYYY-MM-dd"), date.toString("HH")))
- }
- case class ConstantStringPathPattern(constant: String) extends PathPattern {
- override val keysTemplate: HList = (constant ->> "") :: HNil
- override def apply(keys: keysTemplate.type)
- (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]] =
- Set(Seq(keys(constant)))
- }
- /** Make the path generators composable
- * The resulting generator takes a Shapeless records containing the keys of each sub-generators
- */
- implicit object PathPatternMonoid extends Monoid[PathPattern] {
- override def zero: PathPattern = new PathPattern {
- override val keysTemplate = HNil
- override def apply(keys: keysTemplate.type)
- (implicit sel: ops.record.Selector[keysTemplate.type , w.T])= Set(Seq(""))
- }
- override def plus(l: PathPattern, r: PathPattern): PathPattern = new PathPattern {
- override val keysTemplate = l.keysTemplate :: r.keysTemplate
- override def genPath (pKeys: keysTemplate.type)
- (implicit sel: ops.record.Selector[keysTemplate.type , w.T])= for {
- p1 <- l(SelectAll[keysTemplate.type, l.keysTemplate.type](pKeys))
- p2 <- r(SelectAll[keysTemplate.type, r.keysTemplate.type](pKeys))
- } yield (p1 ++ p2)
- }
- }
- /** "Nice" syntax
- *
- * @param pathPattern
- */
- implicit class SlashablePathPattern(pathPattern: PathPattern) {
- def /(child: PathPattern)(implicit mon: Monoid[PathPattern]) = mon.plus(pathPattern, child)
- }
- val RegionHourlyPathPattern = ConstantStringPathPattern("region") / HourlyIntervalPathPattern
- val paths = RegionHourlyPathPattern(("region" ->> "US") :: ("interval" ->> StaticInterval.lastHour) :: HNil)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement