Advertisement
Guest User

Untitled

a guest
Aug 2nd, 2015
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.68 KB | None | 0 0
  1. import com.github.nscala_time.time.StaticInterval
  2. import com.twitter.algebird.Monoid
  3. import shapeless._, record._, syntax.singleton._
  4. import shapeless.ops.record.SelectAll
  5.  
  6. /** Represents a path component generator, basically a function keysTemplate.type -> Set[Seq[String]]
  7. *
  8. */
  9. trait PathPattern {
  10.  
  11. val keysTemplate: HList
  12. val w: Witness
  13.  
  14. def apply[L <: HList](keys: keysTemplate.type)
  15. (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]]
  16. }
  17.  
  18. /** A path component generator taking a Joda Time Interval and generating a list of path components,
  19. * one for each hour contained in the interval
  20. */
  21. case object HourlyIntervalPathPattern extends PathPattern {
  22. override val keysTemplate: HList = ("interval" ->> StaticInterval.lastHour) :: HNil
  23. override val w = Witness("interval")
  24. override def apply(keys: keysTemplate.type)
  25. (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]] =
  26. keys("interval").by[Set](1.hour).map(date =>
  27. Seq(date.toString("YYYY-MM-dd"), date.toString("HH")))
  28. }
  29.  
  30. case class ConstantStringPathPattern(constant: String) extends PathPattern {
  31. override val keysTemplate: HList = (constant ->> "") :: HNil
  32.  
  33. override def apply(keys: keysTemplate.type)
  34. (implicit sel: ops.record.Selector[keysTemplate.type , w.T]): Set[Seq[String]] =
  35. Set(Seq(keys(constant)))
  36. }
  37.  
  38. /** Make the path generators composable
  39. * The resulting generator takes a Shapeless records containing the keys of each sub-generators
  40. */
  41. implicit object PathPatternMonoid extends Monoid[PathPattern] {
  42. override def zero: PathPattern = new PathPattern {
  43. override val keysTemplate = HNil
  44. override def apply(keys: keysTemplate.type)
  45. (implicit sel: ops.record.Selector[keysTemplate.type , w.T])= Set(Seq(""))
  46. }
  47.  
  48. override def plus(l: PathPattern, r: PathPattern): PathPattern = new PathPattern {
  49. override val keysTemplate = l.keysTemplate :: r.keysTemplate
  50. override def genPath (pKeys: keysTemplate.type)
  51. (implicit sel: ops.record.Selector[keysTemplate.type , w.T])= for {
  52. p1 <- l(SelectAll[keysTemplate.type, l.keysTemplate.type](pKeys))
  53. p2 <- r(SelectAll[keysTemplate.type, r.keysTemplate.type](pKeys))
  54. } yield (p1 ++ p2)
  55.  
  56. }
  57. }
  58.  
  59. /** "Nice" syntax
  60. *
  61. * @param pathPattern
  62. */
  63. implicit class SlashablePathPattern(pathPattern: PathPattern) {
  64. def /(child: PathPattern)(implicit mon: Monoid[PathPattern]) = mon.plus(pathPattern, child)
  65. }
  66.  
  67.  
  68. val RegionHourlyPathPattern = ConstantStringPathPattern("region") / HourlyIntervalPathPattern
  69. val paths = RegionHourlyPathPattern(("region" ->> "US") :: ("interval" ->> StaticInterval.lastHour) :: HNil)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement