Skip to content

Instantly share code, notes, and snippets.

@jrwest
Created March 21, 2012 10:29
Show Gist options
  • Save jrwest/2146043 to your computer and use it in GitHub Desktop.
Save jrwest/2146043 to your computer and use it in GitHub Desktop.
case class MediaInfo(mediaRangeType: String, mediaRangeParams: List[(String,String)], qVal: Option[Double], acceptParams: List[(String,String)])
object AcceptHeaderParsers extends JavaTokenParsers {
def acceptHeader: Parser[List[MediaInfo]] = repsep(mediaInfo, ",")
def mediaInfo: Parser[MediaInfo] = (mediaRange ~ opt(qParam ~ rep(params))) ^^ {
case range~None => MediaInfo(range._1,range._2,None,Nil)
case range~Some(q~ap) => MediaInfo(range._1,range._2,Some(q),ap)
}
def qParam: Parser[Double] = ";q=" ~> floatingPointNumber ^^ {
v => {
val value = v.toDouble
if (value < 0) 0.0
else if (value > 1) 1.0
else value
}
}
def mediaRange: Parser[(String, List[(String,String)])] = (mediaType ~ rep(params)) ^^ { case head~tail => (head,tail) }
// this is a little off, but im lazy for now
def params: Parser[(String,String)] = (";" ~> """[^\sq=]+""".r) ~ ("=" ~> """[^,;]+""".r) ^^ { case head~tail => (head,tail) }
def mediaType: Parser[String] = """\*/\*""".r | subTypeAll | fullType
def fullType = ((desc <~ "/".r) ~ desc) ^^ { case s~st => s + "/" + st }
def subTypeAll = (desc ~ """/\*""".r) ^^ { case head~tail => head+tail }
def desc: Parser[String] = """[\w\.-]*""".r
}
scala> parseAll(acceptHeader, "text/html")
List(MediaInfo(text/html,List(),None,List()))
scala> parseAll(acceptHeader, "text/html;q=0.2;a=b,text/plain")
List(MediaInfo(text/html,List(),Some(0.2),List((a,b))), MediaInfo(text/plain,List(),None,List()))
scala> parseAll(acceptHeader, "text/html;version=1;q=0.2;a=b,text/plain;a=0.5")
List(MediaInfo(text/html,List((version,1)),Some(0.2),List((a,b))), MediaInfo(text/plain,List((a,0.5)),None,List()))
scala> parseAll(acceptHeader, "text/html;version=1;q=0.2;a=b,text/plain;q=0.5")
List(MediaInfo(text/html,List((version,1)),Some(0.2),List((a,b))), MediaInfo(text/plain,List(),Some(0.5),List()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment