假设我想创建一个简单的指令,用于从HTTP请求中获取会话标识符,但有一个扭曲:请求可能使用旧格式,但由于向后兼容性,这两者应该被认为是有效的。 / p>
我勾勒出一些简单的东西,它基本上组成了两个现有的指令,结果指令是......
Directive[Option[String] :: Option[String] :: HNil]
这是我的问题的主要内容:是否有任何简洁的方法基本上说“给定一个指令是多个选项的HList,获得第一个并使用否则使用默认值”?
我目前的实施。有效,但看起来有点混乱,根本无法重复使用。
def sessionIdentifier: Directive1[String] = {
(optionalHeaderValueByName("New-Session-Header") & parameter("oldsessionparam"?)).hmap {
case Some(x) :: _ :: HNil if x.nonEmpty => x
case _ :: Some(x) :: HNil if x.nonEmpty => x
case _ => getNewSessionId()
}
}
答案 0 :(得分:1)
如果保证所有元素类型都是Option[String]
类型,那么以下内容将是一个小问题,
@ import shapeless._
import shapeless._
@ val opts = Option.empty[String] :: Option("foo") :: Option("bar") :: HNil
opts: Option[String] :: Option[String] :: Option[String] :: HNil = ...
@ opts.toList.flatten.headOption.getOrElse("default")
res0: String = "foo"
答案 1 :(得分:0)
实际上你的实现非常好。它可能被重构为
val sessionParameters =
optionalHeaderValueByName("New-Session-Header") & parameter("oldsessionparam".?)
val sessionIdentifier =
sessionParameters.hmap {
case newId :: oldId :: HNil =>
newId.filter(_.nonEmpty)
.orElse(oldId.filter(_.nonEmpty))
.getOrElse(getNewSessionId())
}