diff --git a/base/shared/src/main/scala/Dummy.scala b/base/shared/src/main/scala/Dummy.scala index b3c3d16..b51be68 100644 --- a/base/shared/src/main/scala/Dummy.scala +++ b/base/shared/src/main/scala/Dummy.scala @@ -13,5 +13,4 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ diff --git a/base/shared/src/main/scala_2.10/compat.scala b/base/shared/src/main/scala_2.10/compat.scala index 168f829..82f392e 100644 --- a/base/shared/src/main/scala_2.10/compat.scala +++ b/base/shared/src/main/scala_2.10/compat.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.base @@ -32,7 +32,8 @@ class Compat210() { def typeName(c: Context, s: String) = c.universe.newTypeName(s) def constructor(c: Context) = c.universe.nme.CONSTRUCTOR def wildcard(c: Context) = c.universe.nme.WILDCARD - def typeIntersection(c: Context)(xs: List[c.universe.Type]) = c.universe.intersectionType(xs) + def typeIntersection(c: Context)(xs: List[c.universe.Type]) = + c.universe.intersectionType(xs) def paramLists(c: Context)(t: c.universe.MethodSymbol) = t.paramss def normalize(c: Context)(t: c.universe.Type) = t.normalize def declarations(c: Context)(t: c.universe.Type) = t.declarations diff --git a/base/shared/src/main/scala_2.11/compat.scala b/base/shared/src/main/scala_2.11/compat.scala index 4c4e628..d5e4045 100644 --- a/base/shared/src/main/scala_2.11/compat.scala +++ b/base/shared/src/main/scala_2.11/compat.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.base @@ -30,10 +30,13 @@ object `package` { class Compat211() { def termName[C <: blackbox.Context](c: C, s: String) = c.universe.TermName(s) def typeName[C <: blackbox.Context](c: C, s: String) = c.universe.TypeName(s) - def constructor[C <: blackbox.Context](c: C) = c.universe.termNames.CONSTRUCTOR + def constructor[C <: blackbox.Context](c: C) = + c.universe.termNames.CONSTRUCTOR def wildcard[C <: blackbox.Context](c: C) = c.universe.termNames.WILDCARD - def typeIntersection[C <: blackbox.Context](c: C)(xs: List[c.universe.Type]) = c.universe.internal.intersectionType(xs) - def paramLists[C <: blackbox.Context](c: C)(t: c.universe.MethodSymbol) = t.paramLists + def typeIntersection[C <: blackbox.Context](c: C)( + xs: List[c.universe.Type]) = c.universe.internal.intersectionType(xs) + def paramLists[C <: blackbox.Context](c: C)(t: c.universe.MethodSymbol) = + t.paramLists def normalize[C <: blackbox.Context](c: C)(t: c.universe.Type) = t.dealias def declarations[C <: blackbox.Context](c: C)(t: c.universe.Type) = t.decls def readLine(): String = scala.io.StdIn.readLine diff --git a/base/shared/src/main/scala_2.12/compat.scala b/base/shared/src/main/scala_2.12/compat.scala index 4c4e628..d5e4045 100644 --- a/base/shared/src/main/scala_2.12/compat.scala +++ b/base/shared/src/main/scala_2.12/compat.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.base @@ -30,10 +30,13 @@ object `package` { class Compat211() { def termName[C <: blackbox.Context](c: C, s: String) = c.universe.TermName(s) def typeName[C <: blackbox.Context](c: C, s: String) = c.universe.TypeName(s) - def constructor[C <: blackbox.Context](c: C) = c.universe.termNames.CONSTRUCTOR + def constructor[C <: blackbox.Context](c: C) = + c.universe.termNames.CONSTRUCTOR def wildcard[C <: blackbox.Context](c: C) = c.universe.termNames.WILDCARD - def typeIntersection[C <: blackbox.Context](c: C)(xs: List[c.universe.Type]) = c.universe.internal.intersectionType(xs) - def paramLists[C <: blackbox.Context](c: C)(t: c.universe.MethodSymbol) = t.paramLists + def typeIntersection[C <: blackbox.Context](c: C)( + xs: List[c.universe.Type]) = c.universe.internal.intersectionType(xs) + def paramLists[C <: blackbox.Context](c: C)(t: c.universe.MethodSymbol) = + t.paramLists def normalize[C <: blackbox.Context](c: C)(t: c.universe.Type) = t.dealias def declarations[C <: blackbox.Context](c: C)(t: c.universe.Type) = t.decls def readLine(): String = scala.io.StdIn.readLine diff --git a/cli/shared/src/main/scala/rapture/cli/cli.scala b/cli/shared/src/main/scala/rapture/cli/cli.scala index dd2b41b..ac84e0d 100644 --- a/cli/shared/src/main/scala/rapture/cli/cli.scala +++ b/cli/shared/src/main/scala/rapture/cli/cli.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.cli @@ -46,16 +45,18 @@ object debugMode { case class DebugModeConfig(on: Boolean) object ShParam { - implicit def stringableToShParam[T: StringSerializer](t: T): ShParam = + implicit def stringableToShParam[T : StringSerializer](t: T): ShParam = ShParam(Vector(?[StringSerializer[T]].serialize(t))) - implicit def genSeqSerializer[T: StringSerializer, Coll[E] <: TraversableOnce[E]](ts: Coll[T]): ShParam = + implicit def genSeqSerializer[T : StringSerializer, Coll[ + E] <: TraversableOnce[E]](ts: Coll[T]): ShParam = ShParam(ts.map(?[StringSerializer[T]].serialize(_)).to[Vector]) implicit def processToShParam(process: Process) = ShParam(process.params) - implicit def fsUrlToShParam(fsUrl: FsUrl) = ShParam(Vector(fsUrl.elements.mkString("/", "/", ""))) + implicit def fsUrlToShParam(fsUrl: FsUrl) = + ShParam(Vector(fsUrl.elements.mkString("/", "/", ""))) } case class ShParam(elems: Vector[String]) { @@ -66,22 +67,28 @@ object `package` { implicit class ProcessStringContext(sc: StringContext) { def sh(content: ShParam*): Process = macro CliMacros.shImplementation } - + object cliLogging { import rapture.log.parts._ - + implicit val logger = Logger(uri"file:///tmp/rapture-cli/access.log") - - implicit def implicitSpec(implicit severity: Severity, date: Date, time: Time, thread: Thread): Spec = - log"""$date $time $severity ${sourceFile(width = 12, Right)}:${lineNo(4)} ${thread(14)}""" + + implicit def implicitSpec(implicit severity: Severity, + date: Date, + time: Time, + thread: Thread): Spec = + log"""$date $time $severity ${sourceFile(width = 12, Right)}:${lineNo(4)} ${thread( + 14)}""" } } sealed class CliException(msg: String) extends Exception(msg) -case class ParamGetException(name: String) extends CliException(s"Missing parameter $name") +case class ParamGetException(name: String) + extends CliException(s"Missing parameter $name") -abstract class BackgroundCliApp(implicit debugMode: DebugModeConfig) extends CliApp with Completions[Zsh with Bash] { +abstract class BackgroundCliApp(implicit debugMode: DebugModeConfig) + extends CliApp with Completions[Zsh with Bash] { val shellCompleter = new Bash with Zsh {} @@ -97,7 +104,7 @@ abstract class BackgroundCliApp(implicit debugMode: DebugModeConfig) extends Cli val fifo = File.parse(s"file:///tmp/rapture-cli/${appName}.sock") var continue = true var invocation = 0 - while(continue) { + while (continue) { val msg = fifo.slurp[Char].trim msg.split(",").to[List].map(_.urlDecode) match { case "shutdown" :: Nil => @@ -106,24 +113,26 @@ abstract class BackgroundCliApp(implicit debugMode: DebugModeConfig) extends Cli fifo.delete() sys.exit(0) case "sigint" :: file :: Nil => - log.info("Received SIGINT for file "+file) + log.info("Received SIGINT for file " + file) case "winch" :: file :: lines :: cols :: Nil => log.info(s"Received SIGWINCH for file $file $lines x $cols") case "exec" :: file :: pwd :: rest => log.info(s"Using pwd = $pwd") - val ps = new java.io.PrintStream(new java.io.FileOutputStream(new java.io.File(file))) + val ps = new java.io.PrintStream( + new java.io.FileOutputStream(new java.io.File(file))) invocation += 1 Future { try { System.setOut(ps) try super.run(File.parse(s"file://$pwd"), rest.to[Array]) catch { - case e: Throwable => if(debugMode.on) e.printStackTrace() + case e: Throwable => if (debugMode.on) e.printStackTrace() } } catch { case e: Throwable => - if(debugMode.on) e.printStackTrace() + if (debugMode.on) e.printStackTrace() } finally ps.close() - val ps2 = new java.io.PrintStream(new java.io.FileOutputStream(new java.io.File(s"$file.exit"))) + val ps2 = new java.io.PrintStream( + new java.io.FileOutputStream(new java.io.File(s"$file.exit"))) try { ps2.println(lastExitStatus.toString) ps2.flush() @@ -148,20 +157,21 @@ abstract class CliApp(implicit debugMode: DebugModeConfig) { def exec(block: => Unit): Exec = Exec((out: java.io.PrintStream) => block) def exec(block: java.io.PrintStream => Unit): Exec = Exec(block) val sysOut = System.out - + def doExit(code: Int): Unit = sys.exit(code) - def main(args: Array[String]): Unit = run(File.parse(s"file://${System.getenv("PWD")}"), args) + def main(args: Array[String]): Unit = + run(File.parse(s"file://${System.getenv("PWD")}"), args) def run(pwd: FsUrl, args: Array[String]): Unit = { - + val exitStatus: Exit = try { Console.withOut(NoOutput) { try { val cmdLine: CmdLine = makeCmdLine(pwd, args.to[Vector]) val execution = handle(cmdLine) - - if(cmdLine.completer.isEmpty) { + + if (cmdLine.completer.isEmpty) { execution.exec(System.out) Exit(0) } else Exit(0) @@ -171,19 +181,21 @@ abstract class CliApp(implicit debugMode: DebugModeConfig) { case err: Throwable => Console.withOut(sysOut) { println("Unexpected error") - if(debugMode.on) err.printStackTrace() + if (debugMode.on) err.printStackTrace() } throw Exit(1) } } - } catch { case err@Exit(_) => err } + } catch { case err @ Exit(_) => err } doExit(exitStatus.code) } def makeCmdLine(pwd: FsUrl, args: Vector[String]) = - CmdLine(pwd, args map { s => Arg(s, None, false) }, None) - + CmdLine(pwd, args map { s => + Arg(s, None, false) + }, None) + def handle(cmdLine: CmdLine): Exec } @@ -193,23 +205,30 @@ trait Shell { } trait Zsh extends Shell { - override def makeCmdLine(pwd: FsUrl, cmdLine: Vector[String]): CmdLine = cmdLine match { - case "---rapture-zsh" +: prefix +: cursor +: cols +: "--" +: rest => - val colWidth = cols.substring(10).toInt - val cur = cursor.substring(9).toInt - val words = if(cur >= rest.length) rest.tail :+ "" else rest.tail - val completer = Completer(prefix.substring(9).urlDecode, zshCompleter(_, colWidth)) - CmdLine(pwd, words.zipWithIndex map { case (s, idx) => - Arg(s, Some(completer), cur - 2 == idx) - }, Some(completer)) - case _ => - super.makeCmdLine(pwd, cmdLine) - } + override def makeCmdLine(pwd: FsUrl, cmdLine: Vector[String]): CmdLine = + cmdLine match { + case "---rapture-zsh" +: prefix +: cursor +: cols +: "--" +: rest => + val colWidth = cols.substring(10).toInt + val cur = cursor.substring(9).toInt + val words = if (cur >= rest.length) rest.tail :+ "" else rest.tail + val completer = Completer( + prefix.substring(9).urlDecode, zshCompleter(_, colWidth)) + CmdLine(pwd, words.zipWithIndex map { + case (s, idx) => + Arg(s, Some(completer), cur - 2 == idx) + }, Some(completer)) + case _ => + super.makeCmdLine(pwd, cmdLine) + } def zshCompleter(suggestions: Suggestions, colWidth: Int): Nothing = { suggestions.groups.map { g => - val cmds = Compadd(g.title, g.suggestions.keys.to[Vector], true, - v => g.suggestions(v), colWidth, g.hidden) + val cmds = Compadd(g.title, + g.suggestions.keys.to[Vector], + true, + v => g.suggestions(v), + colWidth, + g.hidden) cmds foreach System.out.println } throw ReturnEarly() @@ -217,17 +236,20 @@ trait Zsh extends Shell { } trait Bash extends Shell { - override def makeCmdLine(pwd: FsUrl, cmdLine: Vector[String]): CmdLine = cmdLine match { - case "---rapture-bash" +: prefix +: cursor +: cols +: "--" +: rest => - val colWidth = cols.substring(10).toInt - val words = if(cursor.toInt - 1 >= rest.length) rest.tail :+ "" else rest.tail - val completer = new Completer(prefix.urlDecode, bashCompleter) - CmdLine(pwd, words.zipWithIndex map { case (s, idx) => - Arg(s, Some(completer), cursor.toInt - 2 == idx) - }, Some(completer)) - case _ => - super.makeCmdLine(pwd, cmdLine) - } + override def makeCmdLine(pwd: FsUrl, cmdLine: Vector[String]): CmdLine = + cmdLine match { + case "---rapture-bash" +: prefix +: cursor +: cols +: "--" +: rest => + val colWidth = cols.substring(10).toInt + val words = + if (cursor.toInt - 1 >= rest.length) rest.tail :+ "" else rest.tail + val completer = new Completer(prefix.urlDecode, bashCompleter) + CmdLine(pwd, words.zipWithIndex map { + case (s, idx) => + Arg(s, Some(completer), cursor.toInt - 2 == idx) + }, Some(completer)) + case _ => + super.makeCmdLine(pwd, cmdLine) + } def bashCompleter(suggestions: Suggestions): Nothing = { System.out.println("Using bash") @@ -237,4 +259,3 @@ trait Bash extends Shell { case class Exit(code: Int) extends Exception case class Exec(exec: java.io.PrintStream => Unit) - diff --git a/cli/shared/src/main/scala/rapture/cli/glob.scala b/cli/shared/src/main/scala/rapture/cli/glob.scala index 9c333b3..9ae18a5 100644 --- a/cli/shared/src/main/scala/rapture/cli/glob.scala +++ b/cli/shared/src/main/scala/rapture/cli/glob.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -25,23 +25,25 @@ object globInterpreters { */ object unix { def apply(): GlobInterpreter = implicitGlobInterpreter - implicit val implicitGlobInterpreter: GlobInterpreter = new GlobInterpreter { - def interpret(glob: String): Pattern = { - val sb = new StringBuilder - var start = true - glob foreach { c => - start = false - sb.append(c match { - case '*' => if(start) "[^./][^/]*" else "[^/]*" - case '?' => if(start) "[^./][^/]*" else "[^/]*" - case '/' => start = true; "/" - case esc@('.' | '[' | '{' | '(' | '+' | '^' | '$' | '|') => "\\"+esc - case other => other.toString - }) + implicit val implicitGlobInterpreter: GlobInterpreter = + new GlobInterpreter { + def interpret(glob: String): Pattern = { + val sb = new StringBuilder + var start = true + glob foreach { c => + start = false + sb.append(c match { + case '*' => if (start) "[^./][^/]*" else "[^/]*" + case '?' => if (start) "[^./][^/]*" else "[^/]*" + case '/' => start = true; "/" + case esc @ ('.' | '[' | '{' | '(' | '+' | '^' | '$' | '|') => + "\\" + esc + case other => other.toString + }) + } + Pattern.compile(sb.toString) } - Pattern.compile(sb.toString) } - } } } diff --git a/cli/shared/src/main/scala/rapture/cli/macros.scala b/cli/shared/src/main/scala/rapture/cli/macros.scala index 1781320..048e126 100644 --- a/cli/shared/src/main/scala/rapture/cli/macros.scala +++ b/cli/shared/src/main/scala/rapture/cli/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -22,84 +22,89 @@ import rapture.core._ private[cli] object CliMacros { - - def shImplementation(c: BlackboxContext)(content: c.Expr[ShParam]*): c.Expr[Process] = { + def shImplementation(c: BlackboxContext)( + content: c.Expr[ShParam]*): c.Expr[Process] = { import c.universe._ val params = c.prefix.tree match { case Apply(_, List(Apply(_, rawParts))) => - - val parts = rawParts.to[Vector].zip(content.map(_.tree).to[Vector]).flatMap { - case (x, y) => Vector(x, y) - } :+ rawParts.last - - var params: Vector[c.Tree] = Vector() - var param: Vector[Either[String, c.Tree]] = Vector() - var inline: Boolean = false - var singleQuoted: Boolean = false - var doubleQuoted: Boolean = false - var escaped: Boolean = false + val parts = + rawParts.to[Vector].zip(content.map(_.tree).to[Vector]).flatMap { + case (x, y) => Vector(x, y) + } :+ rawParts.last + + var params: Vector[c.Tree] = Vector() + var param: Vector[Either[String, c.Tree]] = Vector() + var inline: Boolean = false + var singleQuoted: Boolean = false + var doubleQuoted: Boolean = false + var escaped: Boolean = false def add(chr: Char) = { - param = if(param.isEmpty) Vector(Left(chr.toString)) else param.last match { - case Right(_) => - param :+ Left(chr.toString) - case Left(str) => - param.init :+ Left(str+chr) - } - escaped = false - } - - def nextParam() = if(!param.isEmpty) { - - val next: c.Tree = if(inline) { - val strings = param.map { - case Left(str) => - Literal(Constant(str)) - case Right(tr) => - q"""$tr.elems.mkString(" ")""" - } - q"_root_.scala.Vector(_root_.scala.Vector(_root_.scala.Vector(..$strings).mkString))" - } else { - val values = param.map { - case Left(str) => - q"_root_.scala.Vector(${Literal(Constant(str))})" - case Right(tr) => - q"$tr.elems" - } - q"_root_.scala.Vector(..$values)" - } - - params = params :+ next - param = Vector() - inline = false - } - - parts.foreach { + param = if (param.isEmpty) Vector(Left(chr.toString)) + else + param.last match { + case Right(_) => + param :+ Left(chr.toString) + case Left(str) => + param.init :+ Left(str + chr) + } + escaped = false + } + + def nextParam() = if (!param.isEmpty) { + + val next: c.Tree = + if (inline) { + val strings = param.map { + case Left(str) => + Literal(Constant(str)) + case Right(tr) => + q"""$tr.elems.mkString(" ")""" + } + q"_root_.scala.Vector(_root_.scala.Vector(_root_.scala.Vector(..$strings).mkString))" + } else { + val values = param.map { + case Left(str) => + q"_root_.scala.Vector(${Literal(Constant(str))})" + case Right(tr) => + q"$tr.elems" + } + q"_root_.scala.Vector(..$values)" + } + + params = params :+ next + param = Vector() + inline = false + } + + parts.foreach { case Literal(Constant(str: String)) => str.foreach { - case chr if escaped => - add(chr) - case ' ' => - if(singleQuoted || doubleQuoted) add(' ') else nextParam() + case chr if escaped => + add(chr) + case ' ' => + if (singleQuoted || doubleQuoted) add(' ') else nextParam() case '\\' => - escaped = true - case '\'' if !doubleQuoted => + escaped = true + case '\'' if !doubleQuoted => singleQuoted = !singleQuoted - case '"' if !singleQuoted => + case '"' if !singleQuoted => doubleQuoted = !doubleQuoted - case chr => - add(chr) + case chr => + add(chr) } - case tr: c.Tree => - inline = inline || singleQuoted || doubleQuoted - param = param :+ Right(tr) - } + case tr: c.Tree => + inline = inline || singleQuoted || doubleQuoted + param = param :+ Right(tr) + } nextParam() - if(singleQuoted || doubleQuoted) c.abort(c.enclosingPosition, "unclosed quoted parameter") - if(params.isEmpty) c.abort(c.enclosingPosition, "no command specified") + if (singleQuoted || doubleQuoted) + c.abort(c.enclosingPosition, "unclosed quoted parameter") + if (params.isEmpty) + c.abort(c.enclosingPosition, "no command specified") q"_root_.scala.Vector(..$params).flatten.flatten" } diff --git a/cli/shared/src/main/scala/rapture/cli/params.scala b/cli/shared/src/main/scala/rapture/cli/params.scala index f6ef3a8..76be674 100644 --- a/cli/shared/src/main/scala/rapture/cli/params.scala +++ b/cli/shared/src/main/scala/rapture/cli/params.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -32,13 +32,13 @@ object Optable { def description(t: String) = Vector() def hidden(t: String): Boolean = false } - + implicit val OptOptable = new Optable[Opt] { def name(t: Opt) = t.name def description(t: Opt) = Vector(s"-- ${t.description}") def hidden(t: Opt): Boolean = t.hidden } - + implicit val stringPairOptable = new Optable[(String, String)] { def name(t: (String, String)) = t._1 def description(t: (String, String)) = Vector(t._2) @@ -52,14 +52,16 @@ trait Optable[-T] { def hidden(t: T): Boolean } -case class Opt(val name: String, val description: String, val hidden: Boolean = false)(opts: => Opts[Opt]) { +case class Opt( + val name: String, val description: String, val hidden: Boolean = false)( + opts: => Opts[Opt]) { def unapply(arg: Arg): Boolean = opts.unapply(arg) == Some(this) } -case class Opts[T: Optable](options: T*) { - +case class Opts[T : Optable](options: T*) { + private val optable = implicitly[Optable[T]] - + def unapply(arg: Arg): Option[T] = { val p = arg(suggester) options.to[List].find(optable.name(_) == p) @@ -67,33 +69,45 @@ case class Opts[T: Optable](options: T*) { def suggester: Suggester = new Suggester { override def suggest(prefix: String): Suggestions = - Suggestions(SuggestionGroup(None, options.to[Vector].map { opt => - (optable.name(opt), optable.description(opt)) - }.filter (_._1 startsWith prefix).toMap, false)) + Suggestions( + SuggestionGroup(None, + options + .to[Vector] + .map { opt => + (optable.name(opt), optable.description(opt)) + } + .filter(_._1 startsWith prefix) + .toMap, + false)) } } object NoSuggestions extends Suggester -case class Param[+T: ParamParser](longName: String = null, shortName: String = null, - description: String = null, suggester: Suggester = NoSuggestions, - repeatable: Boolean = false) { +case class Param[+T : ParamParser](longName: String = null, + shortName: String = null, + description: String = null, + suggester: Suggester = NoSuggestions, + repeatable: Boolean = false) { def parse(s: List[String]): Option[T] = implicitly[ParamParser[T]].parse(s) } trait ParamParser_1 { - implicit val intParamParser: ParamParser[Int] = - new ParamParser[Int] { def parse(s: List[String]) = s.headOption.map(_.toInt) } - + implicit val intParamParser: ParamParser[Int] = new ParamParser[Int] { + def parse(s: List[String]) = s.headOption.map(_.toInt) + } + implicit val booleanParamParser: ParamParser[Boolean] = - new ParamParser[Boolean] { def parse(s: List[String]): Option[Boolean] = Some(true) } + new ParamParser[Boolean] { + def parse(s: List[String]): Option[Boolean] = Some(true) + } } object ParamParser extends ParamParser_1 { implicit val defaultParamParser: ParamParser[String] = new ParamParser[String] { def parse(s: List[String]) = s.headOption } - def of[T: ParamParser]: ParamParser[T] = implicitly[ParamParser[T]] + def of[T : ParamParser]: ParamParser[T] = implicitly[ParamParser[T]] } trait ParamParser[+T] { paramParser => @@ -104,15 +118,19 @@ trait ParamParser[+T] { paramParser => } object Paramable { - implicit def paramParamable[T]: Paramable[T, Param] = new Paramable[T, Param] { - def longName(p: Param[T]): String = Option(p.longName).map("--"+_).getOrElse("") - def shortName(p: Param[T]): String = Option(p.shortName).map("-"+_).getOrElse("") - def description(p: Param[T]): Vector[String] = Option(p.description).to[Vector] - def hidden(p: Param[T]): Boolean = false - def suggester(p: Param[T]): Suggester = p.suggester - def repeatable(p: Param[T]): Boolean = p.repeatable - def parse(p: Param[T], s: List[String]): Option[T] = p.parse(s) - } + implicit def paramParamable[T]: Paramable[T, Param] = + new Paramable[T, Param] { + def longName(p: Param[T]): String = + Option(p.longName).map("--" + _).getOrElse("") + def shortName(p: Param[T]): String = + Option(p.shortName).map("-" + _).getOrElse("") + def description(p: Param[T]): Vector[String] = + Option(p.description).to[Vector] + def hidden(p: Param[T]): Boolean = false + def suggester(p: Param[T]): Suggester = p.suggester + def repeatable(p: Param[T]): Boolean = p.repeatable + def parse(p: Param[T], s: List[String]): Option[T] = p.parse(s) + } } trait Paramable[T, P[_]] { @@ -125,81 +143,108 @@ trait Paramable[T, P[_]] { def parse(p: P[T], s: List[String]): Option[T] } -case class Params[T, P[_]](options: P[T]*)(implicit paramable: Paramable[T, P]) { - +case class Params[ + T, P[_]](options: P[T]*)(implicit paramable: Paramable[T, P]) { + def suggester(exclusions: Set[String]): Suggester = new Suggester { override def suggest(prefix: String): Suggestions = Suggestions( - SuggestionGroup(None, options.filterNot { opt => - exclusions.contains(paramable.longName(opt).drop(2)) || - exclusions.contains(paramable.shortName(opt).drop(1)) - }.map { opt => - (paramable.longName(opt), paramable.shortName(opt) +: paramable.description(opt)) - }.filter (_._1 startsWith prefix).toMap, false), - SuggestionGroup(None, options.filterNot { opt => - exclusions.contains(paramable.longName(opt).drop(2)) || - exclusions.contains(paramable.shortName(opt).drop(1)) - }.map { opt => paramable.shortName(opt) -> Vector() }.filter(_._1 startsWith prefix).toMap, true) + SuggestionGroup(None, options.filterNot { opt => + exclusions.contains(paramable.longName(opt).drop(2)) || + exclusions.contains(paramable.shortName(opt).drop(1)) + }.map { opt => + (paramable.longName(opt), + paramable.shortName(opt) +: paramable.description(opt)) + }.filter(_._1 startsWith prefix).toMap, false), + SuggestionGroup(None, options.filterNot { opt => + exclusions.contains(paramable.longName(opt).drop(2)) || + exclusions.contains(paramable.shortName(opt).drop(1)) + }.map { opt => + paramable.shortName(opt) -> Vector() + }.filter(_._1 startsWith prefix).toMap, true) ) } private object LongOpt { def unapply(arg: Arg): Option[String] = - if(arg.param.startsWith("--")) Some(arg(suggester(Set())).drop(2)) else None + if (arg.param.startsWith("--")) Some(arg(suggester(Set())).drop(2)) + else None } - + private object ShortOpt { def unapply(arg: Arg): Option[String] = - if(arg.param.startsWith("-")) Some(arg(suggester(Set())).drop(1).take(1)) else None + if (arg.param.startsWith("-")) + Some(arg(suggester(Set())).drop(1).take(1)) else None } @tailrec - private def organize(xs: Seq[Arg], acc: ListMap[String, List[Arg]] = ListMap()): Map[String, List[Arg]] = xs match { - case Seq() => - acc - case LongOpt(dashParam) +: tail => - organize(tail, acc + (dashParam -> Nil)) - case (arg@ShortOpt(dashParam)) +: tail => - if(arg.param.length == 2) organize(tail, acc + (dashParam -> Nil)) - else organize(arg.copy(param = "-"+arg.param.drop(2)) +: tail, acc + (dashParam.take(2) -> Nil)) - case v +: tail => - acc.lastOption match { - case Some((key, entry)) => - organize(tail, acc + (key -> (entry :+ v))) - case None => - val exclusions = acc.keys.to[Set] - v(suggester(exclusions)) - organize(tail, acc) - } - } + private def organize( + xs: Seq[Arg], + acc: ListMap[String, List[Arg]] = ListMap()): Map[String, List[Arg]] = + xs match { + case Seq() => + acc + case LongOpt(dashParam) +: tail => + organize(tail, acc + (dashParam -> Nil)) + case (arg @ ShortOpt(dashParam)) +: tail => + if (arg.param.length == 2) organize(tail, acc + (dashParam -> Nil)) + else + organize(arg.copy(param = "-" + arg.param.drop(2)) +: tail, + acc + (dashParam.take(2) -> Nil)) + case v +: tail => + acc.lastOption match { + case Some((key, entry)) => + organize(tail, acc + (key -> (entry :+ v))) + case None => + val exclusions = acc.keys.to[Set] + v(suggester(exclusions)) + organize(tail, acc) + } + } def unapply(cmdLine: CmdLine): Option[ParamMap] = Some(ParamMap(organize(cmdLine.params), cmdLine.completer)) } -case class ParamMap(params: Map[String, List[Arg]], completer: Option[Completer]) { - - def get[T, P[_]](param: P[T], suggesters: Suggester*)(implicit paramable: Paramable[T, P]): Option[T] = { - params.find { case (k, v) => - k == implicitly[Paramable[T, P]].longName(param).substring(2) || k == implicitly[Paramable[T, P]].shortName(param).substring(1) - }.flatMap { case (_, args) => - val values = suggesters padTo (args.length, NoSuggestions) zip args map { case (suggester, arg) => arg(suggester) } - paramable.parse(param, values.to[List]) +case class ParamMap( + params: Map[String, List[Arg]], completer: Option[Completer]) { + + def get[T, P[_]](param: P[T], suggesters: Suggester*)( + implicit paramable: Paramable[T, P]): Option[T] = { + params.find { + case (k, v) => + k == implicitly[Paramable[T, P]].longName(param).substring(2) || + k == implicitly[Paramable[T, P]].shortName(param).substring(1) + }.flatMap { + case (_, args) => + val values = + suggesters padTo (args.length, NoSuggestions) zip args map { + case (suggester, arg) => arg(suggester) + } + paramable.parse(param, values.to[List]) } } - def apply[T, P[_]](param: P[T], suggesters: Suggester*)(implicit paramable: Paramable[T, P]): T = - get(param, suggesters: _*).getOrElse { if(completer.isDefined) null.asInstanceOf[T] else throw ParamGetException(paramable.longName(param)) } + def apply[T, P[_]](param: P[T], suggesters: Suggester*)( + implicit paramable: Paramable[T, P]): T = + get(param, suggesters: _*).getOrElse { + if (completer.isDefined) null.asInstanceOf[T] + else throw ParamGetException(paramable.longName(param)) + } } object -- { def unapply(cmdLine: CmdLine): Option[(CmdLine, CmdLine)] = { val left = cmdLine.params.takeWhile(_.param != "--") Some( - if(cmdLine.params.length == left.length) (cmdLine, CmdLine(cmdLine.pwd, Vector(), cmdLine.completer)) - else ( - CmdLine(cmdLine.pwd, left, cmdLine.completer), - CmdLine(cmdLine.pwd, cmdLine.params.drop(left.length + 1), cmdLine.completer) - ) + if (cmdLine.params.length == left.length) + (cmdLine, CmdLine(cmdLine.pwd, Vector(), cmdLine.completer)) + else + ( + CmdLine(cmdLine.pwd, left, cmdLine.completer), + CmdLine(cmdLine.pwd, + cmdLine.params.drop(left.length + 1), + cmdLine.completer) + ) ) } } @@ -212,8 +257,9 @@ case class Arg(param: String, completer: Option[Completer], current: Boolean) { } } -case class CmdLine(pwd: FsUrl, params: Vector[Arg], completer: Option[Completer]) extends - collection.SeqLike[Arg, CmdLine] { +case class CmdLine( + pwd: FsUrl, params: Vector[Arg], completer: Option[Completer]) + extends collection.SeqLike[Arg, CmdLine] { def seq = params def apply(idx: Int) = params(idx) @@ -230,19 +276,26 @@ case class CmdLine(pwd: FsUrl, params: Vector[Arg], completer: Option[Completer] } } - override def toString = params.map { - case Arg(p, _, false) => p - case Arg(p, _, true) => completer.get.prefix+"^"+p.drop(completer.get.prefix.length + 1) - }.mkString(" ") + override def toString = + params.map { + case Arg(p, _, false) => p + case Arg(p, _, true) => + completer.get.prefix + "^" + p.drop(completer.get.prefix.length + 1) + }.mkString(" ") } class Suggester { def suggest(prefix: String): Suggestions = Suggestions() } object Suggestions { - def from[T](it: Iterable[T])(fn: T => String, fns: (T => Any)*) = new Suggester { - override def suggest(prefix: String) = Suggestions(SuggestionGroup(None, - it.map { e => fn(e) -> ((if(fns.isEmpty) "" else "--") +: fns.to[Vector].map(_(e).toString)) }.filter(_._1.startsWith(prefix)).toMap, false - )) - } + def from[T](it: Iterable[T])(fn: T => String, fns: (T => Any)*) = + new Suggester { + override def suggest(prefix: String) = + Suggestions( + SuggestionGroup(None, it.map { e => + fn(e) -> + ((if (fns.isEmpty) + "" else "--") +: fns.to[Vector].map(_ (e).toString)) + }.filter(_._1.startsWith(prefix)).toMap, false)) + } /*def from[T](fromPrefix: String => Iterable[T])(fn: T => String, fns: (T => Any)*) = new Suggester { override def suggest(prefix: String) = Suggestions(SuggestionGroup(None, @@ -252,14 +305,17 @@ object Suggestions { }*/ } case class Suggestions(groups: SuggestionGroup*) -case class SuggestionGroup(title: Option[String], suggestions: Map[String, Vector[String]], hidden: Boolean) +case class SuggestionGroup(title: Option[String], + suggestions: Map[String, Vector[String]], + hidden: Boolean) case class Completer(prefix: String, shellCompleter: Suggestions => Nothing) { def process(suggestions: Suggestions): Nothing = shellCompleter(suggestions) } -trait Completions[ShellTypes <: Shell] { this: CliApp => - +trait Completions[ShellTypes <: Shell] { + this: CliApp => + override def makeCmdLine(pwd: FsUrl, args: Vector[String]): CmdLine = shellCompleter().makeCmdLine(pwd, args) diff --git a/cli/shared/src/main/scala/rapture/cli/params2.scala b/cli/shared/src/main/scala/rapture/cli/params2.scala index be31093..85eb76b 100644 --- a/cli/shared/src/main/scala/rapture/cli/params2.scala +++ b/cli/shared/src/main/scala/rapture/cli/params2.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -26,41 +26,49 @@ object New { case class ParamUsage(map: ParamMap, used: Set[String]) { def -(key: String): ParamUsage = copy(used = used + key) def --(keys: Set[String]): ParamUsage = copy(used = used ++ keys) - def unexpected = map.groups.filterNot { p => used contains p.key() } + def unexpected = map.groups.filterNot { p => + used contains p.key() + } } case class ParamMap(args: String*) { - + def ++(pm2: ParamMap) = ParamMap((pm2.args ++ args): _*) - + case class Part(no: Int, start: Int, end: Int) { def apply() = args(no).substring(start, end) } case class Parameter(key: Part, values: Vector[Part] = Vector()) { override def toString = { - val prefix = if(key().length == 1) "-" else "--" - s"$prefix${key()} ${values.map(_()) mkString " "}" + val prefix = if (key().length == 1) "-" else "--" + s"$prefix${key()} ${values.map(_ ()) mkString " "}" } } val groups: Set[Parameter] = parseArgs().to[Set] @tailrec - private def parseArgs(gs: List[Parameter] = Nil, n: Int = 0, off: Int = 0): - List[Parameter] = { - if(n == args.length) gs - else if(args(n) startsWith "--") { + private def parseArgs(gs: List[Parameter] = Nil, + n: Int = 0, + off: Int = 0): List[Parameter] = { + if (n == args.length) gs + else if (args(n) startsWith "--") { val idx = args(n).indexOf('=') - if(idx < off) parseArgs(Parameter(Part(n, 2, args(n).length)) :: gs, n + 1) + if (idx < off) + parseArgs(Parameter(Part(n, 2, args(n).length)) :: gs, n + 1) else parseArgs(Parameter(Part(n, 2, idx)) :: gs, n, idx + 1) - } else if(args(n) startsWith "-") { - if(off == 0) parseArgs(gs, n, 1) - else if(args(n).length == off + 1) parseArgs(Parameter(Part(n, off, off + 1)) :: gs, n + 1) + } else if (args(n) startsWith "-") { + if (off == 0) parseArgs(gs, n, 1) + else if (args(n).length == off + 1) + parseArgs(Parameter(Part(n, off, off + 1)) :: gs, n + 1) else parseArgs(Parameter(Part(n, off, off + 1)) :: gs, n, off + 1) } else { - if(gs.isEmpty) parseArgs(gs, n + 1) - else parseArgs(gs.head.copy(values = gs.head.values :+ Part(n, 0, args(n).length)) :: gs.tail, n + 1) + if (gs.isEmpty) parseArgs(gs, n + 1) + else + parseArgs(gs.head.copy(values = gs.head.values :+ Part( + n, 0, args(n).length)) :: gs.tail, + n + 1) } } @@ -80,24 +88,27 @@ object New { sealed class ParamException(msg: String) extends Exception(msg) - case class MissingParam(name: String) extends - ParamException(s"the parameter --$name was missing") + case class MissingParam(name: String) + extends ParamException(s"the parameter --$name was missing") - case class InvalidValue(value: String, name: String) extends - ParamException(s"the value '$value' is not valid for the parameter --$name") + case class InvalidValue(value: String, name: String) + extends ParamException( + s"the value '$value' is not valid for the parameter --$name") - case class UnexpectedParam(param: String) extends - ParamException(s"found unexpected parameter '$param'") + case class UnexpectedParam(param: String) + extends ParamException(s"found unexpected parameter '$param'") @implicitNotFound("Can not combine elements of type ${A} and ${B}") trait Construct[-A <: Params, -B <: Params] { construct => type And <: Params type Or <: Params - + def and(a: A, b: B): ProductParams[And] def or(a: A, b: B): CoproductParams[Or] - def swap: Construct[B, A] { type And = construct.And; type Or = construct.Or } = + def swap: Construct[B, A] { + type And = construct.And; type Or = construct.Or + } = new Construct[B, A] { type And = construct.And type Or = construct.Or @@ -109,8 +120,9 @@ object New { trait Construct_1 { - implicit def general[A <: Params, B <: Params]: Construct[A, B] { type And = - A with B; type Or = A with B } = { + implicit def general[A <: Params, B <: Params]: Construct[A, B] { + type And = A with B; type Or = A with B + } = { new Construct[A, B] { type And = A with B @@ -123,41 +135,51 @@ object New { } object Construct extends Construct_1 { - - implicit def leftProduct[A <: Params, B <: SimpleParam[_]]: Construct[ProductParams[A], B] { - type And = A with B; type Or = ProductParams[A] with B } = { - + + implicit def leftProduct[A <: Params, B <: SimpleParam[_]]: Construct[ + ProductParams[A], B] { + type And = A with B; type Or = ProductParams[A] with B + } = { + new Construct[ProductParams[A], B] { type And = A with B type Or = ProductParams[A] with B - def and(a: ProductParams[A], b: B) = ProductParams[A with B](a.elements + b) - + def and(a: ProductParams[A], b: B) = + ProductParams[A with B](a.elements + b) + def or(a: ProductParams[A], b: B) = CoproductParams[ProductParams[A] with B](Vector(a, b)) } } - - implicit def rightProduct[A <: SimpleParam[_], B <: Params]: Construct[A, ProductParams[B]] { - type And = B with A; type Or = ProductParams[B] with A } = leftProduct[B, A].swap - - implicit def leftCoproduct[A <: Params, B <: SimpleParam[_]]: Construct[CoproductParams[A], - B] { type And = CoproductParams[A] with B; type Or = A with B } = { - + + implicit def rightProduct[A <: SimpleParam[_], B <: Params]: Construct[ + A, ProductParams[B]] { + type And = B with A; type Or = ProductParams[B] with A + } = leftProduct[B, A].swap + + implicit def leftCoproduct[A <: Params, B <: SimpleParam[_]]: Construct[ + CoproductParams[A], B] { + type And = CoproductParams[A] with B; type Or = A with B + } = { + new Construct[CoproductParams[A], B] { type And = CoproductParams[A] with B type Or = A with B def and(a: CoproductParams[A], b: B) = ProductParams[CoproductParams[A] with B](Set(a, b)) - - def or(a: CoproductParams[A], b: B) = CoproductParams[A with B](a.elements :+ b) + + def or(a: CoproductParams[A], b: B) = + CoproductParams[A with B](a.elements :+ b) } } - - implicit def rightCoproduct[A <: SimpleParam[_], B <: Params]: Construct[A, - CoproductParams[B]] { type And = CoproductParams[B] with A; type Or = B with A } = - leftCoproduct[B, A].swap + + implicit def rightCoproduct[A <: SimpleParam[_], B <: Params]: Construct[ + A, CoproductParams[B]] { + type And = CoproductParams[B] with A; type Or = B with A + } = + leftCoproduct[B, A].swap } case class Suggestions(output: Option[Seq[Vector[String]]]) { @@ -173,29 +195,37 @@ object New { trait Params { params => type Result - - def parse(args: ParamMap, tabArg: Int = -1)(implicit suggestOutput: SuggestionOutput, - mode: Mode[`Params.parse`]): mode.Wrap[Result, ParamException] = mode.wrap { - - val (result, lastArgs, ss) = check(ParamUsage(args, Set()), mode, tabArg, Suggestions(None)) - - suggestOutput.output(ss) - - lastArgs.unexpected foreach { p => mode.exception(UnexpectedParam(p.key())) } - result - } - - def check(args: ParamUsage, mode: Mode[_], tabArg: Int, ss: Suggestions): (Result, ParamUsage, Suggestions) - - def &[B <: Params](b: B)(implicit con: Construct[params.type, b.type]): - ProductParams[con.And] = { - + + def parse(args: ParamMap, tabArg: Int = -1)( + implicit suggestOutput: SuggestionOutput, + mode: Mode[`Params.parse`]): mode.Wrap[Result, ParamException] = + mode.wrap { + + val (result, lastArgs, ss) = + check(ParamUsage(args, Set()), mode, tabArg, Suggestions(None)) + + suggestOutput.output(ss) + + lastArgs.unexpected foreach { p => + mode.exception(UnexpectedParam(p.key())) + } + result + } + + def check(args: ParamUsage, + mode: Mode[_], + tabArg: Int, + ss: Suggestions): (Result, ParamUsage, Suggestions) + + def &[B <: Params](b: B)(implicit con: Construct[params.type, b.type] + ): ProductParams[con.And] = { + con.and(this, b) } - def |[B <: Params](b: B)(implicit con: Construct[params.type, b.type]): - CoproductParams[con.Or] = { - + def |[B <: Params](b: B)(implicit con: Construct[params.type, b.type] + ): CoproductParams[con.Or] = { + con.or(this, b) } @@ -211,27 +241,35 @@ object New { case class OptionParams[Ps <: Params](params: Ps) extends Params { type Result = Option[params.Result] - def check(args: ParamUsage, mode: Mode[_], tabArg: Int, ss: Suggestions): - (Result, ParamUsage, Suggestions) = try { - - val (res, newArgs, newSs) = params.check(args, mode, tabArg, ss) - (Some(res), newArgs, newSs) - } catch { case e: Exception => (None, args, ss) } + def check(args: ParamUsage, + mode: Mode[_], + tabArg: Int, + ss: Suggestions): (Result, ParamUsage, Suggestions) = + try { + + val (res, newArgs, newSs) = params.check(args, mode, tabArg, ss) + (Some(res), newArgs, newSs) + } catch { case e: Exception => (None, args, ss) } override def toString = s"[$params]" } - case class ProductParams[Ps <: Params](elements: Set[Params]) extends Params { + case class ProductParams[Ps <: Params](elements: Set[Params]) + extends Params { type ProductTypes = Ps type Result = Product[ProductTypes] - def check(args: ParamUsage, mode: Mode[_], tabArg: Int, ss: Suggestions): (Result, ParamUsage, Suggestions) = { + def check(args: ParamUsage, + mode: Mode[_], + tabArg: Int, + ss: Suggestions): (Result, ParamUsage, Suggestions) = { - val (finalArgs, finalElems, newSs) = elements.foldLeft((args, Set[(Params, Any)](), ss)) { - case ((args, es, ss), key) => - val (res, nextArgs, newSs) = key.check(args, mode, tabArg, ss) - (nextArgs, es + (key -> res), ss orElse newSs) - } + val (finalArgs, finalElems, newSs) = + elements.foldLeft((args, Set[(Params, Any)](), ss)) { + case ((args, es, ss), key) => + val (res, nextArgs, newSs) = key.check(args, mode, tabArg, ss) + (nextArgs, es + (key -> res), ss orElse newSs) + } (new Product[Ps](finalElems.toMap), finalArgs, newSs) } @@ -239,19 +277,25 @@ object New { override def toString = elements.mkString("( ", " & ", " )") } - case class CoproductParams[Ps <: Params](elements: Vector[Params]) extends Params { + case class CoproductParams[Ps <: Params](elements: Vector[Params]) + extends Params { type CoproductTypes = Ps type Result = Coproduct[CoproductTypes] - - def check(args: ParamUsage, mode: Mode[_], tabArg: Int, ss: Suggestions): (Result, ParamUsage, Suggestions) = { + + def check(args: ParamUsage, + mode: Mode[_], + tabArg: Int, + ss: Suggestions): (Result, ParamUsage, Suggestions) = { val elems = elements.to[List].flatMap { k => Try(Option(k.check(args, mode, tabArg, ss)).get).toOption.map(k -> _) } - + elems match { - case (key, (res, args, newSs)) :: Nil => (Coproduct[CoproductTypes](key -> res), args, newSs) + case (key, (res, args, newSs)) :: Nil => + (Coproduct[CoproductTypes](key -> res), args, newSs) case Nil => mode.exception(MissingParam(toString)) - case _ :: (key, _) :: _ => mode.exception(UnexpectedParam(key.toString)) + case _ :: (key, _) :: _ => + mode.exception(UnexpectedParam(key.toString)) } } @@ -260,16 +304,17 @@ object New { object ToSuggestion { - implicit val stringSuggestion: ToSuggestion[String] = new ToSuggestion[String] { - def suggestion(value: String): Vector[String] = Vector(value) - } + implicit val stringSuggestion: ToSuggestion[String] = + new ToSuggestion[String] { + def suggestion(value: String): Vector[String] = Vector(value) + } } trait ToSuggestion[T] { def suggestion(value: T): Vector[String] } - case class SimpleParam[T: Param.Extractor](val keys: Vector[String]) extends Params { - simpleParam => + case class SimpleParam[T : Param.Extractor](val keys: Vector[String]) + extends Params { simpleParam => type Result = T @@ -277,43 +322,58 @@ object New { def suggestions(s: String): Seq[T] = Seq() def checkValue: Option[T] = None - def suggest(suggestions: T*)(implicit sug: ToSuggestion[T]): SimpleParam[T] = - suggest { s => suggestions } + def suggest(suggestions: T*)( + implicit sug: ToSuggestion[T]): SimpleParam[T] = + suggest { s => + suggestions + } - def suggest(suggestions: String => Seq[T])(implicit sug: ToSuggestion[T]): - SimpleParam[T] = { + def suggest(suggestions: String => Seq[T])( + implicit sug: ToSuggestion[T]): SimpleParam[T] = { val ss = suggestions new SimpleParam[T](keys) { - override def toSuggestion(value: T): Vector[String] = sug.suggestion(value) + override def toSuggestion(value: T): Vector[String] = + sug.suggestion(value) override def suggestions(s: String) = ss(s) override def checkValue = simpleParam.checkValue } } def filter(fn: T => Boolean): SimpleParam[T] = new SimpleParam[T](keys) { - override def toSuggestion(value: T): Vector[String] = simpleParam.toSuggestion(value) - override def suggestions(str: String) = simpleParam.suggestions(str).filter(fn) + override def toSuggestion(value: T): Vector[String] = + simpleParam.toSuggestion(value) + override def suggestions(str: String) = + simpleParam.suggestions(str).filter(fn) override def checkValue = simpleParam.checkValue } protected val extractor = ?[Param.Extractor[T]] - def check(args: ParamUsage, mode: Mode[_], tabArg: Int, ss: Suggestions): - (Result, ParamUsage, Suggestions) = { - - val parameter = args.map(keys) getOrElse mode.exception(MissingParam(keys.head)) + def check(args: ParamUsage, + mode: Mode[_], + tabArg: Int, + ss: Suggestions): (Result, ParamUsage, Suggestions) = { - val res = extractor.extract(parameter.values.map(_())) getOrElse { - mode.exception(InvalidValue(parameter.key(), parameter.values.mkString(" "))) + val parameter = + args.map(keys) getOrElse mode.exception(MissingParam(keys.head)) + + val res = + extractor.extract(parameter.values.map(_ ())) getOrElse { + mode.exception( + InvalidValue(parameter.key(), parameter.values.mkString(" "))) + } + + checkValue.foreach { v => + if (v != res) mode.exception(InvalidValue(keys.head, "invalid")) } - - - checkValue.foreach { v => if(v != res) mode.exception(InvalidValue(keys.head, "invalid")) } - - val newSs = Suggestions(parameter.values.find(tabArg == _.no).map { p => - suggestions(p()).map(toSuggestion) - }) - + + val newSs = Suggestions( + parameter.values + .find(tabArg == _.no) + .map { p => + suggestions(p()).map(toSuggestion) + }) + (res, args -- keys.to[Set], ss orElse newSs) } @@ -321,32 +381,38 @@ object New { override def hashCode = keys.hashCode ^ extractor.hashCode override def equals(that: Any) = that match { - case that: SimpleParam[_] => + case that: SimpleParam [_] => keys.to[Set] == that.keys.to[Set] && that.extractor == extractor case _ => false } - override def toString = keys.map { k => if(k.length == 1) s"-$k" else s"--$k" }.mkString("/") + override def toString = + keys.map { k => + if (k.length == 1) s"-$k" else s"--$k" + }.mkString("/") def of(v: T): SimpleParam[T] = new SimpleParam[T](keys) { - override def toSuggestion(value: T): Vector[String] = simpleParam.toSuggestion(value) + override def toSuggestion(value: T): Vector[String] = + simpleParam.toSuggestion(value) override def suggestions(str: String) = simpleParam.suggestions(str) override def checkValue = Some(v) } } object Param { - + object Extractor { implicit val stringExtractor: Extractor[String] = new Extractor[String] { // FIXME: Add mode parameter, and capture failure types - def extract(values: Vector[String]): Option[String] = Some(values.mkString(" ")) + def extract(values: Vector[String]): Option[String] = + Some(values.mkString(" ")) } implicit val intExtractor: Extractor[Int] = new Extractor[Int] { def extract(values: Vector[String]): Option[Int] = values match { - case Vector(v) => try Some(v.toInt) catch { case e: Exception => None } + case Vector(v) => + try Some(v.toInt) catch { case e: Exception => None } case _ => None } } @@ -363,26 +429,32 @@ object New { def handle(v: From): H } - def apply[T: Extractor](shortName: Char, longName: Symbol): SimpleParam[T] = + def apply[T : Extractor]( + shortName: Char, longName: Symbol): SimpleParam[T] = alloc(Vector(shortName.toString, longName.name)) - - def apply[T: Extractor](shortName: Char): SimpleParam[T] = + + def apply[T : Extractor](shortName: Char): SimpleParam[T] = alloc(Vector(shortName.toString)) - - def apply[T: Extractor](longName: Symbol): SimpleParam[T] = alloc(Vector(longName.name)) - + + def apply[T : Extractor](longName: Symbol): SimpleParam[T] = + alloc(Vector(longName.name)) + def flag(shortName: Char, longName: Symbol): SimpleParam[Unit] = alloc(Vector(shortName.toString, longName.name)) - - def flag(shortName: Char): SimpleParam[Unit] = alloc(Vector(shortName.toString)) - def flag(longName: Symbol): SimpleParam[Unit] = alloc(Vector(longName.name)) + + def flag(shortName: Char): SimpleParam[Unit] = + alloc(Vector(shortName.toString)) + def flag(longName: Symbol): SimpleParam[Unit] = + alloc(Vector(longName.name)) } @implicitNotFound("product does not contain this value") trait ProductContainsParam[V, T] object ProductContainsParam extends ProductContainsParam_1 { - implicit def optional[V <: OptionParams[_ <: Params], P <: Params]: ProductContainsParam[V, P] = null + implicit def optional[ + V <: OptionParams[_ <: Params], P <: Params]: ProductContainsParam[ + V, P] = null } trait ProductContainsParam_1 { implicit def generic[V, T <: V]: ProductContainsParam[V, T] = null @@ -396,10 +468,12 @@ object New { } case class Product[T <: Params](tmap: Map[Params, Any]) { - def apply[V <: Params](value: V)(implicit acc: ProductContainsParam[value.type, T]): - value.Result = tmap(value).asInstanceOf[value.Result] - - override def toString = tmap.map { case (k, v) => s"$k: $v" }.mkString(", ") + def apply[V <: Params](value: V)( + implicit acc: ProductContainsParam[value.type, T]): value.Result = + tmap(value).asInstanceOf[value.Result] + + override def toString = + tmap.map { case (k, v) => s"$k: $v" }.mkString(", ") } case class Coproduct[T <: Params](value: (Params, Any)) { diff --git a/cli/shared/src/main/scala/rapture/cli/process.scala b/cli/shared/src/main/scala/rapture/cli/process.scala index 7475b44..dec98be 100644 --- a/cli/shared/src/main/scala/rapture/cli/process.scala +++ b/cli/shared/src/main/scala/rapture/cli/process.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -28,25 +28,32 @@ import language.higherKinds trait `Process#exec` extends MethodConstraint case class Process(params: Vector[String]) { - def exec[T: ProcessInterpreter](implicit mode: Mode[`Process#exec`], env: Environment): - mode.Wrap[T, CliException] = mode.wrap { - val javaProcess = Runtime.getRuntime().exec(params.to[Array], - env().map { case (k, v) => s"$k=$v" }.to[Array], - new File(env.workDir.getOrElse(System.getenv("HOME")))) - val stream = new ByteInput(new BufferedInputStream(javaProcess.getInputStream)) - val stderr = new ByteInput(new BufferedInputStream(javaProcess.getErrorStream)) - ?[ProcessInterpreter[T]].interpret(stream, stderr, () => javaProcess.waitFor()) + def exec[T : ProcessInterpreter]( + implicit mode: Mode[`Process#exec`], + env: Environment): mode.Wrap[T, CliException] = mode.wrap { + val javaProcess = Runtime + .getRuntime() + .exec(params.to[Array], + env().map { case (k, v) => s"$k=$v" }.to[Array], + new File(env.workDir.getOrElse(System.getenv("HOME")))) + val stream = + new ByteInput(new BufferedInputStream(javaProcess.getInputStream)) + val stderr = + new ByteInput(new BufferedInputStream(javaProcess.getErrorStream)) + ?[ProcessInterpreter[T]] + .interpret(stream, stderr, () => javaProcess.waitFor()) } override def toString = { - val escaped = params.map(_.flatMap { + val escaped = params.map( + _.flatMap { case '\'' => "\\'" case '"' => "\\\"" case '\\' => "\\\\" case ' ' => "\\ " case chr => chr.toString }) - + s"""sh"${escaped.mkString(" ")}"""" } } @@ -69,58 +76,68 @@ trait Environment { package environments { object empty { def apply(): Environment = implicitEnvironment - implicit val implicitEnvironment: Environment = - new Environment { - def apply(): Map[String, String] = Map() - def workDir = None - } + implicit val implicitEnvironment: Environment = new Environment { + def apply(): Map[String, String] = Map() + def workDir = None + } } object enclosing { def apply(): Environment = implicitEnvironment - implicit val implicitEnvironment: Environment = Environment.defaultEnvironment + implicit val implicitEnvironment: Environment = + Environment.defaultEnvironment } } trait ProcessInterpreter_1 { - implicit def genSeqInterpreter[Coll[_], T](implicit cbf: - collection.generic.CanBuildFrom[Nothing, T, Coll[T]], stringParser: StringParser[T]): - ProcessInterpreter[Coll[T]] = new ProcessInterpreter[Coll[T]] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): - Coll[T] = { - val out = input.slurp[Char] - exitStatus() match { - case 0 => - val builder = cbf() - // FIXME: Reimplement this using a streaming method - out.split("\n").foreach { s => builder += stringParser.parse(s, modes.throwExceptions()) } - builder.result() - case n => - throw ShellProcessException(n, out.trim) + implicit def genSeqInterpreter[Coll[_], T]( + implicit cbf: collection.generic.CanBuildFrom[Nothing, T, Coll[T]], + stringParser: StringParser[T]): ProcessInterpreter[Coll[T]] = + new ProcessInterpreter[Coll[T]] { + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): Coll[T] = { + val out = input.slurp[Char] + exitStatus() match { + case 0 => + val builder = cbf() + // FIXME: Reimplement this using a streaming method + out.split("\n").foreach { s => + builder += stringParser.parse(s, modes.throwExceptions()) + } + builder.result() + case n => + throw ShellProcessException(n, out.trim) + } } } - } - } - + object ProcessInterpreter extends ProcessInterpreter_1 { - - implicit def stringProcessInterpreter[T](implicit stringParser: StringParser[T]): ProcessInterpreter[T] = + + implicit def stringProcessInterpreter[T]( + implicit stringParser: StringParser[T]): ProcessInterpreter[T] = new ProcessInterpreter[T] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): T = { + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): T = { val out = input.slurp[Char] val err = stderr.slurp[Char] exitStatus() match { case n => - stringParser.parse(if(out == "" || out.last != '\n') out else out.init, modes.throwExceptions()) + stringParser.parse( + if (out == "" || out.last != '\n') out else out.init, + modes.throwExceptions()) //case n => throw ShellProcessException(n, out.trim) } } } - + implicit val bytesProcessInterpreter: ProcessInterpreter[Bytes] = new ProcessInterpreter[Bytes] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): Bytes = { + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): Bytes = { val out = input.slurp[Byte] exitStatus() match { case 0 => out @@ -128,31 +145,39 @@ object ProcessInterpreter extends ProcessInterpreter_1 { } } } - + implicit val byteInputProcessInterpreter: ProcessInterpreter[Input[Byte]] = new ProcessInterpreter[Input[Byte]] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): Input[Byte] = input + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): Input[Byte] = input } - - implicit def inputProcessInterpreter[T](implicit rdr: Reader[Input[Byte], T]): - ProcessInterpreter[Input[T]] = + + implicit def inputProcessInterpreter[T]( + implicit rdr: Reader[Input[Byte], T]): ProcessInterpreter[Input[T]] = new ProcessInterpreter[Input[T]] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): Input[T] = + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): Input[T] = input.input[T] } - + implicit val exitStatusProcessInterpreter: ProcessInterpreter[ExitStatus] = new ProcessInterpreter[ExitStatus] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): ExitStatus = + def interpret(input: Input[Byte], + stderr: Input[Byte], + exitStatus: () => Int): ExitStatus = ExitStatus(exitStatus()) } } trait ProcessInterpreter[T] { - def interpret(input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): T + def interpret( + input: Input[Byte], stderr: Input[Byte], exitStatus: () => Int): T } -case class ShellProcessException(exitStatus: Int, output: String) extends - Exception("Shell process returned non-zero exit status: "+exitStatus) +case class ShellProcessException(exitStatus: Int, output: String) + extends Exception( + "Shell process returned non-zero exit status: " + exitStatus) case class ExitStatus(value: Int) diff --git a/cli/shared/src/main/scala/rapture/cli/tabulate.scala b/cli/shared/src/main/scala/rapture/cli/tabulate.scala index f927536..15c3a95 100644 --- a/cli/shared/src/main/scala/rapture/cli/tabulate.scala +++ b/cli/shared/src/main/scala/rapture/cli/tabulate.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -24,7 +24,7 @@ object Tabulation { sealed trait Position case object Right extends Position case object Left extends Position - + trait Col_1 { implicit def anyToCol(s: Any): Col = Col(s.toString, Left) } @@ -33,19 +33,24 @@ object Tabulation { implicit def stringToCol(s: String): Col = Col(s, Left) } case class Col(content: String, position: Position = Left) - def tabulate[C[E] <: Seq[E], T](collection: Seq[T], titles: Option[Seq[Col]] = None)(cols: - (T => Col)*): Seq[String] = { - val contents = collection.map { e => cols.map(_(e)) } - + def tabulate[C[E] <: Seq[E], T]( + collection: Seq[T], titles: Option[Seq[Col]] = None)( + cols: (T => Col)*): Seq[String] = { + val contents = collection.map { e => + cols.map(_ (e)) + } + val contentsWithTitles = titles.map { ts => - ts +: (ts.map { case Col(s, p) => Col(s.map(c => '-'), p) }) +: contents + ts +:(ts.map { case Col(s, p) => Col(s.map(c => '-'), p) }) +: contents }.getOrElse(contents) - - val widths = contentsWithTitles.map { _.map(_.content.length) }.reduce(_ zip _ map { case (a, b) => a max b }) - contentsWithTitles.map(_.zip(widths).map { - case (Col(s, Right), w) => " "*(w - s.length)+s+" " - case (Col(s, Left), w) => s+(" "*(w - s.length))+" " + val widths = contentsWithTitles.map { _.map(_.content.length) } + .reduce(_ zip _ map { case (a, b) => a max b }) + + contentsWithTitles.map( + _.zip(widths).map { + case (Col(s, Right), w) => " " * (w - s.length) + s + " " + case (Col(s, Left), w) => s + (" " * (w - s.length)) + " " }.mkString) } } diff --git a/cli/shared/src/main/scala/rapture/cli/zsh.scala b/cli/shared/src/main/scala/rapture/cli/zsh.scala index 2bd7516..c5e05ea 100644 --- a/cli/shared/src/main/scala/rapture/cli/zsh.scala +++ b/cli/shared/src/main/scala/rapture/cli/zsh.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli @@ -23,8 +23,9 @@ object Encoder { private val Translations = "<>#{}|\\^~[]`/?:@=&$!*:; ".to[Vector] def encode(s: String): String = s flatMap { c => - if(Translations contains c) { - "%"+(c/16 + c/160*7 + 48).toChar+(c%16 + c%16/10*7 + 48).toChar + if (Translations contains c) { + "%" + (c / 16 + c / 160 * 7 + 48).toChar + + (c % 16 + c % 16 / 10 * 7 + 48).toChar } else c.toString } } @@ -36,27 +37,34 @@ object Compadd { def padRows(lists: Vector[Vector[String]]): Vector[String] = { val widths = maxWidths(lists) - lists.map(_.zip(widths).map { case (s, w) => s.padTo(w, ' ') }.mkString(" ")) + lists.map( + _.zip(widths).map { case (s, w) => s.padTo(w, ' ') }.mkString(" ")) } - def apply(groupTitle: Option[String] = None, completions: Vector[String] = Vector(), - columns: Boolean = true, descriptions: String => Vector[String] = _ => Vector(), - colWidth: Int = 1000, hidden: Boolean): Vector[String] = { - + def apply(groupTitle: Option[String] = None, + completions: Vector[String] = Vector(), + columns: Boolean = true, + descriptions: String => Vector[String] = _ => Vector(), + colWidth: Int = 1000, + hidden: Boolean): Vector[String] = { + val display: Option[Vector[String]] = { val ds: Vector[Vector[String]] = completions.to[Vector] map descriptions - if(ds.forall(_.isEmpty)) None + if (ds.forall(_.isEmpty)) None else Some(padRows(completions zip ds map { case (c, d) => c +: d })) } - - display.toVector.flatten.map(s => "let "+Encoder.encode(s.take(colWidth - 1))) :+ Vector.strap( - "compadd", - groupTitle.to[Vector].flatMap(Seq("-J", _)), - if(columns) Some("-l") else None, - if(hidden) None else Some("-d matches"), - if(hidden) Some("-n") else None, - "--", - completions.map(Encoder.encode) - ).mkString(" ") + + display.toVector.flatten + .map(s => "let " + Encoder.encode(s.take(colWidth - 1))) :+ Vector + .strap( + "compadd", + groupTitle.to[Vector].flatMap(Seq("-J", _)), + if (columns) Some("-l") else None, + if (hidden) None else Some("-d matches"), + if (hidden) Some("-n") else None, + "--", + completions.map(Encoder.encode) + ) + .mkString(" ") } } diff --git a/cli/shared/src/test/scala/rapture/cli/tests.scala b/cli/shared/src/test/scala/rapture/cli/tests.scala index 6bf10fa..d575582 100644 --- a/cli/shared/src/test/scala/rapture/cli/tests.scala +++ b/cli/shared/src/test/scala/rapture/cli/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.cli.test @@ -309,4 +309,4 @@ object CliTests extends TestSuite { Captured.last() } returns Vector(Vector("red"), Vector("green"), Vector("blue")) } -*/ + */ diff --git a/codec/shared/src/main/scala/rapture/codec/base64.scala b/codec/shared/src/main/scala/rapture/codec/base64.scala index 33b1431..b3cf5cb 100644 --- a/codec/shared/src/main/scala/rapture/codec/base64.scala +++ b/codec/shared/src/main/scala/rapture/codec/base64.scala @@ -13,62 +13,70 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.codec import rapture.core._ /** RFC2045 base-64 codec, based on http://migbase64.sourceforge.net/. */ -class Base64Codec[C <: CodecType](val char62: Char = '+', val char63: Char = '/', val padChar: Char = '=', - val lineBreaks: Boolean = false, val endPadding: Boolean = false) extends ByteCodec[C] { - +class Base64Codec[C <: CodecType](val char62: Char = '+', + val char63: Char = '/', + val padChar: Char = '=', + val lineBreaks: Boolean = false, + val endPadding: Boolean = false) + extends ByteCodec[C] { + private val alphabet = - ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"+char62+char63).toCharArray - + ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" + + char62 + char63).toCharArray + private lazy val decodabet = { val x: Array[Int] = alloc(256) - for(i <- 0 until alphabet.length) x(alphabet(i)) = i + for (i <- 0 until alphabet.length) x(alphabet(i)) = i x } /** Non-RFC-compliant encoder. */ - /** Encoder. The RFC requires that line breaks be added every 76 chars, and * that the data be padded to a multiple of 4 chars, but we do these things * optionally. */ def encode(in: Array[Byte]): String = { - + var inLen = in.length - - if(inLen == 0) "" else { - val evenLen = (inLen/3)*3 - val outDataLen = if(endPadding) ((inLen - 1)/3 + 1) << 2 else ((inLen << 2) + 2 )/3 - val outLen = if(lineBreaks) outDataLen + (outDataLen - 1)/76 << 1 else outDataLen + + if (inLen == 0) "" + else { + val evenLen = (inLen / 3) * 3 + val outDataLen = + if (endPadding) ((inLen - 1) / 3 + 1) << 2 else ((inLen << 2) + 2) / 3 + val outLen = + if (lineBreaks) outDataLen + (outDataLen - 1) / 76 << 1 else outDataLen val out: Array[Char] = alloc(outLen) var inPos = 0 var outPos = 0 var blockCount = 0 - - while(inPos < evenLen) { - val block = (in(inPos) & 0xFF) << 16 | (in(inPos + 1) & 0xFF) << 8 | (in(inPos + 2) & - 0xFF) - + + while (inPos < evenLen) { + val block = + (in(inPos) & 0xFF) << 16 | (in(inPos + 1) & 0xFF) << 8 | + (in(inPos + 2) & 0xFF) + inPos += 3 - + out(outPos) = alphabet((block >>> 18) & 0x3F) out(outPos + 1) = alphabet((block >>> 12) & 0x3F) out(outPos + 2) = alphabet((block >>> 6) & 0x3F) out(outPos + 3) = alphabet(block & 0x3F) - + outPos += 4 - if(lineBreaks) { - + if (lineBreaks) { + blockCount += 1 - - if(blockCount == 19 && outPos < outLen - 2) { + + if (blockCount == 19 && outPos < outLen - 2) { out(outPos) = '\r' out(outPos + 1) = '\n' outPos += 2 @@ -78,21 +86,22 @@ class Base64Codec[C <: CodecType](val char62: Char = '+', val char63: Char = '/' } val left = inLen - evenLen - - if(left > 0) { - + + if (left > 0) { + val block = - ((in(evenLen) & 0xFF) << 10) | (if(left == 2) (in(inLen - 1) & 0xFF) << 2 else 0) - + ((in(evenLen) & 0xFF) << 10) | + (if (left == 2) (in(inLen - 1) & 0xFF) << 2 else 0) + out(outPos) = alphabet(block >>> 12) out(outPos + 1) = alphabet((block >>> 6) & 0x3F) - - if(left == 2) out(outPos + 2) = alphabet(block & 0x3F) - else if(endPadding) out(outPos + 2) = padChar - - if(endPadding) out(outPos + 3) = padChar + + if (left == 2) out(outPos + 2) = alphabet(block & 0x3F) + else if (endPadding) out(outPos + 2) = padChar + + if (endPadding) out(outPos + 3) = padChar } - + alloc(out) } } @@ -105,27 +114,32 @@ class Base64Codec[C <: CodecType](val char62: Char = '+', val char63: Char = '/' val in = data.toCharArray() val inLen = in.length - - if(inLen == 0) Right(alloc(0)) else { - - val padding = if(in(inLen - 1) == padChar) (if(in(inLen - 2) == padChar) 2 else 1) else 0 + + if (inLen == 0) Right(alloc(0)) + else { + + val padding = + if (in(inLen - 1) == padChar) (if (in(inLen - 2) == padChar) 2 else 1) + else 0 // FIXME: This doesn't seem to accommodate different kinds of linebreak - val lineBreaks = if(inLen > 76) (if(in(76) == '\r') inLen/78 else 0) << 1 else 0 + val lineBreaks = + if (inLen > 76) (if (in(76) == '\r') inLen / 78 else 0) << 1 else 0 val outLen = ((inLen - lineBreaks) * 6 >> 3) - padding val out: Array[Byte] = alloc(outLen) var inPos = 0 var outPos = 0 var blockCount = 0 - - val evenLen = (outLen/3)*3 - - while(outPos < evenLen) { - - val block = decodabet(in(inPos)) << 18 | decodabet(in(inPos + 1)) << 12 | - decodabet(in(inPos + 2)) << 6 | decodabet(in(inPos + 3)) - + + val evenLen = (outLen / 3) * 3 + + while (outPos < evenLen) { + + val block = + decodabet(in(inPos)) << 18 | decodabet(in(inPos + 1)) << 12 | decodabet( + in(inPos + 2)) << 6 | decodabet(in(inPos + 3)) + inPos += 4 out(outPos) = (block >> 16).toByte @@ -133,24 +147,26 @@ class Base64Codec[C <: CodecType](val char62: Char = '+', val char63: Char = '/' out(outPos + 2) = block.toByte outPos += 3 - if(lineBreaks > 0) { - + if (lineBreaks > 0) { + blockCount += 1 - - if(blockCount == 19) { + + if (blockCount == 19) { inPos += 2 blockCount = 0 } } } - if(outPos < outLen) { - val block = decodabet(in(inPos)) << 18 | decodabet(in(inPos + 1)) << 12 | - (if(inPos + 2 < inLen - padding) decodabet(in(inPos + 2)) << 6 else 0) + if (outPos < outLen) { + val block = + decodabet(in(inPos)) << 18 | decodabet(in(inPos + 1)) << 12 | + (if (inPos + 2 < inLen - padding) decodabet(in(inPos + 2)) << 6 + else 0) out(outPos) = (block >> 16).toByte - - if(outPos + 1 < outLen) out(outPos + 1) = (block >> 8).toByte + + if (outPos + 1 < outLen) out(outPos + 1) = (block >> 8).toByte } Right(out) diff --git a/codec/shared/src/main/scala/rapture/codec/bytes.scala b/codec/shared/src/main/scala/rapture/codec/bytes.scala index 2deafec..53c8c54 100644 --- a/codec/shared/src/main/scala/rapture/codec/bytes.scala +++ b/codec/shared/src/main/scala/rapture/codec/bytes.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.codec @@ -24,20 +24,25 @@ import scala.collection.generic.CanBuildFrom import language.higherKinds object `package` { - implicit def bytesParser(implicit enc: Encoding): StringParser[Bytes] { type Throws = Nothing } = new StringParser[Bytes] { - type Throws = Nothing // We would like to throw an EncodingException if we try to decode an invalid byte - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Bytes, Nothing] = mode.wrap { - Bytes(s.getBytes("UTF-8")) + implicit def bytesParser( + implicit enc: Encoding): StringParser[Bytes] { type Throws = Nothing } = + new StringParser[Bytes] { + type Throws = Nothing // We would like to throw an EncodingException if we try to decode an invalid byte + def parse(s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Bytes, Nothing] = + mode.wrap { + Bytes(s.getBytes("UTF-8")) + } } - } } trait FromBytes[T] { def build(bytes: Array[Byte]): T } object FromBytes { - implicit def stringFromBytes(implicit enc: Encoding): FromBytes[String] = new FromBytes[String] { - def build(bytes: Array[Byte]): String = new String(bytes, enc.name) - } + implicit def stringFromBytes(implicit enc: Encoding): FromBytes[String] = + new FromBytes[String] { + def build(bytes: Array[Byte]): String = new String(bytes, enc.name) + } implicit def bytesFromBytes = new FromBytes[Array[Byte]] { def build(bytes: Array[Byte]): Array[Byte] = bytes @@ -55,7 +60,8 @@ trait Base32 extends CodecType trait Binary extends CodecType object decode { - def apply[C <: CodecType: ByteCodec](s: String)(implicit mode: Mode[`decode.apply`]): mode.Wrap[Bytes, DecodeException] = + def apply[C <: CodecType : ByteCodec](s: String)( + implicit mode: Mode[`decode.apply`]): mode.Wrap[Bytes, DecodeException] = mode wrap { try { implicitly[ByteCodec[C]].decode(s) match { @@ -67,27 +73,34 @@ object decode { } object ByteCodec { - implicit val base64Url: ByteCodec[Base64Url] = new Base64Codec('-', '_', '=', false, false) - implicit val base64: ByteCodec[Base64] = new Base64Codec('+', '/', '=', false, false) + implicit val base64Url: ByteCodec[Base64Url] = new Base64Codec( + '-', '_', '=', false, false) + implicit val base64: ByteCodec[Base64] = new Base64Codec( + '+', '/', '=', false, false) implicit val hex: ByteCodec[Hex] = new ByteCodec[Hex] { def encode(array: Array[Byte]): String = - alloc(array flatMap { n => + alloc( + array flatMap { n => Array((n & 255) >> 4 & 15, n & 15) } map { _ + 48 } map { i => - (if(i > 57) i + 39 else i).toChar + (if (i > 57) i + 39 else i).toChar }) def decode(s: String): Either[Int, Array[Byte]] = - Right((if(s.length%2 == 0) s else "0"+s).to[Array].grouped(2).to[Array] map { case Array(l, r) => - (((l - 48)%39 << 4) + (r - 48)%39).toByte + Right( + (if (s.length % 2 == 0) + s else "0" + s).to[Array].grouped(2).to[Array] map { + case Array(l, r) => + (((l - 48) % 39 << 4) + (r - 48) % 39).toByte }) } implicit val binary: ByteCodec[Binary] = new ByteCodec[Binary] { def encode(array: Array[Byte]): String = - alloc(Array.range(0, array.length*8) map { i => - if((array(i/8) & (1 << (7 - i%8))) > 0) 49.toByte else 48.toByte + alloc( + Array.range(0, array.length * 8) map { i => + if ((array(i / 8) & (1 << (7 - i % 8))) > 0) 49.toByte else 48.toByte }) def decode(s: String): Either[Int, Array[Byte]] = { @@ -106,29 +119,32 @@ object Bytes { } case class Bytes(bytes: Array[Byte]) { - def encode[Codec <: CodecType: ByteCodec]: String = + def encode[Codec <: CodecType : ByteCodec]: String = implicitly[ByteCodec[Codec]].encode(bytes) - + override def toString = encode[Hex] def ++(that: Bytes): Bytes = Bytes(bytes ++ that.bytes) override def equals(that: Any) = that match { case Bytes(bs) => - bs.length == bytes.length && (bs zip bytes forall { case (a, b) => a == b }) + bs.length == bytes.length && + (bs zip bytes forall { case (a, b) => a == b }) case _ => false } - override def hashCode = bytes.foldLeft(bytes.length)(_*131 + _) + override def hashCode = bytes.foldLeft(bytes.length)(_ * 131 + _) /** Sets all values in the underlying byte array to zeroes. This is useful if the `Bytes` * instance was storing sensitive data, such as a private key. */ def zero() = (0 until bytes.length) foreach { bytes(_) = 0 } - def as[T: FromBytes](implicit mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DecodeException] = mode.wrap { + def as[T : FromBytes](implicit mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[T, DecodeException] = mode.wrap { try ?[FromBytes[T]].build(bytes) catch { - case e: Exception => mode.exception[T, DecodeException](DecodeException(None)) + case e: Exception => + mode.exception[T, DecodeException](DecodeException(None)) } } @@ -138,7 +154,7 @@ case class Bytes(bytes: Array[Byte]) { def length: Int = bytes.length - def to[Coll[_]](implicit cbf: CanBuildFrom[Nothing, Byte, Coll[Byte]]): Coll[Byte] = + def to[Coll[_]]( + implicit cbf: CanBuildFrom[Nothing, Byte, Coll[Byte]]): Coll[Byte] = bytes.to[Coll] } - diff --git a/codec/shared/src/main/scala/rapture/codec/encodings.scala b/codec/shared/src/main/scala/rapture/codec/encodings.scala index 656d0e7..40ac897 100644 --- a/codec/shared/src/main/scala/rapture/codec/encodings.scala +++ b/codec/shared/src/main/scala/rapture/codec/encodings.scala @@ -13,13 +13,14 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.codec import rapture.core._ -@implicitNotFound("Character encoding has not been provided. Please specify an implicit "+ +@implicitNotFound( + "Character encoding has not been provided. Please specify an implicit " + "Encoding value, e.g. import encodings.system._ or import encodings.`UTF-8`._.") case class Encoding(name: String) { def index = name } @@ -35,7 +36,7 @@ case class EncodingImplicit(name: String) { * require escaping with backticks in order to be referenced, however type safety will be * ensured. */ object encodings { - + implicit val `US-ASCII` = EncodingImplicit("US-ASCII") implicit val `windows-1250` = EncodingImplicit("windows-1250") implicit val `windows-1251` = EncodingImplicit("windows-1251") @@ -58,31 +59,31 @@ object encodings { implicit val `UTF-16LE` = EncodingImplicit("UTF-16LE") /** The default file system encoding for this system */ - implicit lazy val system = EncodingImplicit(System.getProperty("file.encoding")) + implicit lazy val system = EncodingImplicit( + System.getProperty("file.encoding")) private val allEncodings: Map[String, Encoding] = Map( - ("US-ASCII", `US-ASCII`()), - ("windows-1250", `windows-1250`()), - ("windows-1251", `windows-1251`()), - ("windows-1252", `windows-1252`()), - ("windows-1253", `windows-1253`()), - ("windows-1254", `windows-1254`()), - ("windows-1257", `windows-1257`()), - ("ISO-8859-1", `ISO-8859-1`()), - ("ISO-8859-2", `ISO-8859-2`()), - ("ISO-8859-4", `ISO-8859-4`()), - ("ISO-8859-5", `ISO-8859-5`()), - ("ISO-8859-7", `ISO-8859-7`()), - ("ISO-8859-9", `ISO-8859-9`()), - ("ISO-8859-13", `ISO-8859-13`()), - ("ISO-8859-15", `ISO-8859-15`()), - ("KOI8-R", `KOI8-R`()), - ("UTF-8", `UTF-8`()), - ("UTF-16", `UTF-16`()), - ("UTF-16BE", `UTF-16BE`()), - ("UTF-16LE", `UTF-16LE`()) + ("US-ASCII", `US-ASCII`()), + ("windows-1250", `windows-1250`()), + ("windows-1251", `windows-1251`()), + ("windows-1252", `windows-1252`()), + ("windows-1253", `windows-1253`()), + ("windows-1254", `windows-1254`()), + ("windows-1257", `windows-1257`()), + ("ISO-8859-1", `ISO-8859-1`()), + ("ISO-8859-2", `ISO-8859-2`()), + ("ISO-8859-4", `ISO-8859-4`()), + ("ISO-8859-5", `ISO-8859-5`()), + ("ISO-8859-7", `ISO-8859-7`()), + ("ISO-8859-9", `ISO-8859-9`()), + ("ISO-8859-13", `ISO-8859-13`()), + ("ISO-8859-15", `ISO-8859-15`()), + ("KOI8-R", `KOI8-R`()), + ("UTF-8", `UTF-8`()), + ("UTF-16", `UTF-16`()), + ("UTF-16BE", `UTF-16BE`()), + ("UTF-16LE", `UTF-16LE`()) ) - - def lookup(enc: String): Encoding = allEncodings(enc) + def lookup(enc: String): Encoding = allEncodings(enc) } diff --git a/core-scalaz/shared/src/main/scala/rapture/core-scalaz/modes.scala b/core-scalaz/shared/src/main/scala/rapture/core-scalaz/modes.scala index 4fa68e8..b61a88f 100644 --- a/core-scalaz/shared/src/main/scala/rapture/core-scalaz/modes.scala +++ b/core-scalaz/shared/src/main/scala/rapture/core-scalaz/modes.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core.scalazInterop @@ -24,39 +24,46 @@ import java.util.concurrent.ExecutorService import scalaz._ import scalaz.concurrent._ -class ReturnTasks[+Group <: MethodConstraint](implicit pool: ExecutorService) extends Mode[Group] { +class ReturnTasks[+Group <: MethodConstraint](implicit pool: ExecutorService) + extends Mode[Group] { type Wrap[+T, E <: Exception] = Task[T] def wrap[T, E <: Exception](t: => T): Task[T] = Task.delay(t) - def unwrap[T](t: => Wrap[T, _ <: Exception]): T = t.attemptRun.valueOr { throw _ } + def unwrap[T](t: => Wrap[T, _ <: Exception]): T = + t.attemptRun.valueOr { throw _ } } class ReturnValidation[+Group <: MethodConstraint] extends Mode[Group] { type Wrap[+T, E <: Exception] = Validation[E, T] - def wrap[T, E <: Exception](t: => T): Validation[E, T] = try Success(t) catch { case e: E => Failure(e) } + def wrap[T, E <: Exception](t: => T): Validation[E, T] = + try Success(t) catch { case e: E => Failure(e) } def unwrap[T](t: => Validation[_ <: Exception, T]): T = t.valueOr { throw _ } } class ReturnDisjunction[+Group <: MethodConstraint] extends Mode[Group] { type Wrap[+T, E <: Exception] = \/[E, T] - def wrap[T, E <: Exception](t: => T): \/[E, T] = try \/-(t) catch { case e: E => -\/(e) } + def wrap[T, E <: Exception](t: => T): \/[E, T] = + try \/-(t) catch { case e: E => -\/(e) } def unwrap[T](t: => \/[_ <: Exception, T]): T = t.valueOr { throw _ } } class ScalazExplicits[+T, E <: Exception](explicit: modes.Explicitly[T, E]) { - def task(implicit pool: ExecutorService): Task[T] = returnTasks.wrap(explicit.get) + def task(implicit pool: ExecutorService): Task[T] = + returnTasks.wrap(explicit.get) def validation: Validation[E, T] = returnValidations.wrap(explicit.get) } - object `package` { - implicit def scalazExplicits[T, E <: Exception](explicit: modes.Explicitly[T, E]): ScalazExplicits[T, E] = + implicit def scalazExplicits[T, E <: Exception]( + explicit: modes.Explicitly[T, E]): ScalazExplicits[T, E] = new ScalazExplicits[T, E](explicit) - implicit def returnTasks[Group <: MethodConstraint](implicit pool: ExecutorService) = new ReturnTasks[Group] + implicit def returnTasks[Group <: MethodConstraint]( + implicit pool: ExecutorService) = new ReturnTasks[Group] // FIXME: This should be modified to collect multiple failures - implicit def returnValidations[Group <: MethodConstraint] = new ReturnValidation[Group] - - implicit def returnDisjunction[Group <: MethodConstraint] = new ReturnDisjunction[Group] + implicit def returnValidations[Group <: MethodConstraint] = + new ReturnValidation[Group] + implicit def returnDisjunction[Group <: MethodConstraint] = + new ReturnDisjunction[Group] } diff --git a/core-scalaz/shared/src/main/scala/rapture/core-scalaz/transformers.scala b/core-scalaz/shared/src/main/scala/rapture/core-scalaz/transformers.scala index be8692f..12e1a56 100644 --- a/core-scalaz/shared/src/main/scala/rapture/core-scalaz/transformers.scala +++ b/core-scalaz/shared/src/main/scala/rapture/core-scalaz/transformers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core.scalazInterop @@ -25,63 +25,74 @@ import scalaz.{Functor, _} import language.higherKinds /** - * ResultT monad transformer - * - * Represents a computation of type `Result[A,B]`. - * - * Example: - * {{{ - * val x: Option[Result[String, E]] = Some(Answer(1)) - * ResultT(x).map(1+).run // Some(Answer(2)) - * }}} - **/ + * ResultT monad transformer + * + * Represents a computation of type `Result[A,B]`. + * + * Example: + * {{{ + * val x: Option[Result[String, E]] = Some(Answer(1)) + * ResultT(x).map(1+).run // Some(Answer(2)) + * }}} + **/ sealed trait ResultT[F[_], T, E <: Exception] { val run: F[Result[T, E]] /** Map on the answer of this result. */ - def map[C](f: T => C)(implicit functor: Functor[F], cte: ClassTag[E]): ResultT[F, C, E] = + def map[C](f: T => C)( + implicit functor: Functor[F], cte: ClassTag[E]): ResultT[F, C, E] = ResultT(functor.map(run)(_.map(f))) /** Bind through the answer of this result accumulating errors in the contents and type signature. */ - def flatMap[C, E2 <: Exception](f: T => ResultT[F, C, E2])(implicit monad: Monad[F], cte: ClassTag[E2]): ResultT[F, C, E with E2] = { - ResultT(monad.bind[Result[T, E], Result[C, E with E2]](run) { result => + def flatMap[C, E2 <: Exception](f: T => ResultT[F, C, E2])( + implicit monad: Monad[F], + cte: ClassTag[E2]): ResultT[F, C, E with E2] = { + ResultT( + monad.bind[Result[T, E], Result[C, E with E2]](run) { result => result.fold[F[Result[C, E with E2]]]({ a => - monad.map(f(a).run)( r2 => Result[C, E with E2](r2.get, r2.errors ++ result.errors)) - },{ e => + monad.map(f(a).run)( + r2 => Result[C, E with E2](r2.get, r2.errors ++ result.errors)) + }, { e => monad.point(Errata[C, E with E2](e)) }) }) } /** Filter on the answer of this result. */ - def filter(p: T => Boolean)(implicit functor: Functor[F], cte: ClassTag[E]): ResultT[F, T, E with NotMatchingFilter] = + def filter(p: T => Boolean)( + implicit functor: Functor[F], + cte: ClassTag[E]): ResultT[F, T, E with NotMatchingFilter] = ResultT(functor.map(run)(_.filter(p))) /** Alias for `filter` */ - def withFilter(p: T => Boolean)(implicit functor: Functor[F], cte: ClassTag[E]): ResultT[F, T, E with NotMatchingFilter] = + def withFilter(p: T => Boolean)( + implicit functor: Functor[F], + cte: ClassTag[E]): ResultT[F, T, E with NotMatchingFilter] = filter(p) - } object ResultT extends ResultTFunctions { + /** Construct a result value. */ - def apply[F[_], T, E <: Exception : ClassTag](a: F[Result[T, E]]): ResultT[F, T, E] = + def apply[F[_], T, E <: Exception : ClassTag]( + a: F[Result[T, E]]): ResultT[F, T, E] = resultT[F, T, E](a) /** Construct an answer value. */ - def answer[F[_], T, E <: Exception : ClassTag](a: F[T])(implicit functor: Functor[F]): ResultT[F, T, E] = + def answer[F[_], T, E <: Exception : ClassTag](a: F[T])( + implicit functor: Functor[F]): ResultT[F, T, E] = apply[F, T, E](functor.map(a)(Result.answer[T, E])) /** Construct an errata value. */ - def errata[F[_], T, E <: Exception : ClassTag](a: F[E])(implicit functor: Functor[F]): ResultT[F, T, E] = + def errata[F[_], T, E <: Exception : ClassTag](a: F[E])( + implicit functor: Functor[F]): ResultT[F, T, E] = apply[F, T, E](functor.map(a)(Result.errata[T, E])) - } private[scalazInterop] trait ResultTFunctions { - def resultT[F[_], T, E <: Exception](a: F[Result[T, E]]): ResultT[F, T, E] = new ResultT[F, T, E] { - val run = a - } + def resultT[F[_], T, E <: Exception](a: F[Result[T, E]]): ResultT[F, T, E] = + new ResultT[F, T, E] { + val run = a + } } - diff --git a/core-test/shared/src/test/scala/rapture/core/tests.scala b/core-test/shared/src/test/scala/rapture/core/tests.scala index 9ccf4db..68cbbc8 100644 --- a/core-test/shared/src/test/scala/rapture/core/tests.scala +++ b/core-test/shared/src/test/scala/rapture/core/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core.test @@ -33,228 +33,289 @@ object CoreTests extends TestSuite { case class BetaException() extends Exception case class MiscException() extends Exception - def alpha(x: Int)(implicit mode: Mode[_]): mode.Wrap[Int, AlphaException] = mode.wrap { - if(x == 0) mode.exception(AlphaException()) - else if(x == 1) throw MiscException() - else 0 - } - - def beta(x: Int)(implicit mode: Mode[_]): mode.Wrap[Int, BetaException] = mode.wrap { - if(x == 0) mode.exception(BetaException()) - else if(x == 1) throw MiscException() - else 0 - } - - val `Successful Result` = test { - import modes.returnResult._ - alpha(2) - } returns Answer(0) - - val `Unforeseen Result` = test { - import modes.returnResult._ - alpha(1) - } returns Unforeseen(MiscException()) - - val `Expected error Result` = test { - import modes.returnResult._ - alpha(0) - } satisfies { case Errata(_) => true case _ => false } - - val `FlatMapped Successful Result` = test { - import modes.returnResult._ - for { - a <- alpha(2) - b <- beta(2) - } yield a + b - } returns Answer(0) - - val `FlatMapped first fails` = test { - import modes.returnResult._ - for { - a <- alpha(0) - b <- beta(2) - } yield a + b - } satisfies (_.exceptions == Vector(AlphaException())) - - val `FlatMapped second fails` = test { - import modes.returnResult._ - for { - a <- alpha(2) - b <- beta(0) - } yield a + b - } satisfies (_.exceptions == Vector(BetaException())) - - val `Resolving errata 1` = test { - import modes.returnResult._ - val result = for(a <- alpha(2); b <- beta(0)) yield a + b - result.resolve( - each[AlphaException] { e => 10 }, - each[BetaException] { e => 20 } - ) - } returns Answer(20) - - val `Resolving errata 2` = test { - import modes.returnResult._ - val result = for(a <- alpha(0); b <- beta(2)) yield a + b - result.resolve( - each[AlphaException] { e => 10 }, - each[BetaException] { e => 20 } - ) - } returns Answer(10) - - val `Catching success` = test { - Result.catching[AlphaException] { - "success" + def alpha(x: Int)(implicit mode: Mode[_]): mode.Wrap[Int, AlphaException] = + mode.wrap { + if (x == 0) mode.exception(AlphaException()) + else if (x == 1) throw MiscException() + else 0 } - } returns Answer("success") - val `Catching failure` = test { - Result.catching[AlphaException] { - throw AlphaException() + def beta(x: Int)(implicit mode: Mode[_]): mode.Wrap[Int, BetaException] = + mode.wrap { + if (x == 0) mode.exception(BetaException()) + else if (x == 1) throw MiscException() + else 0 } - } satisfies (_.exceptions == Vector(AlphaException())) - val `Catching unforeseen` = test { - Result.catching[AlphaException] { - throw BetaException() + val `Successful Result` = + test { + import modes.returnResult._ + alpha(2) + } returns Answer(0) + + val `Unforeseen Result` = + test { + import modes.returnResult._ + alpha(1) + } returns Unforeseen(MiscException()) + + val `Expected error Result` = + test { + import modes.returnResult._ + alpha(0) + } satisfies { + case Errata(_) => true + case _ => false } - } returns Unforeseen(BetaException()) - - val `Checking isErrata with errata` = test { - Result.errata(AlphaException()).isErrata - } returns true - - val `Checking isErrata with answer` = test { - Result.answer(1).isErrata - } returns false - - val `Checking isAnswer with errata` = test { - Result.errata(AlphaException()).isAnswer - } returns false - - val `Checking isAnswer with answer` = test { - Result.answer(1).isAnswer - } returns true - - val `Checking isUnforeseen with answer` = test { - Result.answer(1).isUnforeseen - } returns false - - val `Checking isUnforeseen with errata` = test { - Result.errata(AlphaException()).isUnforeseen - } returns false - - val `Checking isUnforeseen with unforeseen` = test { - Result.catching[AlphaException] { - throw BetaException() - }.isUnforeseen - } returns true - - val `Fold answer` = test { - Result.answer(1).fold( - a => a + 1, - e => 0 - ) - } returns 2 - - val `Fold errata` = test { - Result.errata[Int, AlphaException](AlphaException()).fold( - a => a + 1, - e => 0 - ) - } returns 0 - - val `Exists answer` = test { - Result.answer(1).exists(_ == 1) - } returns true - - val `Exists answer none found` = test { - Result.answer(1).exists(_ == 0) - } returns false - - val `Exists errata` = test { - Result.errata[Int, AlphaException](AlphaException()).exists(_ == 1) - } returns false - - val `Forall answer` = test { - Result.answer(1).forall(_ == 1) - } returns true - - val `Forall answer none found` = test { - Result.answer(1).forall(_ == 0) - } returns false - - val `Forall errata` = test { - Result.errata[Int, AlphaException](AlphaException()).forall(_ == 1) - } returns true - - val `toList answer` = test { - Result.answer(1).to[List] - } returns List(1) - - val `toList errata` = test { - Result.errata[Int, AlphaException](AlphaException()).to[List] - } returns Nil - - val `toStream answer` = test { - Result.answer(1).to[Stream] - } returns Stream(1) - - val `toStream errata` = test { - Result.errata[Int, AlphaException](AlphaException()).to[Stream] - } returns Stream.empty[Int] - - val `toOption answer` = test { - Result.answer(1).toOption - } returns Some(1) - - val `toOption errata` = test { - Result.errata[Int, AlphaException](AlphaException()).toOption - } returns None - - val `toEither answer` = test { - Result.answer(1).toEither - } returns Right(1) - - val `toEither errata` = test { - Result.errata[Int, AlphaException](AlphaException()).toEither - } satisfies (v => v.isLeft) - - val `getOrElse answer` = test { - Result.answer(1).getOrElse(0) - } returns 1 - - val `getOrElse errata` = test { - Result.errata[Int, AlphaException](AlphaException()).getOrElse(0) - } returns 0 - - val `| answer` = test { - Result.answer(1) | 0 - } returns 1 - - val `| errata` = test { - Result.errata[Int, AlphaException](AlphaException()) | 0 - } returns 0 - - val `valueOr answer` = test { - Result.answer(1).valueOr(_ => 0) - } returns 1 - - val `valueOr errata` = test { - Result.errata[Int, AlphaException](AlphaException()).valueOr(_ => 0) - } returns 0 - - val `filter answer` = test { - Result.answer(1) filter (_ == 1) - } returns Answer(1) + + val `FlatMapped Successful Result` = + test { + import modes.returnResult._ + for { + a <- alpha(2) + b <- beta(2) + } yield a + b + } returns Answer(0) + + val `FlatMapped first fails` = + test { + import modes.returnResult._ + for { + a <- alpha(0) + b <- beta(2) + } yield a + b + } satisfies (_.exceptions == Vector(AlphaException())) + + val `FlatMapped second fails` = + test { + import modes.returnResult._ + for { + a <- alpha(2) + b <- beta(0) + } yield a + b + } satisfies (_.exceptions == Vector(BetaException())) + + val `Resolving errata 1` = + test { + import modes.returnResult._ + val result = for (a <- alpha(2); b <- beta(0)) yield a + b + result.resolve( + each[AlphaException] { e => + 10 + }, + each[BetaException] { e => + 20 + } + ) + } returns Answer(20) + + val `Resolving errata 2` = + test { + import modes.returnResult._ + val result = for (a <- alpha(0); b <- beta(2)) yield a + b + result.resolve( + each[AlphaException] { e => + 10 + }, + each[BetaException] { e => + 20 + } + ) + } returns Answer(10) + + val `Catching success` = + test { + Result.catching[AlphaException] { + "success" + } + } returns Answer("success") + + val `Catching failure` = + test { + Result.catching[AlphaException] { + throw AlphaException() + } + } satisfies (_.exceptions == Vector(AlphaException())) + + val `Catching unforeseen` = + test { + Result.catching[AlphaException] { + throw BetaException() + } + } returns Unforeseen(BetaException()) + + val `Checking isErrata with errata` = + test { + Result.errata(AlphaException()).isErrata + } returns true + + val `Checking isErrata with answer` = + test { + Result.answer(1).isErrata + } returns false + + val `Checking isAnswer with errata` = + test { + Result.errata(AlphaException()).isAnswer + } returns false + + val `Checking isAnswer with answer` = + test { + Result.answer(1).isAnswer + } returns true + + val `Checking isUnforeseen with answer` = + test { + Result.answer(1).isUnforeseen + } returns false + + val `Checking isUnforeseen with errata` = + test { + Result.errata(AlphaException()).isUnforeseen + } returns false + + val `Checking isUnforeseen with unforeseen` = + test { + Result + .catching[AlphaException] { + throw BetaException() + } + .isUnforeseen + } returns true + + val `Fold answer` = + test { + Result + .answer(1) + .fold( + a => a + 1, + e => 0 + ) + } returns 2 + + val `Fold errata` = + test { + Result + .errata[Int, AlphaException](AlphaException()) + .fold( + a => a + 1, + e => 0 + ) + } returns 0 + + val `Exists answer` = + test { + Result.answer(1).exists(_ == 1) + } returns true + + val `Exists answer none found` = + test { + Result.answer(1).exists(_ == 0) + } returns false + + val `Exists errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).exists(_ == 1) + } returns false + + val `Forall answer` = + test { + Result.answer(1).forall(_ == 1) + } returns true + + val `Forall answer none found` = + test { + Result.answer(1).forall(_ == 0) + } returns false + + val `Forall errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).forall(_ == 1) + } returns true + + val `toList answer` = + test { + Result.answer(1).to[List] + } returns List(1) + + val `toList errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).to[List] + } returns Nil + + val `toStream answer` = + test { + Result.answer(1).to[Stream] + } returns Stream(1) + + val `toStream errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).to[Stream] + } returns Stream.empty[Int] + + val `toOption answer` = + test { + Result.answer(1).toOption + } returns Some(1) + + val `toOption errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).toOption + } returns None + + val `toEither answer` = + test { + Result.answer(1).toEither + } returns Right(1) + + val `toEither errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).toEither + } satisfies (v => v.isLeft) + + val `getOrElse answer` = + test { + Result.answer(1).getOrElse(0) + } returns 1 + + val `getOrElse errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).getOrElse(0) + } returns 0 + + val `| answer` = + test { + Result.answer(1) | 0 + } returns 1 + + val `| errata` = + test { + Result.errata[Int, AlphaException](AlphaException()) | 0 + } returns 0 + + val `valueOr answer` = + test { + Result.answer(1).valueOr(_ => 0) + } returns 1 + + val `valueOr errata` = + test { + Result.errata[Int, AlphaException](AlphaException()).valueOr(_ => 0) + } returns 0 + + val `filter answer` = + test { + Result.answer(1) filter (_ == 1) + } returns Answer(1) /*val `filter answer 2` = test { Result.answer(1) filter (_ == 0) } returns Errata(Nil)*/ - val `filter errata` = test { - Errata[String, Nothing](Nil) filter (_.isEmpty) - } returns Errata(Nil) + val `filter errata` = + test { + Errata[String, Nothing](Nil) filter (_.isEmpty) + } returns Errata(Nil) /*val `withFilter errata monadic` = test { for { @@ -264,47 +325,55 @@ object CoreTests extends TestSuite { } yield y } returns Errata(Nil)*/ - val `withFilter answer monadic` = test { - for { - x <- Answer(1) - if x == 1 - y = x + 1 - } yield y - } returns Answer(2) - - val `ResultT Checking isErrata with errata` = test { - ResultT.errata(Option(AlphaException())).run.get.isErrata - } returns true - - val `ResultT Checking isErrata with answer` = test { - ResultT.answer(Option(1)).run.get.isErrata - } returns false - - val `ResultT Checking isAnswer with errata` = test { - ResultT.errata(Option(AlphaException())).run.get.isAnswer - } returns false - - val `ResultT Checking isAnswer with answer` = test { - ResultT.answer(Option(1)).run.get.isAnswer - } returns true - - val `ResultT Checking isUnforeseen with answer` = test { - ResultT.answer(Option(1)).run.get.isUnforeseen - } returns false - - val `ResultT Checking isUnforeseen with errata` = test { - ResultT.errata(Option(AlphaException())).run.get.isUnforeseen - } returns false - - val `ResultT withFilter accumulating exceptions` = test { - val z: ResultT[Option, Int, NumberFormatException with IllegalArgumentException] = for { - x <- ResultT(Option(Result.catching[NumberFormatException]("1".toInt))) - y <- ResultT(Option(Result.catching[IllegalArgumentException]("1".toInt))) - } yield x + y - z.run.get.get - } returns 2 - - - + val `withFilter answer monadic` = + test { + for { + x <- Answer(1) if x == 1 + y = x + 1 + } yield y + } returns Answer(2) + + val `ResultT Checking isErrata with errata` = + test { + ResultT.errata(Option(AlphaException())).run.get.isErrata + } returns true + + val `ResultT Checking isErrata with answer` = + test { + ResultT.answer(Option(1)).run.get.isErrata + } returns false + + val `ResultT Checking isAnswer with errata` = + test { + ResultT.errata(Option(AlphaException())).run.get.isAnswer + } returns false + + val `ResultT Checking isAnswer with answer` = + test { + ResultT.answer(Option(1)).run.get.isAnswer + } returns true + + val `ResultT Checking isUnforeseen with answer` = + test { + ResultT.answer(Option(1)).run.get.isUnforeseen + } returns false + + val `ResultT Checking isUnforeseen with errata` = + test { + ResultT.errata(Option(AlphaException())).run.get.isUnforeseen + } returns false + + val `ResultT withFilter accumulating exceptions` = + test { + val z: ResultT[Option, + Int, + NumberFormatException with IllegalArgumentException] = + for { + x <- ResultT( + Option(Result.catching[NumberFormatException]("1".toInt))) + y <- ResultT( + Option(Result.catching[IllegalArgumentException]("1".toInt))) + } yield x + y + z.run.get.get + } returns 2 } - diff --git a/core/shared/src/main/scala/rapture/core/actor.scala b/core/shared/src/main/scala/rapture/core/actor.scala index dd79840..9eaa2b5 100644 --- a/core/shared/src/main/scala/rapture/core/actor.scala +++ b/core/shared/src/main/scala/rapture/core/actor.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -30,9 +30,12 @@ case object Ignore extends ActorResponse[Nothing, Nothing] object Actor { class ActorOf[Msg] { - def apply[Res, State](init: State)(fn: Transition[Msg, State] => ActorResponse[Res, State])(implicit ec: ExecutionContext): Actor[Msg, Res, State] = + def apply[Res, State](init: State)( + fn: Transition[Msg, State] => ActorResponse[Res, State])( + implicit ec: ExecutionContext): Actor[Msg, Res, State] = new Actor[Msg, Res, State](init) { - def handle(trans: Transition[Msg, State]): ActorResponse[Res, State] = fn(trans) + def handle(trans: Transition[Msg, State]): ActorResponse[Res, State] = + fn(trans) } } @@ -41,32 +44,36 @@ object Actor { case class IgnoredException() extends Exception("Message was ignored") -abstract class Actor[Msg, Res, State](init: State)(implicit executionContext: ExecutionContext) { - +abstract class Actor[Msg, Res, State](init: State)( + implicit executionContext: ExecutionContext) { + private var future: Future[Res] = Future.successful(null.asInstanceOf[Res]) private var stateVar: State = init - protected def enqueue(fn: => ActorResponse[Res, State]): Future[Res] = future.synchronized { - val promise = Promise[Res] - future = future.andThen { case _ => - val result = Try(fn) match { - case Success(Ignore) => - promise.failure(IgnoredException()) - case Success(Update(r, s)) => - promise.success(r) - stateVar = s - case Success(Reply(r)) => - promise.success(r) - case Failure(err) => - promise.failure(err) + protected def enqueue(fn: => ActorResponse[Res, State]): Future[Res] = + future.synchronized { + val promise = Promise[Res] + future = future.andThen { + case _ => + val result = Try(fn) match { + case Success(Ignore) => + promise.failure(IgnoredException()) + case Success(Update(r, s)) => + promise.success(r) + stateVar = s + case Success(Reply(r)) => + promise.success(r) + case Failure(err) => + promise.failure(err) + } } + promise.future } - promise.future - } def state: State = stateVar - def cue(msg: Msg): Future[Res] = enqueue { handle(Transition(msg, stateVar)) } + def cue(msg: Msg): Future[Res] = + enqueue { handle(Transition(msg, stateVar)) } def handle(trans: Transition[Msg, State]): ActorResponse[Res, State] } diff --git a/core/shared/src/main/scala/rapture/core/alloc.scala b/core/shared/src/main/scala/rapture/core/alloc.scala index 249ab96..2fa26e9 100644 --- a/core/shared/src/main/scala/rapture/core/alloc.scala +++ b/core/shared/src/main/scala/rapture/core/alloc.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -24,10 +24,16 @@ import annotation.unchecked._ class AllocApply[T](val unit: Int) extends AnyVal { def apply()(implicit inst: Alloc0.Invariant[T]): T = inst.instantiate() - def apply[P1](p1: P1)(implicit inst: Alloc1.Invariant[T, P1]): T = inst.instantiate(p1) - def apply[P1, P2](p1: P1, p2: P2)(implicit inst: Alloc2.Invariant[T, P1, P2]): T = inst.instantiate(p1, p2) - def apply[P1, P2, P3](p1: P1, p2: P2, p3: P3)(implicit inst: Alloc3.Invariant[T, P1, P2, P3]): T = inst.instantiate(p1, p2, p3) - def apply[P1, P2, P3, P4](p1: P1, p2: P2, p3: P3, p4: P4)(implicit inst: Alloc4.Invariant[T, P1, P2, P3, P4]): T = inst.instantiate(p1, p2, p3, p4) + def apply[P1](p1: P1)(implicit inst: Alloc1.Invariant[T, P1]): T = + inst.instantiate(p1) + def apply[P1, P2](p1: P1, p2: P2)( + implicit inst: Alloc2.Invariant[T, P1, P2]): T = inst.instantiate(p1, p2) + def apply[P1, P2, P3](p1: P1, p2: P2, p3: P3)( + implicit inst: Alloc3.Invariant[T, P1, P2, P3]): T = + inst.instantiate(p1, p2, p3) + def apply[P1, P2, P3, P4](p1: P1, p2: P2, p3: P3, p4: P4)( + implicit inst: Alloc4.Invariant[T, P1, P2, P3, P4]): T = + inst.instantiate(p1, p2, p3, p4) } object Alloc0 { @@ -36,36 +42,48 @@ object Alloc0 { } object Alloc1 { - implicit def alloc1[T, P1]: Alloc1[T, P1] = macro CoreMacros.allocMacro1[T, P1] + implicit def alloc1[T, P1]: Alloc1[T, P1] = macro CoreMacros + .allocMacro1[T, P1] type Invariant[+T, P1] = Alloc1[T @uncheckedVariance, P1] } object Alloc2 { - implicit def alloc2[T, P1, P2]: Alloc2[T, P1, P2] = macro CoreMacros.allocMacro2[T, P1, P2] + implicit def alloc2[T, P1, P2]: Alloc2[T, P1, P2] = macro CoreMacros + .allocMacro2[T, P1, P2] type Invariant[+T, P1, P2] = Alloc2[T @uncheckedVariance, P1, P2] } object Alloc3 { - implicit def alloc3[T, P1, P2, P3]: Alloc3[T, P1, P2, P3] = macro CoreMacros.allocMacro3[T, P1, P2, P3] + implicit def alloc3[T, P1, P2, P3]: Alloc3[T, P1, P2, P3] = macro CoreMacros + .allocMacro3[T, P1, P2, P3] type Invariant[+T, P1, P2, P3] = Alloc3[T @uncheckedVariance, P1, P2, P3] } object Alloc4 { - implicit def alloc4[T, P1, P2, P3, P4]: Alloc4[T, P1, P2, P3, P4] = macro CoreMacros.allocMacro4[T, P1, P2, P3, P4] - type Invariant[+T, P1, P2, P3, P4] = Alloc4[T @uncheckedVariance, P1, P2, P3, P4] + implicit def alloc4[T, P1, P2, P3, P4]: Alloc4[T, P1, P2, P3, P4] = macro CoreMacros + .allocMacro4[T, P1, P2, P3, P4] + type Invariant[+T, P1, P2, P3, P4] = Alloc4[ + T @uncheckedVariance, P1, P2, P3, P4] } -@implicitNotFound("No constructor exists for instantiating an object of this type") +@implicitNotFound( + "No constructor exists for instantiating an object of this type") trait Alloc0[T] { def instantiate(): T } -@implicitNotFound("No constructor exists for instantiating an object of this type") +@implicitNotFound( + "No constructor exists for instantiating an object of this type") trait Alloc1[T, P1] { def instantiate(p1: P1): T } -@implicitNotFound("No constructor exists for instantiating an object of this type") +@implicitNotFound( + "No constructor exists for instantiating an object of this type") trait Alloc2[T, P1, P2] { def instantiate(p1: P1, p2: P2): T } -@implicitNotFound("No constructor exists for instantiating an object of this type") +@implicitNotFound( + "No constructor exists for instantiating an object of this type") trait Alloc3[T, P1, P2, P3] { def instantiate(p1: P1, p2: P2, p3: P3): T } -@implicitNotFound("No constructor exists for instantiating an object of this type") -trait Alloc4[T, P1, P2, P3, P4] { def instantiate(p1: P1, p2: P2, p3: P3, p4: P4): T } +@implicitNotFound( + "No constructor exists for instantiating an object of this type") +trait Alloc4[T, P1, P2, P3, P4] { + def instantiate(p1: P1, p2: P2, p3: P3, p4: P4): T +} diff --git a/core/shared/src/main/scala/rapture/core/app.scala b/core/shared/src/main/scala/rapture/core/app.scala index d9fb3e5..b3522ab 100644 --- a/core/shared/src/main/scala/rapture/core/app.scala +++ b/core/shared/src/main/scala/rapture/core/app.scala @@ -13,10 +13,11 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core object Main extends App { - Console.println("Running this JAR file does nothing. To use it, please include it on your classpath.") + Console.println( + "Running this JAR file does nothing. To use it, please include it on your classpath.") } diff --git a/core/shared/src/main/scala/rapture/core/core.scala b/core/shared/src/main/scala/rapture/core/core.scala index a9d0f09..6ef524e 100644 --- a/core/shared/src/main/scala/rapture/core/core.scala +++ b/core/shared/src/main/scala/rapture/core/core.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core diff --git a/core/shared/src/main/scala/rapture/core/default.scala b/core/shared/src/main/scala/rapture/core/default.scala index c0ae5c5..bd1c93a 100644 --- a/core/shared/src/main/scala/rapture/core/default.scala +++ b/core/shared/src/main/scala/rapture/core/default.scala @@ -13,16 +13,18 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core private[core] trait DefaultsTo_1 { - implicit def fallbackDefaultsTo[T, S]: DefaultsTo[T, S] = null.asInstanceOf[DefaultsTo[T, S]] + implicit def fallbackDefaultsTo[T, S]: DefaultsTo[T, S] = + null.asInstanceOf[DefaultsTo[T, S]] } object DefaultsTo extends DefaultsTo_1 { - implicit def defaultDefaultsTo[T]: DefaultsTo[T, T] = null.asInstanceOf[DefaultsTo[T, T]] + implicit def defaultDefaultsTo[T]: DefaultsTo[T, T] = + null.asInstanceOf[DefaultsTo[T, T]] } trait DefaultsTo[T, S] diff --git a/core/shared/src/main/scala/rapture/core/functor.scala b/core/shared/src/main/scala/rapture/core/functor.scala index 89396d5..5bcc284 100644 --- a/core/shared/src/main/scala/rapture/core/functor.scala +++ b/core/shared/src/main/scala/rapture/core/functor.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -24,21 +24,25 @@ trait Functor[+F[x] <: Functor[F, x], A] { functor => type Throws <: Exception protected def rawMap[B](fn: (A, Mode[_ <: MethodConstraint]) => B): F[B] - - def map[B](fn: A => B): F[B] { type Throws = functor.Throws with Exception } = + + def map[B]( + fn: A => B): F[B] { type Throws = functor.Throws with Exception } = emap[Exception](fn) def emap[E <: Exception]: Emap[E] = new Emap[E]() - + def smap[B](fn: A => B): F[B] { type Throws = functor.Throws } = emap[Nothing](fn).asInstanceOf[F[B] { type Throws = functor.Throws }] - + // FIXME: Make this a value class class Emap[E <: Exception]() { - def apply[B](fn: A => B)(implicit tt: ClassTag[E]): F[B] { type Throws = functor.Throws with E } = - functor.rawMap { case (a, m) => - try fn(a) catch { case e: Exception => m.exception[B, E](e.asInstanceOf[E]) } + def apply[B](fn: A => B)(implicit tt: ClassTag[E] + ): F[B] { type Throws = functor.Throws with E } = + functor.rawMap { + case (a, m) => + try fn(a) catch { + case e: Exception => m.exception[B, E](e.asInstanceOf[E]) + } }.asInstanceOf[F[B] { type Throws = functor.Throws with E }] } } - diff --git a/core/shared/src/main/scala/rapture/core/macros.scala b/core/shared/src/main/scala/rapture/core/macros.scala index ba60d80..782980d 100644 --- a/core/shared/src/main/scala/rapture/core/macros.scala +++ b/core/shared/src/main/scala/rapture/core/macros.scala @@ -13,110 +13,151 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core import rapture.base._ private[core] object CoreMacros { - def enumerateMacro[Cls: c.WeakTypeTag, T: c.WeakTypeTag](c: BlackboxContext)(value: c.Expr[Cls]): - c.Expr[List[T]] = { + def enumerateMacro[Cls : c.WeakTypeTag, T : c.WeakTypeTag]( + c: BlackboxContext)(value: c.Expr[Cls]): c.Expr[List[T]] = { import c.universe._ import compatibility._ val cls = weakTypeOf[Cls] - val allMethods = weakTypeOf[Cls].members.to[List].filter(_.isMethod).map(_.asMethod) - val matchingMethods = allMethods filter { m => paramLists(c)(m).isEmpty && m.returnType.weak_<:<(weakTypeOf[T]) } - val methodNames = matchingMethods map { m => - Select(value.tree, termName(c, m.name.toString)) - } + val allMethods = + weakTypeOf[Cls].members.to[List].filter(_.isMethod).map(_.asMethod) + val matchingMethods = + allMethods filter { m => + paramLists(c)(m).isEmpty && m.returnType.weak_<:<(weakTypeOf[T]) + } + val methodNames = + matchingMethods map { m => + Select(value.tree, termName(c, m.name.toString)) + } val listApply = Select(reify(List).tree, termName(c, "apply")) - + c.Expr[List[T]](Apply(listApply, methodNames)) } def assignedMethodNameMacro(c: BlackboxContext): c.Expr[MethodName] = { import c.universe._ - + val name = c.enclosingClass.find { - case DefDef(_, name, _, _, _, rhs) => rhs.pos.isDefined && rhs.pos.point == c.macroApplication.pos.point + case DefDef(_, name, _, _, _, rhs) => + rhs.pos.isDefined && rhs.pos.point == c.macroApplication.pos.point case _ => false - }.map { case DefDef(_, name, _, _, _, _) => - val dec = c.Expr[String](Literal(Constant(name.decodedName.toString))) - reify { new MethodName(dec.splice) } + }.map { + case DefDef(_, name, _, _, _, _) => + val dec = c.Expr[String](Literal(Constant(name.decodedName.toString))) + reify { new MethodName(dec.splice) } } - - name getOrElse c.abort(c.enclosingPosition, "This method invocation must be assigned to a named identifier.") + + name getOrElse c.abort( + c.enclosingPosition, + "This method invocation must be assigned to a named identifier.") } - + def assignedNameMacro(c: BlackboxContext): c.Expr[AssignedName] = { import c.universe._ - val name = c.enclosingClass find { - case ValDef(_, name, _, rhs) => rhs.pos.isDefined && rhs.pos.point == c.macroApplication.pos.point - case other => false - } map { case ValDef(_, name, _, _) => - val dec = c.Expr[String](Literal(Constant(name.decodedName.toString))) - reify { new AssignedName(dec.splice) } - } - - name getOrElse c.abort(c.enclosingPosition, "This method invocation must be assigned to a named identifier.") + val name = + c.enclosingClass find { + case ValDef(_, name, _, rhs) => + rhs.pos.isDefined && rhs.pos.point == c.macroApplication.pos.point + case other => false + } map { + case ValDef(_, name, _, _) => + val dec = + c.Expr[String](Literal(Constant(name.decodedName.toString))) + reify { new AssignedName(dec.splice) } + } + + name getOrElse c.abort( + c.enclosingPosition, + "This method invocation must be assigned to a named identifier.") } - def allocMacro[T: c.WeakTypeTag](c: BlackboxContext): c.Expr[Alloc0[T]] = { + def allocMacro[T : c.WeakTypeTag](c: BlackboxContext): c.Expr[Alloc0[T]] = { import c.universe._ import compatibility._ - val construction = c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List())) + val construction = c.Expr[T]( + Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List())) reify { new Alloc0[T] { def instantiate(): T = construction.splice } } } - - def allocMacro1[T: c.WeakTypeTag, P1: c.WeakTypeTag](c: BlackboxContext): c.Expr[Alloc1[T, P1]] = { + + def allocMacro1[T : c.WeakTypeTag, P1 : c.WeakTypeTag]( + c: BlackboxContext): c.Expr[Alloc1[T, P1]] = { import c.universe._ import compatibility._ - - val construction = c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List( - Ident(termName(c, "p1"))))) - - reify { new Alloc1[T, P1] { def instantiate(p1: P1): T = construction.splice } } + + val construction = + c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), + List(Ident(termName(c, "p1"))))) + + reify { + new Alloc1[T, P1] { def instantiate(p1: P1): T = construction.splice } + } } - - def allocMacro2[T: c.WeakTypeTag, P1: c.WeakTypeTag, P2: c.WeakTypeTag](c: BlackboxContext): - c.Expr[Alloc2[T, P1, P2]] = { - + + def allocMacro2[T : c.WeakTypeTag, P1 : c.WeakTypeTag, P2 : c.WeakTypeTag]( + c: BlackboxContext): c.Expr[Alloc2[T, P1, P2]] = { + import c.universe._ import compatibility._ - - val construction = c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List( - Ident(termName(c, "p1")), Ident(termName(c, "p2"))))) - reify { new Alloc2[T, P1, P2] { def instantiate(p1: P1, p2: P2): T = construction.splice } } + + val construction = c.Expr[T]( + Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), + List(Ident(termName(c, "p1")), Ident(termName(c, "p2"))))) + reify { + new Alloc2[T, P1, P2] { + def instantiate(p1: P1, p2: P2): T = construction.splice + } + } } - - def allocMacro3[T: c.WeakTypeTag, P1: c.WeakTypeTag, P2: c.WeakTypeTag, P3: c.WeakTypeTag](c: - WhiteboxContext): c.Expr[Alloc3[T, P1, P2, P3]] = { - + + def allocMacro3[ + T : c.WeakTypeTag, P1 : c.WeakTypeTag, P2 : c.WeakTypeTag, P3 : c.WeakTypeTag]( + c: WhiteboxContext): c.Expr[Alloc3[T, P1, P2, P3]] = { + import c.universe._ import compatibility._ - - val construction = c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List( - Ident(termName(c, "p1")), Ident(termName(c, "p2")), Ident(termName(c, "p3"))))) - - reify { new Alloc3[T, P1, P2, P3] { def instantiate(p1: P1, p2: P2, p3: P3): T = construction.splice } } + + val construction = c.Expr[T]( + Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), + List(Ident(termName(c, "p1")), + Ident(termName(c, "p2")), + Ident(termName(c, "p3"))))) + + reify { + new Alloc3[T, P1, P2, P3] { + def instantiate(p1: P1, p2: P2, p3: P3): T = construction.splice + } + } } - - def allocMacro4[T: c.WeakTypeTag, P1: c.WeakTypeTag, P2: c.WeakTypeTag, P3: c.WeakTypeTag, P4: c.WeakTypeTag](c: - WhiteboxContext): c.Expr[Alloc4[T, P1, P2, P3, P4]] = { - + + def allocMacro4[ + T : c.WeakTypeTag, P1 : c.WeakTypeTag, P2 : c.WeakTypeTag, P3 : c.WeakTypeTag, P4 : c.WeakTypeTag]( + c: WhiteboxContext): c.Expr[Alloc4[T, P1, P2, P3, P4]] = { + import c.universe._ import compatibility._ - - val construction = c.Expr[T](Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), List( - Ident(termName(c, "p1")), Ident(termName(c, "p2")), Ident(termName(c, "p3")), Ident(termName(c, "p4"))))) - + + val construction = c.Expr[T]( + Apply(Select(New(TypeTree(weakTypeOf[T])), constructor(c)), + List(Ident(termName(c, "p1")), + Ident(termName(c, "p2")), + Ident(termName(c, "p3")), + Ident(termName(c, "p4"))))) + reify { - new Alloc4[T, P1, P2, P3, P4] { def instantiate(p1: P1, p2: P2, p3: P3, p4: P4): T = construction.splice } + new Alloc4[T, P1, P2, P3, P4] { + def instantiate(p1: P1, p2: P2, p3: P3, p4: P4): T = + construction.splice + } } } } diff --git a/core/shared/src/main/scala/rapture/core/med.scala b/core/shared/src/main/scala/rapture/core/med.scala index 4a93869..a1bf386 100644 --- a/core/shared/src/main/scala/rapture/core/med.scala +++ b/core/shared/src/main/scala/rapture/core/med.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -22,21 +22,28 @@ object MinimumEditDistance { var d = Vector.fill(a.length + 1)(Vector.fill(b.length + 1)(0)) (0 to b.length).foreach { j => (0 to a.length).foreach { i => - if(i == 0 || j == 0) d = d.updated(i, d(i).updated(j, i + j)) - else if(a(i - 1) == b(j - 1)) d = d.updated(i, d(i).updated(j, d(i - 1)(j - 1))) - else d = d.updated(i, d(i).updated(j, List(d(i - 1)(j), d(i)(j - 1), d(i - 1)(j - 1)).min + 1)) + if (i == 0 || j == 0) d = d.updated(i, d(i).updated(j, i + j)) + else if (a(i - 1) == b(j - 1)) + d = d.updated(i, d(i).updated(j, d(i - 1)(j - 1))) + else + d = d.updated(i, + d(i).updated(j, + List(d(i - 1)(j), + d(i)(j - 1), + d(i - 1)(j - 1)).min + 1)) } } d(a.length)(b.length) } - - def filterStrings(words: Array[String], word: String, limit: Int): List[String] = { + + def filterStrings( + words: Array[String], word: String, limit: Int): List[String] = { val arr = new Array[Int](256) val results = new collection.mutable.ListBuffer[String] - - for(i <- 0 to 15) { + + for (i <- 0 to 15) { arr(i) = i - arr(16*i) = i + arr(16 * i) = i } def difference(d: Array[Int], a: String): Int = { @@ -45,29 +52,33 @@ object MinimumEditDistance { var i, j, n = 0 var min = Int.MaxValue var cont = true - while(n <= t && cont) { - val r = if(i == 0 || j == 0) i + j - else if(a(i - 1) == word(j - 1)) d(16*(i - 1) + j - 1) - else math.min(math.min(d(16*(i - 1) + j), d(16*i + j - 1)), d(16*(i - 1) + j - 1)) + 1 - - min = math.min(min, r) - d(16*i + j) = r - - if(j == 0 || i == amax) { - n += 1 - if(n <= word.length) { j = n; i = 0 } - else { i = n - word.length; j = word.length } - if(min > limit) cont = false - min = Int.MaxValue - } else { - i += 1 - j -= 1 - } + while (n <= t && cont) { + val r = + if (i == 0 || j == 0) i + j + else if (a(i - 1) == word(j - 1)) d(16 * (i - 1) + j - 1) + else + math.min(math.min(d(16 * (i - 1) + j), d(16 * i + j - 1)), + d(16 * (i - 1) + j - 1)) + 1 + + min = math.min(min, r) + d(16 * i + j) = r + + if (j == 0 || i == amax) { + n += 1 + if (n <= word.length) { j = n; i = 0 } else { + i = n - word.length; j = word.length + } + if (min > limit) cont = false + min = Int.MaxValue + } else { + i += 1 + j -= 1 + } } - - if(cont) d(16*amax + word.length) else Int.MaxValue + + if (cont) d(16 * amax + word.length) else Int.MaxValue } - + val len = word.length words.filter { w => diff --git a/core/shared/src/main/scala/rapture/core/modes.scala b/core/shared/src/main/scala/rapture/core/modes.scala index 4025a13..7eb13d2 100644 --- a/core/shared/src/main/scala/rapture/core/modes.scala +++ b/core/shared/src/main/scala/rapture/core/modes.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -34,13 +34,15 @@ object Mode extends Mode_1 { } } -@implicitNotFound(msg = "No implicit mode was available for ${Group} methods. "+ - "Please import a member of rapture.core.modes, e.g. modes.throwExceptions.") +@implicitNotFound( + msg = "No implicit mode was available for ${Group} methods. " + + "Please import a member of rapture.core.modes, e.g. modes.throwExceptions.") trait Mode[+Group <: MethodConstraint] { mode => - type Wrap[+_, _ <: Exception] + type Wrap [+ _, _ <: Exception] def wrap[Res, E <: Exception](blk: => Res): Wrap[Res, E] - def flatWrap[Res, E <: Exception: ClassTag](blk: => Wrap[Res, E]): Wrap[Res, E] = + def flatWrap[Res, E <: Exception : ClassTag]( + blk: => Wrap[Res, E]): Wrap[Res, E] = wrap(unwrap(blk)) var callPath = "_" @@ -54,20 +56,24 @@ trait Mode[+Group <: MethodConstraint] { mode => res } - def generic[C <: MethodConstraint]: Mode[C] { type Wrap[+T, E <: Exception] = mode.Wrap[T, E] } = - this.asInstanceOf[Mode[C] { type Wrap[+T, E <: Exception] = mode.Wrap[T, E] }] - - def compose[Group2 <: MethodConstraint](mode2: Mode[Group2]) = new Mode[Group] { - type Wrap[+Res, E <: Exception] = mode.Wrap[mode2.Wrap[Res, E], E] - - def wrap[Res, E <: Exception](blk: => Res): Wrap[Res, E] = - mode.wrap(mode2.wrap(blk)) - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = - mode2.unwrap(mode.unwrap(value)) - } + def generic[C <: MethodConstraint]: Mode[C] { + type Wrap[+T, E <: Exception] = mode.Wrap[T, E] + } = + this.asInstanceOf[ + Mode[C] { type Wrap[+T, E <: Exception] = mode.Wrap[T, E] }] + + def compose[Group2 <: MethodConstraint](mode2: Mode[Group2]) = + new Mode[Group] { + type Wrap[+Res, E <: Exception] = mode.Wrap[mode2.Wrap[Res, E], E] + + def wrap[Res, E <: Exception](blk: => Res): Wrap[Res, E] = + mode.wrap(mode2.wrap(blk)) - def catching[E <: Exception: ClassTag, T](blk: => T) = try blk catch { + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + mode2.unwrap(mode.unwrap(value)) + } + + def catching[E <: Exception : ClassTag, T](blk: => T) = try blk catch { case e: E => exception(e) case e: Exception => throw e } @@ -75,9 +81,11 @@ trait Mode[+Group <: MethodConstraint] { mode => def safe[T](blk: => T): T = { try blk catch { case e: Exception => exception(e) } } - def exception[T, E <: Exception: ClassTag](e: E, continue: Boolean = true): T = throw e + def exception[T, E <: Exception : ClassTag]( + e: E, continue: Boolean = true): T = throw e - def wrapEither[Res, E <: Exception: ClassTag](blk: => Either[E, Res]): Wrap[Res, E] = + def wrapEither[Res, E <: Exception : ClassTag]( + blk: => Either[E, Res]): Wrap[Res, E] = wrap { blk match { case Left(e) => throw e @@ -85,21 +93,22 @@ trait Mode[+Group <: MethodConstraint] { mode => } } - def wrapOption[Res](blk: => Option[Res]): Wrap[Res, Exception] = wrap(blk.get) + def wrapOption[Res](blk: => Option[Res]): Wrap[Res, Exception] = + wrap(blk.get) - def wrapTry[Res, E <: Exception: ClassTag](blk: => Try[Res]): Wrap[Res, E] = + def wrapTry[Res, E <: Exception : ClassTag](blk: => Try[Res]): Wrap[Res, E] = wrap(blk.get) } object repl { - + var showStackTraces: Boolean = false private var lastExceptionValue: Throwable = new SilentException def lastException: Nothing = throw lastExceptionValue implicit def modeImplicit[Group <: MethodConstraint] = new Repl[Group] - + class SilentException extends Throwable { override def printStackTrace(pw: java.io.PrintWriter) = () } @@ -107,12 +116,14 @@ object repl { class Repl[+Group <: MethodConstraint] extends Mode[Group] { type Wrap[+Return, E <: Exception] = Return def wrap[Return, E <: Exception](blk: => Return): Return = try blk catch { - case e: Exception => if(showStackTraces) throw e else { - Console.println("Execution failed with exception: "+e.toString) - Console.print("For the full stacktrace, see repl.lastException.") - lastExceptionValue = e - throw new SilentException() - } + case e: Exception => + if (showStackTraces) throw e + else { + Console.println("Execution failed with exception: " + e.toString) + Console.print("For the full stacktrace, see repl.lastException.") + lastExceptionValue = e + throw new SilentException() + } } def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value @@ -124,7 +135,7 @@ package modes { object throwExceptions extends Mode.Import[ThrowExceptionsMode] { protected def mode[G <: MethodConstraint] = new ThrowExceptionsMode[G] } - + object explicit extends Mode.Import[ExplicitMode] { protected def mode[G <: MethodConstraint] = new ExplicitMode[G] } @@ -132,7 +143,7 @@ package modes { /*object returnEither extends Mode.Import[ReturnEitherMode] { protected def mode[G <: MethodConstraint] = new ReturnEitherMode[G] }*/ - + object returnResult extends Mode.Import[ReturnResultMode] { protected def mode[G <: MethodConstraint] = new ReturnResultMode[G] } @@ -154,17 +165,21 @@ package modes { } object returnFuture { - implicit def modeImplicit[G <: MethodConstraint](implicit ec: ExecutionContext) = + implicit def modeImplicit[G <: MethodConstraint]( + implicit ec: ExecutionContext) = new ReturnFutureMode[G] - - def apply[G <: MethodConstraint](implicit ec: ExecutionContext) = modeImplicit[G] + + def apply[G <: MethodConstraint](implicit ec: ExecutionContext) = + modeImplicit[G] } object timeExecution { - implicit def modeImplicit[D: TimeSystem.ByDuration, G <: MethodConstraint] = + implicit def modeImplicit[ + D : TimeSystem.ByDuration, G <: MethodConstraint] = new TimeExecution[D, G] - - def apply[D: TimeSystem.ByDuration, G <: MethodConstraint] = modeImplicit[D, G] + + def apply[D : TimeSystem.ByDuration, G <: MethodConstraint] = + modeImplicit[D, G] } class Explicitly[+Res, E <: Exception](blk: => Res) { @@ -173,22 +188,26 @@ package modes { def getOrElse[Res2 >: Res](t: Res2): Res2 = opt.getOrElse(blk) //def either: Either[E, Res] = returnEither[Nothing].wrap(blk) def attempt: Try[Res] = returnTry[Nothing].wrap(blk) - def backoff(maxRetries: Int = 10, initialPause: Long = 1000L, - backoffRate: Double = 2.0): Res = - new ExponentialBackoffMode(maxRetries, initialPause, backoffRate).wrap(blk) - def time[D: TimeSystem.ByDuration] = timeExecution[D, Nothing].wrap(blk) - def future(implicit ec: ExecutionContext): Future[Res] = returnFuture[Nothing].wrap(blk) + def backoff(maxRetries: Int = 10, + initialPause: Long = 1000L, + backoffRate: Double = 2.0): Res = + new ExponentialBackoffMode(maxRetries, initialPause, backoffRate) + .wrap(blk) + def time[D : TimeSystem.ByDuration] = timeExecution[D, Nothing].wrap(blk) + def future(implicit ec: ExecutionContext): Future[Res] = + returnFuture[Nothing].wrap(blk) override def toString = "" } - } private[core] trait Mode_1 { - implicit def defaultMode: ThrowExceptionsMode[Nothing] = new ThrowExceptionsMode + implicit def defaultMode: ThrowExceptionsMode[Nothing] = + new ThrowExceptionsMode } -private[core] class ThrowExceptionsMode[+G <: MethodConstraint] extends Mode[G] { +private[core] class ThrowExceptionsMode[+G <: MethodConstraint] + extends Mode[G] { type Wrap[+T, E <: Exception] = T def wrap[T, E <: Exception](t: => T): T = t def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value @@ -199,47 +218,54 @@ private[core] class ExplicitMode[+G <: MethodConstraint] extends Mode[G] { def wrap[T, E <: Exception](t: => T): modes.Explicitly[T, E] = new modes.Explicitly[T, E](t) - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value.get + + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + value.get } private[core] class ReturnTryMode[+G <: MethodConstraint] extends Mode[G] { type Wrap[+T, E <: Exception] = Try[T] def wrap[T, E <: Exception](t: => T): Try[T] = Try(t) - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value.get + + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + value.get override def toString = "[modes.returnTry]" } -private[core] class ExponentialBackoffMode[+G <: MethodConstraint](maxRetries: Int = 10, initialPause: Long = 1000L, - backoffRate: Double = 2.0) extends Mode[G] { +private[core] class ExponentialBackoffMode[+G <: MethodConstraint]( + maxRetries: Int = 10, + initialPause: Long = 1000L, + backoffRate: Double = 2.0) + extends Mode[G] { type Wrap[+T, E <: Exception] = T def wrap[T, E <: Exception](t: => T): T = { var multiplier = 1.0 var count = 1 var result: T = null.asInstanceOf[T] var exception: Exception = null.asInstanceOf[Exception] - while(result == null && count < maxRetries) try { result = t } catch { + while (result == null && count < maxRetries) try { result = t } catch { case e: Exception => exception = e import timeSystems.numeric._ - Thread.sleep((multiplier*initialPause).toLong) + Thread.sleep((multiplier * initialPause).toLong) multiplier *= backoffRate count += 1 } - if(result != null) result else throw exception + if (result != null) result else throw exception } - + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value } -private[core] class KeepCalmAndCarryOnMode[+G <: MethodConstraint] extends Mode[G] { +private[core] class KeepCalmAndCarryOnMode[+G <: MethodConstraint] + extends Mode[G] { type Wrap[+T, E <: Exception] = T def wrap[T, E <: Exception](t: => T): T = try t catch { case e: Exception => null.asInstanceOf[T] } - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = Option[Return](value).get + + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + Option[Return](value).get override def toString = "[modes.kcaco]" } @@ -248,25 +274,31 @@ private[core] class ReturnOptionMode[+G <: MethodConstraint] extends Mode[G] { type Wrap[+T, E <: Exception] = Option[T] def wrap[T, E <: Exception](t: => T): Option[T] = try Some(t) catch { case e: Exception => None } - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value.get + + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + value.get override def toString = "[modes.returnOption]" } -private[core] class ReturnFutureMode[+G <: MethodConstraint](implicit ec: ExecutionContext) extends Mode[G] { +private[core] class ReturnFutureMode[+G <: MethodConstraint]( + implicit ec: ExecutionContext) + extends Mode[G] { type Wrap[+T, E <: Exception] = Future[T] def wrap[T, E <: Exception](t: => T): Future[T] = Future { t } - + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = Await.result(value, duration.Duration.Inf) - - override def flatWrap[Res, E <: Exception: ClassTag](blk: => Wrap[Res, E]): Wrap[Res, E] = blk - + + override def flatWrap[Res, E <: Exception : ClassTag]( + blk: => Wrap[Res, E]): Wrap[Res, E] = blk + override def toString = "[modes.returnFuture]" } -private[core] class TimeExecution[D: TimeSystem.ByDuration, +G <: MethodConstraint] extends Mode[G] { +private[core] class TimeExecution[ + D : TimeSystem.ByDuration, +G <: MethodConstraint] + extends Mode[G] { val ts = ?[TimeSystem.ByDuration[D]] type Wrap[+T, E <: Exception] = (T, D) def wrap[T, E <: Exception](r: => T): (T, D) = { @@ -275,7 +307,6 @@ private[core] class TimeExecution[D: TimeSystem.ByDuration, +G <: MethodConstrai } def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value._1 - + override def toString = "[modes.timeExecution]" } - diff --git a/core/shared/src/main/scala/rapture/core/package.scala b/core/shared/src/main/scala/rapture/core/package.scala index 5f2ead3..903383a 100644 --- a/core/shared/src/main/scala/rapture/core/package.scala +++ b/core/shared/src/main/scala/rapture/core/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -24,35 +24,42 @@ import reflect.ClassTag object `package` { - type CanBuildFrom[-From, -Elem, +To] = collection.generic.CanBuildFrom[From, Elem, To] + type CanBuildFrom[-From, -Elem, +To] = collection.generic.CanBuildFrom[ + From, Elem, To] def alloc[T] = new AllocApply[T](0) def each[E <: Exception] = EachUnapplied[E]() implicit class EnrichedString(val string: String) extends AnyVal { - def as[T](implicit parser: StringParser[T], mode: Mode[`String#as`]): mode.Wrap[T, parser.Throws] = + def as[T](implicit parser: StringParser[T], + mode: Mode[`String#as`]): mode.Wrap[T, parser.Throws] = parser.parse(string, mode) } def indentTree(s: String): String = { var indent = 0 s flatMap { - case '(' => indent += 1; s"(\n${" "*indent}" - case ')' => indent -= 1; s"\n${" "*indent})" - case ',' => s",\n${" "*(indent - 1)}" + case '(' => indent += 1; s"(\n${" " * indent}" + case ')' => indent -= 1; s"\n${" " * indent})" + case ',' => s",\n${" " * (indent - 1)}" case ' ' => "" case o => o.toString } } - implicit class EnrichedCollection[Coll[X] <: Seq[X]](val coll: Coll[String]) extends AnyVal { - def mapAs[T](implicit parser: StringParser[T], cbf: CanBuildFrom[Coll[String], T, Coll[T]], mode: Mode[`Seq#mapAs`]): - mode.Wrap[Coll[T], parser.Throws] = mode.wrap[Coll[T], parser.Throws] { - val b = cbf(coll) - coll foreach { x => b += mode.unwrap(parser.parse(x, mode)) } - b.result - } + implicit class EnrichedCollection[Coll[X] <: Seq[X]](val coll: Coll[String]) + extends AnyVal { + def mapAs[T](implicit parser: StringParser[T], + cbf: CanBuildFrom[Coll[String], T, Coll[T]], + mode: Mode[`Seq#mapAs`]): mode.Wrap[Coll[T], parser.Throws] = + mode.wrap[Coll[T], parser.Throws] { + val b = cbf(coll) + coll foreach { x => + b += mode.unwrap(parser.parse(x, mode)) + } + b.result + } } private[rapture] type implicitNotFound = annotation.implicitNotFound @@ -65,22 +72,24 @@ object `package` { def modally[G <: MethodConstraint, E <: Exception] = new Modal[G, E] - def yCombinator[A, B](fn: (A => B) => (A => B)): A => B = fn(yCombinator(fn))(_) + def yCombinator[A, B](fn: (A => B) => (A => B)): A => B = + fn(yCombinator(fn))(_) /** Times how long it takes to perform an operation, returning a pair of the result and the * duration of the operation in milliseconds. */ - def time[T, D: TimeSystem.ByDuration](blk: => T): (T, D) = { + def time[T, D : TimeSystem.ByDuration](blk: => T): (T, D) = { val t = System.currentTimeMillis (blk, ?[TimeSystem.ByDuration[D]].duration(t, System.currentTimeMillis)) } - + def enumerateMembers[T] = new Enumerator[T] - + @inline implicit class SeqExtras[A, C[A] <: Seq[A]](val xs: C[A]) { /** Inserts an element between each of the elements of the sequence. */ - def intersperse[B >: A, That](between: B)(implicit bf: CanBuildFrom[C[A], B, That]): That = { + def intersperse[B >: A, That](between: B)( + implicit bf: CanBuildFrom[C[A], B, That]): That = { val b = bf(xs) xs.init foreach { x => b += x @@ -92,7 +101,8 @@ object `package` { /** Inserts an element between each of the elements of the sequence, and additionally * prepends and affixes the sequence with `before` and `after`. */ - def intersperse[B >: A, That](before: B, between: B, after: B)(implicit bf: CanBuildFrom[C[A], B, That]): That = { + def intersperse[B >: A, That](before: B, between: B, after: B)( + implicit bf: CanBuildFrom[C[A], B, That]): That = { val b = bf(xs) b += before xs.init foreach { x => @@ -105,15 +115,20 @@ object `package` { } /** Convenience method for zipping a sequence with a value derived from each element. */ - def zipWith[T](fn: A => T)(implicit bf: CanBuildFrom[C[A], (A, T), C[(A, T)]]): C[(A, T)] = { + def zipWith[T](fn: A => T)( + implicit bf: CanBuildFrom[C[A], (A, T), C[(A, T)]]): C[(A, T)] = { val b = bf(xs) - xs.foreach { x => b += ((x, fn(x))) } + xs.foreach { x => + b += ((x, fn(x))) + } b.result } } - implicit class EnrichedCollectionCompanion[+C[X] <: collection.GenTraversable[X]]( - val cc: collection.generic.GenericCompanion[C]) extends AnyVal { + implicit class EnrichedCollectionCompanion[ + +C[X] <: collection.GenTraversable[X]]( + val cc: collection.generic.GenericCompanion[C]) + extends AnyVal { def strap[T](xs: Strapped[T]*): C[T] = { val b = cc.newBuilder[T] xs foreach { b ++= _.elems } @@ -122,7 +137,7 @@ object `package` { } implicit class EnrichedArrayCompanion(val arr: Array.type) extends AnyVal { - def strap[T: ClassTag](xs: Strapped[T]*): Array[T] = { + def strap[T : ClassTag](xs: Strapped[T]*): Array[T] = { val b = Array.newBuilder[T] xs foreach { b ++= _.elems } b.result() @@ -143,7 +158,8 @@ trait `String#as` extends MethodConstraint private[core] object Strapped { implicit def toStrapped[T](t: T): Strapped[T] = Strapped(List(t)) implicit def toStrapped[T](elems: Iterable[T]): Strapped[T] = Strapped(elems) - implicit def toStrapped[T](opt: Option[T]): Strapped[T] = Strapped(opt.toList) + implicit def toStrapped[T](opt: Option[T]): Strapped[T] = + Strapped(opt.toList) } private[core] case class Strapped[+T](elems: Iterable[T]) extends AnyVal @@ -153,6 +169,7 @@ private[core] class Enumerator[T] { } private[core] class Modal[G <: MethodConstraint, E <: Exception] { - def apply[T](fn: => T)(implicit mode: Mode[G], typeTag: TypeTag[E]): mode.Wrap[T, E] = mode.wrap(fn) + def apply[T](fn: => T)( + implicit mode: Mode[G], typeTag: TypeTag[E]): mode.Wrap[T, E] = + mode.wrap(fn) } - diff --git a/core/shared/src/main/scala/rapture/core/parser.scala b/core/shared/src/main/scala/rapture/core/parser.scala index bb8e6bd..dd9513a 100644 --- a/core/shared/src/main/scala/rapture/core/parser.scala +++ b/core/shared/src/main/scala/rapture/core/parser.scala @@ -13,25 +13,29 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core import scala.util.Try object ParseException -case class ParseException(bad: String, typ: String) extends Exception(s"could not parse '$bad' as $typ") +case class ParseException(bad: String, typ: String) + extends Exception(s"could not parse '$bad' as $typ") package booleanParsing { object strict { def apply() = implicitBooleanParsing - implicit def implicitBooleanParsing(implicit br: BooleanRepresentation): BooleanParser = + implicit def implicitBooleanParsing( + implicit br: BooleanRepresentation): BooleanParser = new BooleanParser { - def parse(s: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] = mode.wrap { - if(s == br.trueValue) true - else if(s == br.falseValue) false - else mode.exception(InvalidBoolean(s)) - } + def parse( + s: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] = + mode.wrap { + if (s == br.trueValue) true + else if (s == br.falseValue) false + else mode.exception(InvalidBoolean(s)) + } } } @@ -40,121 +44,183 @@ package booleanParsing { private val trueValues = List("true", "yes", "on", "1") private val falseValues = List("false", "no", "off", "0") implicit val implicitBooleanParsing: BooleanParser = new BooleanParser { - def parse(b: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] = mode.wrap { - if(trueValues.contains(b.toLowerCase)) true - else if(falseValues.contains(b.toLowerCase)) false - else mode.exception(ParseException(b, "boolean using permissive parser")) - } + def parse(b: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] = + mode.wrap { + if (trueValues.contains(b.toLowerCase)) true + else if (falseValues.contains(b.toLowerCase)) false + else + mode.exception( + ParseException(b, "boolean using permissive parser")) + } } } } -object BooleanParser { implicit val implicitBooleanParser: BooleanParser = booleanParsing.permissive() } -trait BooleanParser { def parse(s: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] } +object BooleanParser { + implicit val implicitBooleanParser: BooleanParser = + booleanParsing.permissive() +} +trait BooleanParser { + def parse(s: String, mode: Mode[_]): mode.Wrap[Boolean, InvalidBoolean] +} abstract class StringParser[T] extends Functor[StringParser, T] { strp => type Throws <: Exception - def parse(string: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] + def parse( + string: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] - def rawMap[T2](fn: (T, Mode[_ <: MethodConstraint]) => T2): StringParser[T2] { type Throws = strp.Throws } = + def rawMap[T2](fn: (T, Mode[_ <: MethodConstraint]) => T2 + ): StringParser[T2] { type Throws = strp.Throws } = new StringParser[T2] { type Throws = strp.Throws - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T2, Throws] = + def parse(s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T2, Throws] = mode.wrap(fn(mode.unwrap(strp.parse(s, mode)), mode)) } } -case class InvalidBoolean(value: String) extends Exception(s"""The value "$value" is not a valid boolean.""") -case class InvalidNumber(value: String, numberType: String) extends Exception(s"""The value "$value" is not a valid $numberType.""") +case class InvalidBoolean(value: String) + extends Exception(s"""The value "$value" is not a valid boolean.""") +case class InvalidNumber(value: String, numberType: String) + extends Exception(s"""The value "$value" is not a valid $numberType.""") trait StringParser_1 { - implicit def optParser[T: StringParser]: StringParser[Option[T]] { type Throws = Nothing } = new StringParser[Option[T]] { + implicit def optParser[T : StringParser]: StringParser[Option[T]] { + type Throws = Nothing + } = new StringParser[Option[T]] { type Throws = Nothing - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Option[T], Nothing] = mode.wrap { - try Some(mode.unwrap(?[StringParser[T]].parse(s, mode))) catch { - case e: Exception => None + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Option[T], Nothing] = + mode.wrap { + try Some(mode.unwrap(?[StringParser[T]].parse(s, mode))) catch { + case e: Exception => None + } } - } } - - implicit def tryParser[T: StringParser]: StringParser[Try[T]] { type Throws = Nothing } = new StringParser[Try[T]] { + + implicit def tryParser[T : StringParser]: StringParser[Try[T]] { type Throws = Nothing - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Try[T], Nothing] = mode.wrap { - ?[StringParser[T]].parse(s, modes.returnTry()) - } + } = new StringParser[Try[T]] { + type Throws = Nothing + def parse(s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Try[T], Nothing] = + mode.wrap { + ?[StringParser[T]].parse(s, modes.returnTry()) + } } } object StringParser extends StringParser_1 { - implicit def booleanParser(implicit bp: BooleanParser): StringParser[Boolean] { type Throws = InvalidBoolean } = new StringParser[Boolean] { - type Throws = InvalidBoolean - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Boolean, InvalidBoolean] = bp.parse(s, mode.generic) - } + implicit def booleanParser(implicit bp: BooleanParser + ): StringParser[Boolean] { type Throws = InvalidBoolean } = + new StringParser[Boolean] { + type Throws = InvalidBoolean + def parse(s: String, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[Boolean, InvalidBoolean] = bp.parse(s, mode.generic) + } - implicit val byteParser: StringParser[Byte] { type Throws = InvalidNumber } = new StringParser[Byte] { - type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Byte, InvalidNumber] = mode.wrap { - try java.lang.Byte.parseByte(s) catch { - case e: NumberFormatException => mode.exception(InvalidNumber(s, "byte")) - } + implicit val byteParser: StringParser[Byte] { type Throws = InvalidNumber } = + new StringParser[Byte] { + type Throws = InvalidNumber + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Byte, InvalidNumber] = + mode.wrap { + try java.lang.Byte.parseByte(s) catch { + case e: NumberFormatException => + mode.exception(InvalidNumber(s, "byte")) + } + } } - } - implicit val charParser: StringParser[Char] { type Throws = InvalidNumber } = new StringParser[Char] { - type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Char, InvalidNumber] = mode.wrap { - if(s.length == 1) s.charAt(0) else mode.exception(InvalidNumber(s, "character")) + implicit val charParser: StringParser[Char] { type Throws = InvalidNumber } = + new StringParser[Char] { + type Throws = InvalidNumber + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Char, InvalidNumber] = + mode.wrap { + if (s.length == 1) s.charAt(0) + else mode.exception(InvalidNumber(s, "character")) + } } - } - implicit val shortParser: StringParser[Short] { type Throws = InvalidNumber } = new StringParser[Short] { - type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Short, InvalidNumber] = mode.wrap { - try java.lang.Short.parseShort(s) catch { - case e: NumberFormatException => mode.exception(InvalidNumber(s, "short")) - } + implicit val shortParser: StringParser[Short] { type Throws = InvalidNumber } = + new StringParser[Short] { + type Throws = InvalidNumber + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Short, InvalidNumber] = + mode.wrap { + try java.lang.Short.parseShort(s) catch { + case e: NumberFormatException => + mode.exception(InvalidNumber(s, "short")) + } + } } - } - implicit val intParser: StringParser[Int] { type Throws = InvalidNumber } = new StringParser[Int] { - type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Int, InvalidNumber] = mode.wrap { - try java.lang.Integer.parseInt(s) catch { - case e: NumberFormatException => mode.exception(InvalidNumber(s, "integer")) - } + implicit val intParser: StringParser[Int] { type Throws = InvalidNumber } = + new StringParser[Int] { + type Throws = InvalidNumber + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Int, InvalidNumber] = + mode.wrap { + try java.lang.Integer.parseInt(s) catch { + case e: NumberFormatException => + mode.exception(InvalidNumber(s, "integer")) + } + } } - } - implicit val longParser: StringParser[Long] { type Throws = InvalidNumber } = new StringParser[Long] { - type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Long, InvalidNumber] = mode.wrap { - try java.lang.Long.parseLong(s) catch { - case e: NumberFormatException => mode.exception(InvalidNumber(s, "long")) - } + implicit val longParser: StringParser[Long] { type Throws = InvalidNumber } = + new StringParser[Long] { + type Throws = InvalidNumber + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Long, InvalidNumber] = + mode.wrap { + try java.lang.Long.parseLong(s) catch { + case e: NumberFormatException => + mode.exception(InvalidNumber(s, "long")) + } + } } - } - implicit val stringParser: StringParser[String] { type Throws = Nothing } = new StringParser[String] { - type Throws = Nothing - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[String, Nothing] = mode.wrap(s) - } + implicit val stringParser: StringParser[String] { type Throws = Nothing } = + new StringParser[String] { + type Throws = Nothing + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[String, Nothing] = + mode.wrap(s) + } implicit val doubleParser: StringParser[Double] = new StringParser[Double] { type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Double, InvalidNumber] = mode.wrap { - try java.lang.Double.parseDouble(s) catch { - case e: NumberFormatException => mode.exception(ParseException(s, "double")) + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Double, InvalidNumber] = + mode.wrap { + try java.lang.Double.parseDouble(s) catch { + case e: NumberFormatException => + mode.exception(ParseException(s, "double")) + } } - } } implicit val floatParser: StringParser[Float] = new StringParser[Float] { type Throws = InvalidNumber - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Float, InvalidNumber] = mode.wrap { - try java.lang.Float.parseFloat(s) catch { - case e: NumberFormatException => mode.exception(InvalidNumber(s, "float")) + def parse( + s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Float, InvalidNumber] = + mode.wrap { + try java.lang.Float.parseFloat(s) catch { + case e: NumberFormatException => + mode.exception(InvalidNumber(s, "float")) + } } - } } } - diff --git a/core/shared/src/main/scala/rapture/core/pool.scala b/core/shared/src/main/scala/rapture/core/pool.scala index 1779501..5f7060e 100644 --- a/core/shared/src/main/scala/rapture/core/pool.scala +++ b/core/shared/src/main/scala/rapture/core/pool.scala @@ -13,15 +13,15 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core import scala.collection.mutable.Queue /** Implements a dynamic pool of some resource, e.g. database connections. */ -abstract class Pool[Resource] -{ +abstract class Pool[Resource] { + /** Implement to make new resources. */ protected def make(): Resource @@ -35,7 +35,7 @@ abstract class Pool[Resource] protected def spare = 5 /** How long to leave surplus resources unused before discarding them. */ - protected def timeout = 10*60000L + protected def timeout = 10 * 60000L private val pool = new Queue[Resource] private var poolCount = 0 @@ -49,11 +49,12 @@ abstract class Pool[Resource] /** Acquire a resource without any nesting guarantees. Avoid this method. */ def acquireDirect(): Resource = pool.synchronized { - if(poolCount == 0) make() + if (poolCount == 0) make() else { val r = pool.dequeue poolCount = poolCount - 1 - if(check(r)) r else { + if (check(r)) r + else { dispose(r) make() } @@ -63,8 +64,8 @@ abstract class Pool[Resource] /** Release a directly-acquired resource. */ def releaseDirect(r: Resource): Unit = pool.synchronized { val now = System.currentTimeMillis() - if(poolCount < spare) lastLow = now - if(lastLow > now - timeout) { + if (poolCount < spare) lastLow = now + if (lastLow > now - timeout) { pool.enqueue(r) poolCount = poolCount + 1 } else dispose(r) @@ -72,7 +73,7 @@ abstract class Pool[Resource] /** Dispose of all resources not currently in use. */ def disposeAll() = pool.synchronized { - while(poolCount > 0) { + while (poolCount > 0) { dispose(pool.dequeue) poolCount = poolCount - 1 } diff --git a/core/shared/src/main/scala/rapture/core/result.scala b/core/shared/src/main/scala/rapture/core/result.scala index 22e6b8c..4ec8adc 100644 --- a/core/shared/src/main/scala/rapture/core/result.scala +++ b/core/shared/src/main/scala/rapture/core/result.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -24,36 +24,46 @@ import scala.reflect.ClassTag import scala.annotation.unchecked._ object Result { - private[core] def apply[T, E <: Exception](result: => T, errors: Seq[(ClassTag[_], (String, Exception))]) = try { - if(errors.isEmpty) Answer[T, E](result) else Errata[T, E](errors) - } catch { case e: Throwable => if(errors.isEmpty) Unforeseen[T, E](e) else Errata[T, E](errors) } + private[core] def apply[T, E <: Exception]( + result: => T, errors: Seq[(ClassTag[_], (String, Exception))]) = + try { + if (errors.isEmpty) Answer[T, E](result) else Errata[T, E](errors) + } catch { + case e: Throwable => + if (errors.isEmpty) Unforeseen[T, E](e) else Errata[T, E](errors) + } def apply[T](result: => T): Result[T, Nothing] = - try Answer[T, Nothing](result) catch { case e: Throwable => Unforeseen[T, Nothing](e) } + try Answer[T, Nothing](result) catch { + case e: Throwable => Unforeseen[T, Nothing](e) + } def catching[E <: Exception]: Catching[E] = new Catching[E]() /** Construct an answer. */ - def answer[T, E <: Exception](a : T): Result[T, E] = Answer[T, E](a) + def answer[T, E <: Exception](a: T): Result[T, E] = Answer[T, E](a) /** Construct an errata. */ - def errata[T, E <: Exception](e : E)(implicit cte : ClassTag[E]) = Errata[T, E](e) - + def errata[T, E <: Exception](e: E)(implicit cte: ClassTag[E]) = + Errata[T, E](e) } class Catching[E <: Exception]() { - def apply[T](blk: => T)(implicit classTag: ClassTag[E]): Result[T, E] = try Answer(blk) catch { - case e: E => Errata(Vector((?[ClassTag[E]], ("", e)))) - case e: Throwable => Unforeseen(e) - } + def apply[T](blk: => T)(implicit classTag: ClassTag[E]): Result[T, E] = + try Answer(blk) catch { + case e: E => Errata(Vector((?[ClassTag[E]], ("", e)))) + case e: Throwable => Unforeseen(e) + } } -sealed abstract class Result[+T, E <: Exception](val answer: T, val errors: Seq[(ClassTag[_], (String, Exception))], +sealed abstract class Result[+T, E <: Exception]( + val answer: T, + val errors: Seq[(ClassTag[_], (String, Exception))], val unforeseen: Option[Throwable] = None) { - - def errata[E2 >: E: ClassTag]: Seq[E2] = + + def errata[E2 >: E : ClassTag]: Seq[E2] = errors.filter(_._1 == ?[ClassTag[E2]]).map(_._2.asInstanceOf[E2]) - + def exceptions: Seq[Exception] = errors.map(_._2._2) def get: T = { @@ -62,29 +72,34 @@ sealed abstract class Result[+T, E <: Exception](val answer: T, val errors: Seq[ answer } - def flatMap[T2, E2 <: Exception](fn: T => Result[T2, E2]): Result[T2, E with E2] = + def flatMap[T2, E2 <: Exception]( + fn: T => Result[T2, E2]): Result[T2, E with E2] = try { val res = fn(answer) val probs = res.errors ++ errors Result[T2, E with E2](res.get, probs) } catch { - case e: NullPointerException if errors.nonEmpty => Errata[T2, E with E2](errors) + case e: NullPointerException if errors.nonEmpty => + Errata[T2, E with E2](errors) case e: Throwable => Unforeseen[T2, E with E2](e) } def map[T2](fn: T => T2) = Result[T2, E](fn(answer), errors) - def resolve[E2, T2 >: T](handlers: Each[E2, T2]*)(implicit ev: E2 <:< E): Resolved[T2, Nothing] = this match { + def resolve[E2, T2 >: T](handlers: Each[E2, T2]*)( + implicit ev: E2 <:< E): Resolved[T2, Nothing] = this match { case Unforeseen(e) => Unforeseen[T2, Nothing](e) case Answer(a) => Answer[T2, Nothing](a) case Errata((t, (_, err)) +: _) => - Answer[T2, Nothing](handlers.find { case Each(fn, ct) => ct == t }.get.fn(err.asInstanceOf[E2])) + Answer[T2, Nothing](handlers.find { case Each(fn, ct) => ct == t }.get + .fn(err.asInstanceOf[E2])) } def reconcile[E2, E3 <: Exception](handlers: Each[E2, E3]*) = { - val hs = handlers.map { case Each(e, typ) => typ -> e }.toMap[ClassTag[_], E2 => E3] + val hs = handlers.map { case Each(e, typ) => typ -> e } + .toMap[ClassTag[_], E2 => E3] errors.map { case (t, (p, e)) => hs(t)(e.asInstanceOf[E2]) } } @@ -132,7 +147,9 @@ sealed abstract class Result[+T, E <: Exception](val answer: T, val errors: Seq[ } /** Return a collection containing -- if the result was successful -- the answer. */ - def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]]): Col[T @uncheckedVariance] = this match { + def to[Col[_]]( + implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]] + ): Col[T @uncheckedVariance] = this match { case Answer(ans) => val builder = cbf() builder += ans @@ -180,57 +197,69 @@ sealed abstract class Result[+T, E <: Exception](val answer: T, val errors: Seq[ this match { case Answer(b) => val t = this.get - if(p(b)) - Answer(t) + if (p(b)) Answer(t) else - Errata[T, E with NotMatchingFilter](Seq((implicitly[ClassTag[NotMatchingFilter]], ("", NotMatchingFilter(t))))) + Errata[T, E with NotMatchingFilter]( + Seq((implicitly[ClassTag[NotMatchingFilter]], + ("", NotMatchingFilter(t))))) case Errata(e) => Errata[T, E with NotMatchingFilter](e) case Unforeseen(e) => Unforeseen[T, E with NotMatchingFilter](e) } /** Alias for filter */ - def withFilter(p: T => Boolean): Result[T, E with NotMatchingFilter] = filter(p) - + def withFilter(p: T => Boolean): Result[T, E with NotMatchingFilter] = + filter(p) } object Resolved { - def unapply[T, E <: Exception](res: Result[T, E]): Option[(T, Option[Throwable])] = + def unapply[T, E <: Exception]( + res: Result[T, E]): Option[(T, Option[Throwable])] = Some(res.answer -> res.unforeseen) - def apply[T, E <: Exception](answer: T, unforeseen: Option[E]) = if(unforeseen.isEmpty) Answer(answer) else Unforeseen(unforeseen.get) + def apply[T, E <: Exception](answer: T, unforeseen: Option[E]) = + if (unforeseen.isEmpty) Answer(answer) else Unforeseen(unforeseen.get) } -sealed abstract class Resolved[+T, E <: Exception](answer: T, unforeseen: Option[Throwable]) +sealed abstract class Resolved[+T, E <: Exception]( + answer: T, unforeseen: Option[Throwable]) extends Result[T, E](answer, Seq(), unforeseen) { override def equals(that: Any) = that match { - case that: Resolved[_, _] => that.answer == answer && that.unforeseen == unforeseen + case that: Resolved [_, _] => + that.answer == answer && that.unforeseen == unforeseen case _ => false } override def hashCode = answer.hashCode ^ unforeseen.hashCode - } -case class Answer[T, E <: Exception](override val answer: T) extends Resolved[T, E](answer, None) +case class Answer[T, E <: Exception](override val answer: T) + extends Resolved[T, E](answer, None) -case class Errata[T, E <: Exception](override val errors: Seq[(ClassTag[_], (String, Exception))]) extends - Result[T, E](null.asInstanceOf[T], errors) { - override def toString = "Errata(\n "+ errors.map { case (t, (p, e)) => s"$t: ${e.getMessage} [$p]" }.mkString(",\n ") +"\n)" +case class Errata[T, E <: Exception]( + override val errors: Seq[(ClassTag[_], (String, Exception))]) + extends Result[T, E](null.asInstanceOf[T], errors) { + override def toString = + "Errata(\n " + errors.map { + case (t, (p, e)) => s"$t: ${e.getMessage} [$p]" + }.mkString(",\n ") + "\n)" } object Errata { - def apply[T, E <: Exception](e: => E) - (implicit classTag: ClassTag[E]): Result[T, E] = Errata(Vector((?[ClassTag[E]], ("", e)))) + def apply[T, E <: Exception](e: => E)( + implicit classTag: ClassTag[E]): Result[T, E] = + Errata(Vector((?[ClassTag[E]], ("", e)))) } -case class Unforeseen[T, E <: Exception](e: Throwable) extends Resolved[T, E](null.asInstanceOf[T], Some(e)) +case class Unforeseen[T, E <: Exception](e: Throwable) + extends Resolved[T, E](null.asInstanceOf[T], Some(e)) case class AbortException() extends Exception -private[core] class ReturnResultMode[+Group <: MethodConstraint] extends Mode[Group] { +private[core] class ReturnResultMode[+Group <: MethodConstraint] + extends Mode[Group] { type Wrap[+R, E <: Exception] = Result[R, E] - + def wrap[R, E <: Exception](blk: => R): Result[R, E] = { try { val res = blk @@ -239,41 +268,46 @@ private[core] class ReturnResultMode[+Group <: MethodConstraint] extends Mode[Gr case AbortException() => Result[R, E](null.asInstanceOf[R], accumulated) case e: Throwable => - if(accumulated.isEmpty) Unforeseen[R, E](e) + if (accumulated.isEmpty) Unforeseen[R, E](e) else Errata(accumulated) } } - private var accumulated: Vector[(ClassTag[_], (String, Exception))] = Vector() - override def exception[T, E <: Exception: ClassTag](e: E, continue: Boolean = true): T = { + private var accumulated: Vector[(ClassTag[_], (String, Exception))] = + Vector() + override def exception[T, E <: Exception : ClassTag]( + e: E, continue: Boolean = true): T = { accumulated :+= ((?[ClassTag[E]], (callPath, e))) - if(continue) null.asInstanceOf[T] else throw AbortException() + if (continue) null.asInstanceOf[T] else throw AbortException() } - override def catching[E <: Exception: ClassTag, T](blk: => T) = try blk catch { - case e: E => - exception(e) - case e: Exception => - throw e - } + override def catching[E <: Exception : ClassTag, T](blk: => T) = + try blk catch { + case e: E => + exception(e) + case e: Exception => + throw e + } + + override def flatWrap[R, E <: Exception : ClassTag]( + blk: => Wrap[R, E]): Wrap[R, E] = blk + + def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = + value match { + case Answer(a) => a + case Errata(xs) => null.asInstanceOf[Return] + case Unforeseen(e) => throw e + case _ => ??? + } - override def flatWrap[R, E <: Exception: ClassTag](blk: => Wrap[R, E]): Wrap[R, E] = blk - - def unwrap[Return](value: => Wrap[Return, _ <: Exception]): Return = value match { - case Answer(a) => a - case Errata(xs) => null.asInstanceOf[Return] - case Unforeseen(e) => throw e - case _ => ??? - } - override def toString = "[modes.returnResult]" } case class Each[-E, +T](fn: E => T, classTag: ClassTag[_]) case class EachUnapplied[E]() { - def apply[R](fn: E => R)(implicit classTag: ClassTag[E]): Each[E, R] = Each(fn, classTag) + def apply[R](fn: E => R)(implicit classTag: ClassTag[E]): Each[E, R] = + Each(fn, classTag) } -case class NotMatchingFilter(value : Any) extends Exception(s"value '$value' did not match filter") - - +case class NotMatchingFilter(value: Any) + extends Exception(s"value '$value' did not match filter") diff --git a/core/shared/src/main/scala/rapture/core/serializer.scala b/core/shared/src/main/scala/rapture/core/serializer.scala index f862900..442f99c 100644 --- a/core/shared/src/main/scala/rapture/core/serializer.scala +++ b/core/shared/src/main/scala/rapture/core/serializer.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -83,77 +83,96 @@ package integerFormats { } object to1sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(1) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(1) } object to2sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(2) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(2) } object to3sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(3) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(3) } object to4sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(4) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(4) } object to5sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(5) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(5) } object to6sf { def apply() = implicitIntegerFormat - implicit val implicitIntegerFormat: IntegerFormat = IntegerSignificantFigures(6) + implicit val implicitIntegerFormat: IntegerFormat = + IntegerSignificantFigures(6) } } package booleanRepresentations { object trueFalse { def apply() = implicitBooleanRepresentation - implicit val implicitBooleanRepresentation: BooleanRepresentation = BooleanRepresentation("true", "false") + implicit val implicitBooleanRepresentation: BooleanRepresentation = + BooleanRepresentation("true", "false") } - + object digital { def apply() = implicitBooleanRepresentation - implicit val implicitBooleanRepresentation: BooleanRepresentation = BooleanRepresentation("1", "0") + implicit val implicitBooleanRepresentation: BooleanRepresentation = + BooleanRepresentation("1", "0") } object yesNo { def apply() = implicitBooleanRepresentation - implicit val implicitBooleanRepresentation: BooleanRepresentation = BooleanRepresentation("yes", "no") + implicit val implicitBooleanRepresentation: BooleanRepresentation = + BooleanRepresentation("yes", "no") } - + object onOff { def apply() = implicitBooleanRepresentation - implicit val implicitBooleanRepresentation: BooleanRepresentation = BooleanRepresentation("on", "off") + implicit val implicitBooleanRepresentation: BooleanRepresentation = + BooleanRepresentation("on", "off") } } object BooleanRepresentation { - implicit val defaultBooleanRepresentation: BooleanRepresentation = BooleanRepresentation("true", "false") + implicit val defaultBooleanRepresentation: BooleanRepresentation = + BooleanRepresentation("true", "false") } case class BooleanRepresentation(trueValue: String, falseValue: String) -object DecimalFormat { implicit val defaultRounding: DecimalFormat = SignificantFigures(4) } +object DecimalFormat { + implicit val defaultRounding: DecimalFormat = SignificantFigures(4) +} trait DecimalFormat { def format(bigDecimal: BigDecimal): String } case class DecimalPlaces(n: Int) extends DecimalFormat { def format(bigDecimal: BigDecimal): String = { val integral = bigDecimal.toBigInt.toString.length - bigDecimal.round(new java.math.MathContext(integral + n)).setScale(n).toString + bigDecimal + .round(new java.math.MathContext(integral + n)) + .setScale(n) + .toString } } case class SignificantFigures(n: Int) extends DecimalFormat { - def format(bigDecimal: BigDecimal) = bigDecimal.round(new java.math.MathContext(n)).toString + def format(bigDecimal: BigDecimal) = + bigDecimal.round(new java.math.MathContext(n)).toString } case object ExactDecimal extends DecimalFormat { def format(bigDecimal: BigDecimal) = bigDecimal.toString } -object IntegerFormat { implicit val defaultRounding: IntegerFormat = ExactInteger } +object IntegerFormat { + implicit val defaultRounding: IntegerFormat = ExactInteger +} trait IntegerFormat { def format(bigInt: BigInt): String } case object ExactInteger extends IntegerFormat { @@ -165,45 +184,73 @@ case class IntegerSignificantFigures(n: Int) extends IntegerFormat { } object StringSerializer { - implicit def booleanSerializer(implicit bs: BooleanRepresentation): StringSerializer[Boolean] = + implicit def booleanSerializer( + implicit bs: BooleanRepresentation): StringSerializer[Boolean] = new StringSerializer[Boolean] { - def serialize(s: Boolean): String = if(s) bs.trueValue else bs.falseValue + def serialize(s: Boolean): String = + if (s) bs.trueValue else bs.falseValue } - implicit val charSerializer: StringSerializer[Char] = new StringSerializer[Char] { - def serialize(s: Char): String = s.toString - } + implicit val charSerializer: StringSerializer[Char] = + new StringSerializer[Char] { + def serialize(s: Char): String = s.toString + } - implicit def byteSerializer(implicit df: IntegerFormat): StringSerializer[Byte] = - new StringSerializer[Byte] { def serialize(s: Byte): String = df.format(BigInt(s)) } + implicit def byteSerializer( + implicit df: IntegerFormat): StringSerializer[Byte] = + new StringSerializer[Byte] { + def serialize(s: Byte): String = df.format(BigInt(s)) + } - implicit def shortSerializer(implicit df: IntegerFormat): StringSerializer[Short] = - new StringSerializer[Short] { def serialize(s: Short): String = df.format(BigInt(s)) } + implicit def shortSerializer( + implicit df: IntegerFormat): StringSerializer[Short] = + new StringSerializer[Short] { + def serialize(s: Short): String = df.format(BigInt(s)) + } - implicit def longSerializer(implicit df: IntegerFormat): StringSerializer[Long] = - new StringSerializer[Long] { def serialize(s: Long): String = df.format(BigInt(s)) } + implicit def longSerializer( + implicit df: IntegerFormat): StringSerializer[Long] = + new StringSerializer[Long] { + def serialize(s: Long): String = df.format(BigInt(s)) + } - implicit def intSerializer(implicit df: IntegerFormat): StringSerializer[Int] = - new StringSerializer[Int] { def serialize(s: Int): String = df.format(BigInt(s)) } + implicit def intSerializer( + implicit df: IntegerFormat): StringSerializer[Int] = + new StringSerializer[Int] { + def serialize(s: Int): String = df.format(BigInt(s)) + } implicit val stringSerializer: StringSerializer[String] = new StringSerializer[String] { def serialize(s: String): String = s } - implicit def doubleSerializer(implicit df: DecimalFormat): StringSerializer[Double] = - new StringSerializer[Double] { def serialize(s: Double): String = df.format(BigDecimal(s)) } - - implicit def floatSerializer(implicit df: DecimalFormat): StringSerializer[Float] = - new StringSerializer[Float] { def serialize(f: Float): String = df.format(BigDecimal(f.toDouble)) } - - implicit def bigDecimalSerializer(implicit df: DecimalFormat): StringSerializer[BigDecimal] = - new StringSerializer[BigDecimal] { def serialize(s: BigDecimal): String = df.format(s) } - - implicit def bigIntSerializer(implicit df: IntegerFormat): StringSerializer[BigInt] = - new StringSerializer[BigInt] { def serialize(s: BigInt): String = df.format(s) } + implicit def doubleSerializer( + implicit df: DecimalFormat): StringSerializer[Double] = + new StringSerializer[Double] { + def serialize(s: Double): String = df.format(BigDecimal(s)) + } + + implicit def floatSerializer( + implicit df: DecimalFormat): StringSerializer[Float] = + new StringSerializer[Float] { + def serialize(f: Float): String = df.format(BigDecimal(f.toDouble)) + } + + implicit def bigDecimalSerializer( + implicit df: DecimalFormat): StringSerializer[BigDecimal] = + new StringSerializer[BigDecimal] { + def serialize(s: BigDecimal): String = df.format(s) + } + + implicit def bigIntSerializer( + implicit df: IntegerFormat): StringSerializer[BigInt] = + new StringSerializer[BigInt] { + def serialize(s: BigInt): String = df.format(s) + } } /** A generic string serializer */ -@implicitNotFound("It is not possible to serialize a value of type ${T} to a String without a"+ +@implicitNotFound( + "It is not possible to serialize a value of type ${T} to a String without a" + " valid StringSerializer instance in scope.") trait StringSerializer[-T] { stringSerializer => def serialize(string: T): String @@ -213,13 +260,13 @@ trait StringSerializer[-T] { stringSerializer => } object String { - - def apply[T: StringSerializer](t: T): String = + + def apply[T : StringSerializer](t: T): String = ?[StringSerializer[T]].serialize(t) // Proxied from java.lang.String def format(str: String, any: AnyRef*) = java.lang.String.format(str, any: _*) - + def format(locale: java.util.Locale, str: String, any: AnyRef*) = java.lang.String.format(locale, str, any: _*) @@ -230,7 +277,8 @@ object String { def vauleOf(x: Double): String = java.lang.String.valueOf(x) def vauleOf(x: Int): String = java.lang.String.valueOf(x) def vauleOf(x: Any): String = java.lang.String.valueOf(x) - def vauleOf(x: Array[Char], a: Int, b: Int): String = java.lang.String.valueOf(x, a, b) + def vauleOf(x: Array[Char], a: Int, b: Int): String = + java.lang.String.valueOf(x, a, b) def vauleOf(x: Char): String = java.lang.String.valueOf(x) def vauleOf(x: Float): String = java.lang.String.valueOf(x) def vauleOf(x: Long): String = java.lang.String.valueOf(x) diff --git a/core/shared/src/main/scala/rapture/core/threads.scala b/core/shared/src/main/scala/rapture/core/threads.scala index c166d41..8db256c 100644 --- a/core/shared/src/main/scala/rapture/core/threads.scala +++ b/core/shared/src/main/scala/rapture/core/threads.scala @@ -13,21 +13,23 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core import java.lang.{ClassLoader => JClassLoader, Thread => JThread} object ClasspathUrlItem { - implicit def toClasspathUrlItem[T: ClasspathUrlable](t: T): ClasspathUrlItem = + implicit def toClasspathUrlItem[T : ClasspathUrlable]( + t: T): ClasspathUrlItem = ?[ClasspathUrlable[T]].toClasspathUrlItem(t) } case class ClasspathUrlItem(javaUrl: List[java.net.URL]) object ClasspathUrlable { - implicit def seqUrlable[T](implicit urlable: ClasspathUrlable[T]): ClasspathUrlable[List[T]] = + implicit def seqUrlable[T]( + implicit urlable: ClasspathUrlable[T]): ClasspathUrlable[List[T]] = new ClasspathUrlable[List[T]] { def toClasspathUrlItem(xs: List[T]): ClasspathUrlItem = ClasspathUrlItem(xs.flatMap(urlable.toClasspathUrlItem(_).javaUrl)) @@ -40,7 +42,8 @@ object ClassLoader { new ClassLoader(JThread.currentThread.getContextClassLoader) def apply(urls: ClasspathUrlItem*): ClassLoader = - new ClassLoader(new java.net.URLClassLoader(urls.flatMap(_.javaUrl).to[Array])) + new ClassLoader( + new java.net.URLClassLoader(urls.flatMap(_.javaUrl).to[Array])) } class ClassLoader(val javaClassLoader: JClassLoader) { @@ -54,17 +57,16 @@ class ClassLoader(val javaClassLoader: JClassLoader) { } object Thread { - def fork(threadName: String, daemon: Boolean = false)(blk: => Unit) - (implicit cl: ClassLoader): Thread = + def fork(threadName: String, daemon: Boolean = false)(blk: => Unit)( + implicit cl: ClassLoader): Thread = ThreadSpec(threadName, daemon)(blk).spawn() - def sleep[D: TimeSystem.ByDuration](duration: D) = + def sleep[D : TimeSystem.ByDuration](duration: D) = JThread.sleep(?[TimeSystem.ByDuration[D]].fromDuration(duration)) - } -case class ThreadSpec(name: String, daemon: Boolean = false)(blk: => Unit) - (implicit cl: ClassLoader) { +case class ThreadSpec(name: String, daemon: Boolean = false)( + blk: => Unit)(implicit cl: ClassLoader) { def spawn(): Thread = { val parentThread = JThread.currentThread @@ -77,7 +79,7 @@ case class ThreadSpec(name: String, daemon: Boolean = false)(blk: => Unit) javaThread.setDaemon(daemon) javaThread.setContextClassLoader(cl.javaClassLoader) javaThread.start() - + new Thread(this, javaThread) { def parentAlive = javaThread.isAlive } diff --git a/core/shared/src/main/scala/rapture/core/time.scala b/core/shared/src/main/scala/rapture/core/time.scala index 7630904..f7bed4b 100644 --- a/core/shared/src/main/scala/rapture/core/time.scala +++ b/core/shared/src/main/scala/rapture/core/time.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.core @@ -22,7 +22,8 @@ object TimeSystem { type ByDuration[T] = TimeSystem[_, T] } -@implicitNotFound("an implicit TimeSystem is required; please import timeSystems.numeric._ or "+ +@implicitNotFound( + "an implicit TimeSystem is required; please import timeSystems.numeric._ or " + "timeSystems.javaUtil._") trait TimeSystem[Instant, Duration] { def instant(millis: Long): Instant @@ -34,12 +35,13 @@ trait TimeSystem[Instant, Duration] { package timeSystems { object numeric { def apply(): TimeSystem[Long, Long] = timeSystemImplicit - implicit val timeSystemImplicit: TimeSystem[Long, Long] = new TimeSystem[Long, Long] { - def instant(millis: Long): Long = millis - def duration(from: Long, to: Long): Long = to - from - def fromInstant(inst: Long): Long = inst - def fromDuration(dur: Long): Long = dur - } + implicit val timeSystemImplicit: TimeSystem[Long, Long] = + new TimeSystem[Long, Long] { + def instant(millis: Long): Long = millis + def duration(from: Long, to: Long): Long = to - from + def fromInstant(inst: Long): Long = inst + def fromDuration(dur: Long): Long = dur + } } object javaUtil { diff --git a/crypto/shared/src/main/scala/rapture/crypto/aes.scala b/crypto/shared/src/main/scala/rapture/crypto/aes.scala index bb44fb1..752a5fe 100644 --- a/crypto/shared/src/main/scala/rapture/crypto/aes.scala +++ b/crypto/shared/src/main/scala/rapture/crypto/aes.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.crypto @@ -37,63 +37,71 @@ abstract class AesEncryption { private val keySpec = new SecretKeySpec(secretKey, "AES") def encrypt(clearText: Array[Byte], iv: Array[Byte] = null): Array[Byte] = { - + val cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding") - - if(iv == null) cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec) - else cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)) - + + if (iv == null) cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, keySpec) + else + cipher.init( + javax.crypto.Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(iv)) + val digest = Hash.digest[Sha256](clearText).bytes val paddedLength = (clearText.length >> 4) + 1 << 4 - val cipherText = new Array[Byte](paddedLength + (if(iv == null) 48 else 0)) - - if(iv == null) { + val cipherText = + new Array[Byte](paddedLength + (if (iv == null) 48 else 0)) + + if (iv == null) { Array.copy(cipher.getIV, 0, cipherText, 0, 16) cipher.update(digest, 0, 32, cipherText, 16) } - cipher.doFinal(clearText, 0, clearText.length, cipherText, if(iv == null) 48 else 0) - + cipher.doFinal( + clearText, 0, clearText.length, cipherText, if (iv == null) 48 else 0) + cipherText } - def decrypt(cipherText: Array[Byte], iv: Array[Byte] = null)(implicit mode: Mode[`AesEncryption#decrypt`]): - mode.Wrap[Array[Byte], DecryptionException] = mode.wrap { - if(iv == null && cipherText.length < 48) mode.exception(DecryptionException()) - + def decrypt(cipherText: Array[Byte], iv: Array[Byte] = null)( + implicit mode: Mode[`AesEncryption#decrypt`] + ): mode.Wrap[Array[Byte], DecryptionException] = mode.wrap { + if (iv == null && cipherText.length < 48) + mode.exception(DecryptionException()) + val cipher = javax.crypto.Cipher.getInstance("AES/CBC/PKCS5Padding") - val ips = if(iv == null) new IvParameterSpec(cipherText, 0, 16) else new IvParameterSpec(iv) - + val ips = + if (iv == null) new IvParameterSpec(cipherText, 0, 16) + else new IvParameterSpec(iv) + cipher.init(javax.crypto.Cipher.DECRYPT_MODE, keySpec, ips) - - val n = if(iv == null) 64 else 0 - - val digest1 = if(iv == null) cipher.update(cipherText, 16, 48) else Array[Byte]() + + val n = if (iv == null) 64 else 0 + + val digest1 = + if (iv == null) cipher.update(cipherText, 16, 48) else Array[Byte]() val clearText = cipher.doFinal(cipherText, n, cipherText.length - n) - - if(iv == null) { + + if (iv == null) { val digest2 = Hash.digest[Sha256](clearText).bytes var i = 0 var r = true - - - while(i < 32) { - if(digest1(i) != digest2(i)) r = false + + while (i < 32) { + if (digest1(i) != digest2(i)) r = false i += 1 } - if(!r) { + if (!r) { Arrays.fill(digest1, 0.toByte) Arrays.fill(digest2, 0.toByte) Arrays.fill(clearText, 0.toByte) mode.exception(DecryptionException()) } } - + clearText } def apply(clearText: Array[Byte]): Array[Byte] = encrypt(clearText) - + def unapply(cipherText: Array[Byte]): Option[Array[Byte]] = try Some(decrypt(cipherText)) catch { case DecryptionException() => None } } diff --git a/crypto/shared/src/main/scala/rapture/crypto/digest.scala b/crypto/shared/src/main/scala/rapture/crypto/digest.scala index 526cda1..1cd18fb 100644 --- a/crypto/shared/src/main/scala/rapture/crypto/digest.scala +++ b/crypto/shared/src/main/scala/rapture/crypto/digest.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.crypto import rapture.core._ @@ -38,29 +38,28 @@ package ciphers { implicit def desDecryption = Des.decryption implicit def desEncryption = Des.encryption } - + object blowfish { - implicit def blowfishGenerator: KeyGenerator[Blowfish] = Blowfish.keyGenerator + implicit def blowfishGenerator: KeyGenerator[Blowfish] = + Blowfish.keyGenerator implicit def blowfishDecryption = Blowfish.decryption implicit def blowfishEncryption = Blowfish.encryption } - + object aes { implicit def aesGenerator: KeyGenerator[Aes] = Aes.keyGenerator implicit def aesDecryption = Aes.decryption implicit def aesEncryption = Aes.encryption } - } class EncryptedData[C <: CipherType](bytes: Array[Byte]) extends Bytes(bytes) object Hash { - def digest[D <: DigestType: Digester](msg: Bytes): Digest[D] = + def digest[D <: DigestType : Digester](msg: Bytes): Digest[D] = new Digest[D](?[Digester[D]].digest(msg.bytes)) } - object Digester { implicit val sha1: Digester[Sha1] = digests.sha1 implicit val sha256: Digester[Sha256] = digests.sha256 @@ -70,6 +69,7 @@ object Digester { implicit val md2: Digester[Md2] = digests.md2 } abstract class Digester[D <: DigestType] { + /** Digests the array of bytes. */ def digest(msg: Array[Byte]): Array[Byte] } @@ -77,16 +77,19 @@ abstract class Digester[D <: DigestType] { case class Salt(value: String) object Password { - def apply(value: String)(implicit salt: Salt) = new HashedPassword(value)(salt) + def apply(value: String)(implicit salt: Salt) = + new HashedPassword(value)(salt) } class Password(private val value: String)(implicit salt: Salt) { - def digest: String = Bytes(Digester.sha256.digest((value + salt).getBytes("UTF-8"))).encode[Hex] + def digest: String = + Bytes(Digester.sha256.digest((value + salt).getBytes("UTF-8"))).encode[Hex] override def toString = s"password:$digest" def check(password: String) = new Password(password).digest == digest } -class HashedPassword(hash: String)(implicit salt: Salt) extends Password(null)(salt) { +class HashedPassword(hash: String)(implicit salt: Salt) + extends Password(null)(salt) { override def digest: String = hash } @@ -99,6 +102,7 @@ object digests { /** SHA-256 digester, with additional methods for secure password encoding. */ implicit val sha256: Digester[Sha256] = new Digester[Sha256] { + /** Digests the given bytes. */ def digest(msg: Array[Byte]): Array[Byte] = MessageDigest.getInstance("SHA-256").digest(msg) @@ -109,7 +113,7 @@ object digests { def digest(msg: Array[Byte]): Array[Byte] = MessageDigest.getInstance("SHA-512").digest(msg) } - + /** SHA-384 digester, with additional methods for secure password encoding. */ implicit val sha384: Digester[Sha384] = new Digester[Sha384] { def digest(msg: Array[Byte]): Array[Byte] = @@ -122,7 +126,7 @@ object digests { def digest(msg: Array[Byte]): Array[Byte] = MessageDigest.getInstance("MD5").digest(msg) } - + implicit val md2: Digester[Md2] = new Digester[Md2] { def digest(msg: Array[Byte]): Array[Byte] = MessageDigest.getInstance("MD2").digest(msg) @@ -133,22 +137,25 @@ trait CipherType trait Blowfish extends CipherType class JavaxCryptoImplementations[Codec <: CipherType](codec: String) { - implicit def encryption: Encryption[Codec, Bytes] = new Encryption[Codec, Bytes] { - def encrypt(key: Array[Byte], message: Bytes) = { - val cipher = javax.crypto.Cipher.getInstance(codec) - cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, new javax.crypto.spec.SecretKeySpec(key, codec)) - cipher.doFinal(message.bytes) + implicit def encryption: Encryption[Codec, Bytes] = + new Encryption[Codec, Bytes] { + def encrypt(key: Array[Byte], message: Bytes) = { + val cipher = javax.crypto.Cipher.getInstance(codec) + cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, + new javax.crypto.spec.SecretKeySpec(key, codec)) + cipher.doFinal(message.bytes) + } } - } - + implicit def decryption = new Decryption[Codec] { def decrypt(key: Array[Byte], message: Array[Byte]) = { val cipher = javax.crypto.Cipher.getInstance(codec) - cipher.init(javax.crypto.Cipher.DECRYPT_MODE, new javax.crypto.spec.SecretKeySpec(key, codec)) + cipher.init(javax.crypto.Cipher.DECRYPT_MODE, + new javax.crypto.spec.SecretKeySpec(key, codec)) cipher.doFinal(message) } } - + implicit def keyGenerator: KeyGenerator[Codec] = new KeyGenerator[Codec] { def generate(): Array[Byte] = { val keyGen = javax.crypto.KeyGenerator.getInstance(codec) @@ -157,7 +164,6 @@ class JavaxCryptoImplementations[Codec <: CipherType](codec: String) { } } - trait Aes extends CipherType object Aes extends JavaxCryptoImplementations[Aes]("AES") object Des extends JavaxCryptoImplementations[Des]("DES") @@ -182,7 +188,8 @@ trait Decryption[C <: CipherType] { } object Key { - def generate[K <: CipherType]()(implicit gen: KeyGenerator[K]): Key[gen.KeyType] = + def generate[K <: CipherType]()( + implicit gen: KeyGenerator[K]): Key[gen.KeyType] = new Key[gen.KeyType](?[KeyGenerator[K]].generate()) def read[K <: CipherType](key: Bytes): Key[K] = @@ -190,15 +197,18 @@ object Key { } class Key[C <: CipherType](bytes: Array[Byte]) extends Bytes(bytes) { - def encrypt[Msg](message: Msg)(implicit encryption: Encryption[C, Msg]): EncryptedData[C] = + def encrypt[Msg](message: Msg)( + implicit encryption: Encryption[C, Msg]): EncryptedData[C] = new EncryptedData[C](encryption.encrypt(bytes, message)) - def decrypt(message: EncryptedData[C]) - (implicit mode: Mode[`Key#decrypt`], decryption: Decryption[C]): mode.Wrap[Bytes, DecryptionException] = mode wrap { - try Bytes(decryption.decrypt(bytes, message.bytes)) catch { - case e: Exception => mode.exception(DecryptionException()) + def decrypt(message: EncryptedData[C])( + implicit mode: Mode[`Key#decrypt`], + decryption: Decryption[C]): mode.Wrap[Bytes, DecryptionException] = + mode wrap { + try Bytes(decryption.decrypt(bytes, message.bytes)) catch { + case e: Exception => mode.exception(DecryptionException()) + } } - } } case class HmacSigner(key: Bytes) { @@ -206,10 +216,10 @@ case class HmacSigner(key: Bytes) { implicit val hmac: Digester[Sha256Hmac] = new Digester[Sha256Hmac] { def digest(msg: Array[Byte]): Array[Byte] = { val mac = Mac.getInstance("HmacSHA256") - val secretKey = new javax.crypto.spec.SecretKeySpec(key.bytes, "HmacSHA256") + val secretKey = + new javax.crypto.spec.SecretKeySpec(key.bytes, "HmacSHA256") mac.init(secretKey) mac.doFinal(msg) } } - } diff --git a/css/shared/src/main/scala/rapture/css/context.scala b/css/shared/src/main/scala/rapture/css/context.scala index 05fcf01..aca84e7 100644 --- a/css/shared/src/main/scala/rapture/css/context.scala +++ b/css/shared/src/main/scala/rapture/css/context.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.css @@ -24,120 +24,133 @@ import rapture.data._ import language.experimental.macros private[css] object CssMacros { - - def parseSource(s: List[String], stringsUsed: List[Boolean], stylesheet: Boolean): Option[(Int, Int, String)] = try { - CssValidator.validate(s, stylesheet) - None - } catch { - case CssValidator.ValidationException(strNo, pos, msg) => - Some((strNo, pos, s"failed to parse Css literal: $msg")) - } + + def parseSource(s: List[String], + stringsUsed: List[Boolean], + stylesheet: Boolean): Option[(Int, Int, String)] = + try { + CssValidator.validate(s, stylesheet) + None + } catch { + case CssValidator.ValidationException(strNo, pos, msg) => + Some((strNo, pos, s"failed to parse Css literal: $msg")) + } // FIXME: Unify these two implementations - def stylesheetContextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[CssStylesheet]]*): c.Expr[CssStylesheet] = { + def stylesheetContextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[CssStylesheet]]* + ): c.Expr[CssStylesheet] = { import c.universe._ import compatibility._ c.prefix.tree match { case Select(Apply(_, List(Apply(_, rawParts))), _) => val ys = rawParts.to[List] - val text = rawParts map { case lit@Literal(Constant(part: String)) => part } + val text = + rawParts map { case lit @ Literal(Constant(part: String)) => part } - val listExprs = c.Expr[List[ForcedConversion[CssStylesheet]]](Apply( - Select(reify(List).tree, termName(c, "apply")), - exprs.map(_.tree).to[List] - )) + val listExprs = c.Expr[List[ForcedConversion[CssStylesheet]]](Apply( + Select(reify(List).tree, termName(c, "apply")), + exprs.map(_.tree).to[List] + )) val stringsUsed: List[Boolean] = listExprs.tree match { - case Apply(_, bs) => bs.map { - case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => nme.toString == "forceStringConversion" - } - } - - parseSource(text, stringsUsed, true) foreach { case (n, offset, msg) => - val oldPos = ys(n).asInstanceOf[Literal].pos - val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) - c.error(newPos, msg) - } - - val listParts = c.Expr[List[String]](Apply( - Select(reify(List).tree, termName(c, "apply")), - rawParts - )) - - reify { + case Apply(_, bs) => + bs.map { + case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => + nme.toString == "forceStringConversion" + } + } + + parseSource(text, stringsUsed, true) foreach { + case (n, offset, msg) => + val oldPos = ys(n).asInstanceOf[Literal].pos + val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) + c.error(newPos, msg) + } + + val listParts = c.Expr[List[String]](Apply( + Select(reify(List).tree, termName(c, "apply")), + rawParts + )) + + reify { val sb = new StringBuilder - val textParts = listParts.splice.iterator - val expressions: Iterator[ForcedConversion[_]] = listExprs.splice.iterator - - sb.append(textParts.next()) - - while(textParts.hasNext) { - sb.append(expressions.next.value) - sb.append(textParts.next) - } - CssStylesheet(sb.toString) - } + val textParts = listParts.splice.iterator + val expressions: Iterator[ForcedConversion[_]] = + listExprs.splice.iterator + + sb.append(textParts.next()) + + while (textParts.hasNext) { + sb.append(expressions.next.value) + sb.append(textParts.next) + } + CssStylesheet(sb.toString) + } } } - def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Css]]*): c.Expr[Css] = { + def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[Css]]*): c.Expr[Css] = { import c.universe._ import compatibility._ c.prefix.tree match { case Select(Apply(_, List(Apply(_, rawParts))), _) => val ys = rawParts.to[List] - val text = rawParts map { case lit@Literal(Constant(part: String)) => part } + val text = + rawParts map { case lit @ Literal(Constant(part: String)) => part } - val listExprs = c.Expr[List[ForcedConversion[Css]]](Apply( - Select(reify(List).tree, termName(c, "apply")), - exprs.map(_.tree).to[List] - )) + val listExprs = c.Expr[List[ForcedConversion[Css]]](Apply( + Select(reify(List).tree, termName(c, "apply")), + exprs.map(_.tree).to[List] + )) val stringsUsed: List[Boolean] = listExprs.tree match { - case Apply(_, bs) => bs.map { - case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => nme.toString == "forceStringConversion" - } - } - - parseSource(text, stringsUsed, false) foreach { case (n, offset, msg) => - val oldPos = ys(n).asInstanceOf[Literal].pos - val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) - c.error(newPos, msg) - } - - val listParts = c.Expr[List[String]](Apply( - Select(reify(List).tree, termName(c, "apply")), - rawParts - )) - - reify { + case Apply(_, bs) => + bs.map { + case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => + nme.toString == "forceStringConversion" + } + } + + parseSource(text, stringsUsed, false) foreach { + case (n, offset, msg) => + val oldPos = ys(n).asInstanceOf[Literal].pos + val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) + c.error(newPos, msg) + } + + val listParts = c.Expr[List[String]](Apply( + Select(reify(List).tree, termName(c, "apply")), + rawParts + )) + + reify { val sb = new StringBuilder - val textParts = listParts.splice.iterator - val expressions: Iterator[ForcedConversion[_]] = listExprs.splice.iterator - - sb.append(textParts.next()) - - while(textParts.hasNext) { - sb.append(expressions.next.value) - sb.append(textParts.next) - } - Css(sb.toString) - } + val textParts = listParts.splice.iterator + val expressions: Iterator[ForcedConversion[_]] = + listExprs.splice.iterator + + sb.append(textParts.next()) + + while (textParts.hasNext) { + sb.append(expressions.next.value) + sb.append(textParts.next) + } + Css(sb.toString) + } } } - } private[css] class CssStrings(sc: StringContext) { class CssContext() { - def apply(exprs: ForcedConversion[Css]*): Css = - macro CssMacros.contextMacro + def apply(exprs: ForcedConversion[Css]*): Css = macro CssMacros.contextMacro } class StylesheetContext() { - def apply(exprs: ForcedConversion[CssStylesheet]*): CssStylesheet = - macro CssMacros.stylesheetContextMacro + def apply(exprs: ForcedConversion[CssStylesheet]*): CssStylesheet = macro CssMacros.stylesheetContextMacro } val css = new CssContext() val cssStylesheet = new StylesheetContext() diff --git a/css/shared/src/main/scala/rapture/css/css.scala b/css/shared/src/main/scala/rapture/css/css.scala index 4329df6..ec3c397 100644 --- a/css/shared/src/main/scala/rapture/css/css.scala +++ b/css/shared/src/main/scala/rapture/css/css.scala @@ -13,14 +13,14 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.css case class Css(content: String) { - override def toString = s"""css${"\""*3}$content${"\""*3}""" + override def toString = s"""css${"\"" * 3}$content${"\"" * 3}""" } case class CssStylesheet(content: String) { - override def toString = s"""cssStylesheet${"\""*3}$content${"\""*3}""" + override def toString = s"""cssStylesheet${"\"" * 3}$content${"\"" * 3}""" } diff --git a/css/shared/src/main/scala/rapture/css/package.scala b/css/shared/src/main/scala/rapture/css/package.scala index 79038b0..7441fb8 100644 --- a/css/shared/src/main/scala/rapture/css/package.scala +++ b/css/shared/src/main/scala/rapture/css/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.css diff --git a/css/shared/src/main/scala/rapture/css/properties.scala b/css/shared/src/main/scala/rapture/css/properties.scala index f1a468a..3c75519 100644 --- a/css/shared/src/main/scala/rapture/css/properties.scala +++ b/css/shared/src/main/scala/rapture/css/properties.scala @@ -4,85 +4,327 @@ object Properties { // List of properties supported by Firefox val all = Set( - "align-content", "align-items", "align-self", "alignment-adjust", - "alignment-baseline", "anchor-point", "animation", "animation-delay", - "animation-direction", "animation-duration", "animation-fill-mode", - "animation-iteration-count", "animation-name", "animation-play-state", - "animation-timing-function", "appearance", "azimuth", "backface-visibility", - "background", "background-attachment", "background-blend-mode", "background-clip", - "background-color", "background-image", "background-origin", "background-position", - "background-repeat", "background-size", "baseline-shift", "binding", - "bleed", "bookmark-label", "bookmark-level", "bookmark-state", - "bookmark-target", "border", "border-bottom", "border-bottom-color", - "border-bottom-left-radius", "border-bottom-right-radius", - "border-bottom-style", "border-bottom-width", "border-collapse", - "border-color", "border-image", "border-image-outset", - "border-image-repeat", "border-image-slice", "border-image-source", - "border-image-width", "border-left", "border-left-color", - "border-left-style", "border-left-width", "border-radius", "border-right", - "border-right-color", "border-right-style", "border-right-width", - "border-spacing", "border-style", "border-top", "border-top-color", - "border-top-left-radius", "border-top-right-radius", "border-top-style", - "border-top-width", "border-width", "bottom", "box-decoration-break", - "box-shadow", "box-sizing", "break-after", "break-before", "break-inside", - "caption-side", "clear", "clip", "color", "color-profile", "column-count", - "column-fill", "column-gap", "column-rule", "column-rule-color", - "column-rule-style", "column-rule-width", "column-span", "column-width", - "columns", "content", "counter-increment", "counter-reset", "crop", "cue", - "cue-after", "cue-before", "cursor", "direction", "display", - "dominant-baseline", "drop-initial-after-adjust", - "drop-initial-after-align", "drop-initial-before-adjust", - "drop-initial-before-align", "drop-initial-size", "drop-initial-value", - "elevation", "empty-cells", "fit", "fit-position", "flex", "flex-basis", - "flex-direction", "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", - "float", "float-offset", "flow-from", "flow-into", "font", "font-feature-settings", - "font-family", "font-kerning", "font-language-override", "font-size", "font-size-adjust", - "font-stretch", "font-style", "font-synthesis", "font-variant", - "font-variant-alternates", "font-variant-caps", "font-variant-east-asian", - "font-variant-ligatures", "font-variant-numeric", "font-variant-position", - "font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow", - "grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end", - "grid-column-start", "grid-row", "grid-row-end", "grid-row-start", - "grid-template", "grid-template-areas", "grid-template-columns", - "grid-template-rows", "hanging-punctuation", "height", "hyphens", - "icon", "image-orientation", "image-rendering", "image-resolution", - "inline-box-align", "justify-content", "left", "letter-spacing", - "line-break", "line-height", "line-stacking", "line-stacking-ruby", - "line-stacking-shift", "line-stacking-strategy", "list-style", - "list-style-image", "list-style-position", "list-style-type", "margin", - "margin-bottom", "margin-left", "margin-right", "margin-top", - "marker-offset", "marks", "marquee-direction", "marquee-loop", - "marquee-play-count", "marquee-speed", "marquee-style", "max-height", - "max-width", "min-height", "min-width", "move-to", "nav-down", "nav-index", - "nav-left", "nav-right", "nav-up", "object-fit", "object-position", - "opacity", "order", "orphans", "outline", - "outline-color", "outline-offset", "outline-style", "outline-width", - "overflow", "overflow-style", "overflow-wrap", "overflow-x", "overflow-y", - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", - "page", "page-break-after", "page-break-before", "page-break-inside", - "page-policy", "pause", "pause-after", "pause-before", "perspective", - "perspective-origin", "pitch", "pitch-range", "play-during", "position", - "presentation-level", "punctuation-trim", "quotes", "region-break-after", - "region-break-before", "region-break-inside", "region-fragment", - "rendering-intent", "resize", "rest", "rest-after", "rest-before", "richness", - "right", "rotation", "rotation-point", "ruby-align", "ruby-overhang", - "ruby-position", "ruby-span", "shape-image-threshold", "shape-inside", "shape-margin", - "shape-outside", "size", "speak", "speak-as", "speak-header", - "speak-numeral", "speak-punctuation", "speech-rate", "stress", "string-set", - "tab-size", "table-layout", "target", "target-name", "target-new", - "target-position", "text-align", "text-align-last", "text-decoration", - "text-decoration-color", "text-decoration-line", "text-decoration-skip", - "text-decoration-style", "text-emphasis", "text-emphasis-color", - "text-emphasis-position", "text-emphasis-style", "text-height", - "text-indent", "text-justify", "text-outline", "text-overflow", "text-shadow", - "text-size-adjust", "text-space-collapse", "text-transform", "text-underline-position", - "text-wrap", "top", "transform", "transform-origin", "transform-style", - "transition", "transition-delay", "transition-duration", - "transition-property", "transition-timing-function", "unicode-bidi", - "vertical-align", "visibility", "voice-balance", "voice-duration", - "voice-family", "voice-pitch", "voice-range", "voice-rate", "voice-stress", - "voice-volume", "volume", "white-space", "widows", "width", "word-break", - "word-spacing", "word-wrap", "z-index" + "align-content", + "align-items", + "align-self", + "alignment-adjust", + "alignment-baseline", + "anchor-point", + "animation", + "animation-delay", + "animation-direction", + "animation-duration", + "animation-fill-mode", + "animation-iteration-count", + "animation-name", + "animation-play-state", + "animation-timing-function", + "appearance", + "azimuth", + "backface-visibility", + "background", + "background-attachment", + "background-blend-mode", + "background-clip", + "background-color", + "background-image", + "background-origin", + "background-position", + "background-repeat", + "background-size", + "baseline-shift", + "binding", + "bleed", + "bookmark-label", + "bookmark-level", + "bookmark-state", + "bookmark-target", + "border", + "border-bottom", + "border-bottom-color", + "border-bottom-left-radius", + "border-bottom-right-radius", + "border-bottom-style", + "border-bottom-width", + "border-collapse", + "border-color", + "border-image", + "border-image-outset", + "border-image-repeat", + "border-image-slice", + "border-image-source", + "border-image-width", + "border-left", + "border-left-color", + "border-left-style", + "border-left-width", + "border-radius", + "border-right", + "border-right-color", + "border-right-style", + "border-right-width", + "border-spacing", + "border-style", + "border-top", + "border-top-color", + "border-top-left-radius", + "border-top-right-radius", + "border-top-style", + "border-top-width", + "border-width", + "bottom", + "box-decoration-break", + "box-shadow", + "box-sizing", + "break-after", + "break-before", + "break-inside", + "caption-side", + "clear", + "clip", + "color", + "color-profile", + "column-count", + "column-fill", + "column-gap", + "column-rule", + "column-rule-color", + "column-rule-style", + "column-rule-width", + "column-span", + "column-width", + "columns", + "content", + "counter-increment", + "counter-reset", + "crop", + "cue", + "cue-after", + "cue-before", + "cursor", + "direction", + "display", + "dominant-baseline", + "drop-initial-after-adjust", + "drop-initial-after-align", + "drop-initial-before-adjust", + "drop-initial-before-align", + "drop-initial-size", + "drop-initial-value", + "elevation", + "empty-cells", + "fit", + "fit-position", + "flex", + "flex-basis", + "flex-direction", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-wrap", + "float", + "float-offset", + "flow-from", + "flow-into", + "font", + "font-feature-settings", + "font-family", + "font-kerning", + "font-language-override", + "font-size", + "font-size-adjust", + "font-stretch", + "font-style", + "font-synthesis", + "font-variant", + "font-variant-alternates", + "font-variant-caps", + "font-variant-east-asian", + "font-variant-ligatures", + "font-variant-numeric", + "font-variant-position", + "font-weight", + "grid", + "grid-area", + "grid-auto-columns", + "grid-auto-flow", + "grid-auto-position", + "grid-auto-rows", + "grid-column", + "grid-column-end", + "grid-column-start", + "grid-row", + "grid-row-end", + "grid-row-start", + "grid-template", + "grid-template-areas", + "grid-template-columns", + "grid-template-rows", + "hanging-punctuation", + "height", + "hyphens", + "icon", + "image-orientation", + "image-rendering", + "image-resolution", + "inline-box-align", + "justify-content", + "left", + "letter-spacing", + "line-break", + "line-height", + "line-stacking", + "line-stacking-ruby", + "line-stacking-shift", + "line-stacking-strategy", + "list-style", + "list-style-image", + "list-style-position", + "list-style-type", + "margin", + "margin-bottom", + "margin-left", + "margin-right", + "margin-top", + "marker-offset", + "marks", + "marquee-direction", + "marquee-loop", + "marquee-play-count", + "marquee-speed", + "marquee-style", + "max-height", + "max-width", + "min-height", + "min-width", + "move-to", + "nav-down", + "nav-index", + "nav-left", + "nav-right", + "nav-up", + "object-fit", + "object-position", + "opacity", + "order", + "orphans", + "outline", + "outline-color", + "outline-offset", + "outline-style", + "outline-width", + "overflow", + "overflow-style", + "overflow-wrap", + "overflow-x", + "overflow-y", + "padding", + "padding-bottom", + "padding-left", + "padding-right", + "padding-top", + "page", + "page-break-after", + "page-break-before", + "page-break-inside", + "page-policy", + "pause", + "pause-after", + "pause-before", + "perspective", + "perspective-origin", + "pitch", + "pitch-range", + "play-during", + "position", + "presentation-level", + "punctuation-trim", + "quotes", + "region-break-after", + "region-break-before", + "region-break-inside", + "region-fragment", + "rendering-intent", + "resize", + "rest", + "rest-after", + "rest-before", + "richness", + "right", + "rotation", + "rotation-point", + "ruby-align", + "ruby-overhang", + "ruby-position", + "ruby-span", + "shape-image-threshold", + "shape-inside", + "shape-margin", + "shape-outside", + "size", + "speak", + "speak-as", + "speak-header", + "speak-numeral", + "speak-punctuation", + "speech-rate", + "stress", + "string-set", + "tab-size", + "table-layout", + "target", + "target-name", + "target-new", + "target-position", + "text-align", + "text-align-last", + "text-decoration", + "text-decoration-color", + "text-decoration-line", + "text-decoration-skip", + "text-decoration-style", + "text-emphasis", + "text-emphasis-color", + "text-emphasis-position", + "text-emphasis-style", + "text-height", + "text-indent", + "text-justify", + "text-outline", + "text-overflow", + "text-shadow", + "text-size-adjust", + "text-space-collapse", + "text-transform", + "text-underline-position", + "text-wrap", + "top", + "transform", + "transform-origin", + "transform-style", + "transition", + "transition-delay", + "transition-duration", + "transition-property", + "transition-timing-function", + "unicode-bidi", + "vertical-align", + "visibility", + "voice-balance", + "voice-duration", + "voice-family", + "voice-pitch", + "voice-range", + "voice-rate", + "voice-stress", + "voice-volume", + "volume", + "white-space", + "widows", + "width", + "word-break", + "word-spacing", + "word-wrap", + "z-index" ) - } diff --git a/css/shared/src/main/scala/rapture/css/validator.scala b/css/shared/src/main/scala/rapture/css/validator.scala index 861bd07..436f0f6 100644 --- a/css/shared/src/main/scala/rapture/css/validator.scala +++ b/css/shared/src/main/scala/rapture/css/validator.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.css @@ -27,22 +27,25 @@ private[css] object CssValidator { case class ValidationException(strNo: Int, pos: Int, msg: String) extends Exception - + def validate(parts: List[String], stylesheet: Boolean): Unit = { val errHandler = new ErrorHandler { - def error(e: CSSParseException) = throw ValidationException(0, e.getColumnNumber - 1, e.getMessage) + def error(e: CSSParseException) = + throw ValidationException(0, e.getColumnNumber - 1, e.getMessage) def fatalError(e: CSSParseException) = error(e) def warning(e: CSSParseException) = error(e) } val source = new InputSource(new StringReader(parts.mkString("null"))) val parser = new CSSOMParser(new SACParserCSS3()) parser.setErrorHandler(errHandler) - - if(stylesheet) { + + if (stylesheet) { parser.parseStyleSheet(source, null, null) } else { val ss = parser.parseStyleDeclaration(source) - for(i <- 0 until ss.getLength) if(!Properties.all.contains(ss.item(i))) throw ValidationException(0, 0, s"invalid CSS attribute '${ss.item(i)}'") + for (i <- 0 until ss.getLength) if (!Properties.all.contains(ss.item(i))) + throw ValidationException( + 0, 0, s"invalid CSS attribute '${ss.item(i)}'") } } } diff --git a/csv/shared/src/main/scala/rapture/csv/csv.scala b/csv/shared/src/main/scala/rapture/csv/csv.scala index 017c03a..66b6b13 100644 --- a/csv/shared/src/main/scala/rapture/csv/csv.scala +++ b/csv/shared/src/main/scala/rapture/csv/csv.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.csv @@ -44,8 +44,10 @@ sealed trait CsvGetException extends RuntimeException case class CsvMissingValue(col: Int) extends CsvGetException { override def getMessage = s"missing value: Column $col does not exist" } -case class CsvTypeMismatch(typeName: String, col: Int) extends CsvGetException { - override def getMessage = s"type mismatch: Could not read value of type $typeName in column $col" +case class CsvTypeMismatch(typeName: String, col: Int) + extends CsvGetException { + override def getMessage = + s"type mismatch: Could not read value of type $typeName in column $col" } trait `Csv.parse` extends MethodConstraint @@ -59,61 +61,89 @@ class KeyedCsvRow(val csvRow: CsvRow, val keys: Map[String, Int]) { class CsvRow(val elems: Seq[String]) { def apply(idx: Int): CsvCell = CsvCell(elems(idx), idx) - def as[T](implicit mode: Mode[`CsvRow#as`], extractor: CsvRowExtractor[T]): mode.Wrap[T, CsvGetException] = + def as[T](implicit mode: Mode[`CsvRow#as`], + extractor: CsvRowExtractor[T]): mode.Wrap[T, CsvGetException] = extractor.extract(elems, mode) - + override def toString = elems.mkString("\"", "\",\"", "\"") } object CsvRowExtractor { - implicit def generateExtractor[T]: CsvRowExtractor[T] = macro Macros.extractorMacro[T] + implicit def generateExtractor[T]: CsvRowExtractor[T] = macro Macros + .extractorMacro[T] } trait CsvRowExtractor[T] { - def extract(values: Seq[String], mode: Mode[_]): mode.Wrap[T, CsvGetException] + def extract( + values: Seq[String], mode: Mode[_]): mode.Wrap[T, CsvGetException] } -case class BadLength(len: Int) extends Exception("Bad length: "+len) +case class BadLength(len: Int) extends Exception("Bad length: " + len) object CsvCellExtractor { implicit val stringExtractor: CsvCellExtractor[String] = new CsvCellExtractor[String] { type ExceptionType = CsvGetException - def extract(value: String, c: Int, mode: Mode[_]): mode.Wrap[String, CsvGetException] = + def extract(value: String, + c: Int, + mode: Mode[_]): mode.Wrap[String, CsvGetException] = mode.wrap(value) } - - implicit val intExtractor: CsvCellExtractor[Int] = new CsvCellExtractor[Int] { - type ExceptionType = CsvGetException - def extract(value: String, c: Int, mode: Mode[_]): mode.Wrap[Int, CsvGetException] = - mode.wrap { try value.toInt catch { case e: Exception => mode.exception(CsvTypeMismatch("integer", c)) } } - } - - implicit val doubleExtractor: CsvCellExtractor[Double] = new CsvCellExtractor[Double] { - type ExceptionType = CsvGetException - def extract(value: String, c: Int, mode: Mode[_]): mode.Wrap[Double, CsvGetException] = - mode.wrap { try value.toDouble catch { case e: Exception => mode.exception(CsvTypeMismatch("double", c)) } } - } - - implicit val charExtractor: CsvCellExtractor[Char] = new CsvCellExtractor[Char] { - type ExceptionType = BadLength - def extract(value: String, c: Int, mode: Mode[_]): mode.Wrap[Char, CsvGetException with BadLength] = mode.wrap { - if(value.length == 1) value.head else { - mode.exception(CsvTypeMismatch("character", c)) - '\u0000' - } + + implicit val intExtractor: CsvCellExtractor[Int] = + new CsvCellExtractor[Int] { + type ExceptionType = CsvGetException + def extract(value: String, + c: Int, + mode: Mode[_]): mode.Wrap[Int, CsvGetException] = + mode.wrap { + try value.toInt catch { + case e: Exception => mode.exception(CsvTypeMismatch("integer", c)) + } + } + } + + implicit val doubleExtractor: CsvCellExtractor[Double] = + new CsvCellExtractor[Double] { + type ExceptionType = CsvGetException + def extract(value: String, + c: Int, + mode: Mode[_]): mode.Wrap[Double, CsvGetException] = + mode.wrap { + try value.toDouble catch { + case e: Exception => mode.exception(CsvTypeMismatch("double", c)) + } + } + } + + implicit val charExtractor: CsvCellExtractor[Char] = + new CsvCellExtractor[Char] { + type ExceptionType = BadLength + def extract( + value: String, + c: Int, + mode: Mode[_]): mode.Wrap[Char, CsvGetException with BadLength] = + mode.wrap { + if (value.length == 1) value.head + else { + mode.exception(CsvTypeMismatch("character", c)) + '\u0000' + } + } } - } } trait CsvCellExtractor[T] { type ExceptionType <: Exception - def extract(value: String, c: Int, mode: Mode[_]): mode.Wrap[T, CsvGetException with ExceptionType] + def extract(value: String, + c: Int, + mode: Mode[_]): mode.Wrap[T, CsvGetException with ExceptionType] } case class CsvCell(value: String, col: Int) { - def as[T](mode: Mode[`CsvCell#as`])(ext: CsvCellExtractor[T]): mode.Wrap[T, CsvGetException with ext.ExceptionType] = + def as[T](mode: Mode[`CsvCell#as`])(ext: CsvCellExtractor[T] + ): mode.Wrap[T, CsvGetException with ext.ExceptionType] = ext.extract(value, col, mode) - + override def toString = value } @@ -121,61 +151,81 @@ case class Csv(rows: Vector[CsvRow]) extends Seq[CsvRow] { def iterator = rows.iterator def apply(idx: Int) = rows(idx) def length = rows.length - - override def toString = rows.take(4).mkString("\n")+(if(rows.length > 4) "\n..." else "") - def mapAs[T: CsvRowExtractor](implicit mode: Mode[`Csv#mapAs`]): mode.Wrap[Seq[T], CsvGetException] = mode.wrap { - rows.map { row => mode.unwrap(?[CsvRowExtractor[T]].extract(row.elems, mode)) } - } + override def toString = + rows.take(4).mkString("\n") + (if (rows.length > 4) "\n..." else "") + + def mapAs[T : CsvRowExtractor]( + implicit mode: Mode[`Csv#mapAs`]): mode.Wrap[Seq[T], CsvGetException] = + mode.wrap { + rows.map { row => + mode.unwrap(?[CsvRowExtractor[T]].extract(row.elems, mode)) + } + } } object Csv { - def parse[Res](resource: Res)(implicit mode: Mode[`Csv.parse`], reader: Reader[Res, String], + def parse[Res](resource: Res)( + implicit mode: Mode[`Csv.parse`], + reader: Reader[Res, String], backend: CsvBackend): mode.Wrap[Csv, CsvParseException] = mode.wrap { - Csv(reader.input(resource).to[Vector].zipWithIndex.map { case (ln, idx) => - new CsvRow(mode.unwrap(backend.parseRow(ln, idx, mode))) - }) + Csv( + reader + .input(resource) + .to[Vector] + .zipWithIndex + .map { + case (ln, idx) => + new CsvRow(mode.unwrap(backend.parseRow(ln, idx, mode))) + }) } - def extractor[T: CsvCellExtractor] = ?[CsvCellExtractor[T]] + def extractor[T : CsvCellExtractor] = ?[CsvCellExtractor[T]] } -trait CsvBackend { def parseRow(s: String, line: Int, mode: Mode[_]): mode.Wrap[Seq[String], CsvParseException] } +trait CsvBackend { + def parseRow(s: String, + line: Int, + mode: Mode[_]): mode.Wrap[Seq[String], CsvParseException] +} object csvBackends { object simple { implicit val simpleBackend: CsvBackend = new CsvBackend { - def parseRow(s: String, line: Int, mode: Mode[_]): mode.Wrap[Seq[String], CsvParseException] = mode.wrap { - var cells: Vector[String] = Vector() - var cur = 0 - var quoted = false - var expectingQuote = false - var sb = new StringBuilder - while(cur < s.length) { - s(cur) match { - case '"' => - if(sb.isEmpty && !quoted) { - quoted = true - } else if(quoted) { - quoted = false - } else if(expectingQuote) { - sb.append('"') - expectingQuote = false - } else expectingQuote = true - cur += 1 - case _ if expectingQuote => - mode.exception(CsvParseException(line, cells.length)) - case ',' if !quoted => - cells = cells :+ sb.toString.trim - sb = new StringBuilder - cur += 1 - case other => - sb.append(other) - cur += 1 + def parseRow(s: String, + line: Int, + mode: Mode[_]): mode.Wrap[Seq[String], CsvParseException] = + mode.wrap { + var cells: Vector[String] = Vector() + var cur = 0 + var quoted = false + var expectingQuote = false + var sb = new StringBuilder + while (cur < s.length) { + s(cur) match { + case '"' => + if (sb.isEmpty && !quoted) { + quoted = true + } else if (quoted) { + quoted = false + } else if (expectingQuote) { + sb.append('"') + expectingQuote = false + } else expectingQuote = true + cur += 1 + case _ if expectingQuote => + mode.exception(CsvParseException(line, cells.length)) + case ',' if !quoted => + cells = cells :+ sb.toString.trim + sb = new StringBuilder + cur += 1 + case other => + sb.append(other) + cur += 1 + } } + cells :+ sb.toString.trim } - cells :+ sb.toString.trim - } } } } diff --git a/csv/shared/src/main/scala/rapture/csv/macros.scala b/csv/shared/src/main/scala/rapture/csv/macros.scala index b15852a..5f411d9 100644 --- a/csv/shared/src/main/scala/rapture/csv/macros.scala +++ b/csv/shared/src/main/scala/rapture/csv/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.csv @@ -22,63 +22,68 @@ import rapture.base._ object Macros { - def extractorMacro[T: c.WeakTypeTag](c: BlackboxContext): c.Expr[CsvRowExtractor[T]] = { + def extractorMacro[T : c.WeakTypeTag]( + c: BlackboxContext): c.Expr[CsvRowExtractor[T]] = { import c.universe._ import compatibility._ - val cellExtractor = typeOf[CsvCellExtractor[_]].typeSymbol.asType.toTypeConstructor + val cellExtractor = + typeOf[CsvCellExtractor[_]].typeSymbol.asType.toTypeConstructor require(weakTypeOf[T].typeSymbol.asClass.isCaseClass) val params = declarations(c)(weakTypeOf[T]).collect { case m: MethodSymbol if m.isCaseAccessor => m.asMethod - }.zipWithIndex.map { case (p, i) => - - Apply( - Select( - Ident(termName(c, "mode")), - termName(c, "unwrap") - ), - List( - Apply( + }.zipWithIndex.map { + case (p, i) => + Apply( Select( - c.inferImplicitValue(appliedType(cellExtractor, List(p.returnType)), false, false), - termName(c, "extract") + Ident(termName(c, "mode")), + termName(c, "unwrap") ), List( - Apply( - Select( - Ident(termName(c, "values")), - termName(c, "apply") - ), - List(Literal(Constant(i))) - ), - Literal(Constant(i)), - Ident(termName(c, "mode")) + Apply( + Select( + c.inferImplicitValue(appliedType(cellExtractor, + List(p.returnType)), + false, + false), + termName(c, "extract") + ), + List( + Apply( + Select( + Ident(termName(c, "values")), + termName(c, "apply") + ), + List(Literal(Constant(i))) + ), + Literal(Constant(i)), + Ident(termName(c, "mode")) + ) + ) ) - ) ) - ) } - + val construction = c.Expr[T]( - Apply( - Select( - New( - TypeTree(weakTypeOf[T]) - ), - constructor(c) - ), - params.to[List] - ) + Apply( + Select( + New( + TypeTree(weakTypeOf[T]) + ), + constructor(c) + ), + params.to[List] + ) ) reify { new CsvRowExtractor[T] { - def extract(values: Seq[String], mode: Mode[_]): mode.Wrap[T, CsvGetException] = + def extract(values: Seq[String], + mode: Mode[_]): mode.Wrap[T, CsvGetException] = mode.wrap(construction.splice) } } } } - diff --git a/data/shared/src/main/scala/rapture/data/ast.scala b/data/shared/src/main/scala/rapture/data/ast.scala index 3875a6d..dff43e5 100644 --- a/data/shared/src/main/scala/rapture/data/ast.scala +++ b/data/shared/src/main/scala/rapture/data/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data @@ -32,32 +32,33 @@ object DataTypes { case object Any extends DataType("any") } -@implicitNotFound(msg = "Cannot find ${Ast} parser for values of type ${Source}") +@implicitNotFound( + msg = "Cannot find ${Ast} parser for values of type ${Source}") trait Parser[-Source, +Ast <: DataAst] { val ast: Ast def parse(s: Source): Option[Any] } trait DataAst { - + /** Dereferences the named element within the JSON object. */ def dereferenceObject(obj: Any, element: String): Any = getObject(obj)(element) - + /** Returns at `Iterator[String]` over the names of the elements in the JSON object. */ def getKeys(obj: Any): Iterator[String] = getObject(obj).keys.iterator - + /** Gets the indexed element from the parsed JSON array. */ def dereferenceArray(array: Any, element: Int): Any = getArray(array)(element) - + /** Tests if the element represents an `Object` */ def isObject(any: Any): Boolean - + /** Tests if the element represents an `Array` */ def isArray(any: Any): Boolean - + def isNull(any: Any): Boolean /** Extracts a JSON object as a `Map[String, Any]` from the parsed JSON. */ @@ -76,7 +77,7 @@ trait DataAst { def fromArray(array: Seq[Any]): Any def isScalar(any: Any): Boolean - + def getString(any: Any): Any def isString(any: Any): Boolean @@ -89,4 +90,3 @@ trait MutableDataAst extends DataAst { def removeObjectValue(obj: Any, name: String): Any def addArrayValue(array: Any, value: Any): Any } - diff --git a/data/shared/src/main/scala/rapture/data/context.scala b/data/shared/src/main/scala/rapture/data/context.scala index 6d275cb..6581643 100644 --- a/data/shared/src/main/scala/rapture/data/context.scala +++ b/data/shared/src/main/scala/rapture/data/context.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data @@ -22,172 +22,206 @@ import rapture.core._ object patternMatching { object exactArrays { - implicit val implicitArrayMachingConfig = - new ArrayMatchingConfig { def checkLengths = true } + implicit val implicitArrayMachingConfig = new ArrayMatchingConfig { + def checkLengths = true + } } object exactObjects { - implicit val implicitArrayMachingConfig = - new ObjectMatchingConfig { def checkSizes = true } + implicit val implicitArrayMachingConfig = new ObjectMatchingConfig { + def checkSizes = true + } } object exact { - implicit val implicitArrayMachingConfig = - new ObjectMatchingConfig with ArrayMatchingConfig { - def checkSizes = true - def checkLengths = true - } + implicit val implicitArrayMachingConfig = new ObjectMatchingConfig + with ArrayMatchingConfig { + def checkSizes = true + def checkLengths = true + } } } object ArrayMatchingConfig { - implicit val ignoreByDefault = new ArrayMatchingConfig { def checkLengths = false } + implicit val ignoreByDefault = new ArrayMatchingConfig { + def checkLengths = false + } } object ObjectMatchingConfig { - implicit val ignoreByDefault = new ObjectMatchingConfig { def checkSizes = false } + implicit val ignoreByDefault = new ObjectMatchingConfig { + def checkSizes = false + } } trait ArrayMatchingConfig { def checkLengths: Boolean } trait ObjectMatchingConfig { def checkSizes: Boolean } -abstract class DataContextMacros[+Data <: DataType[Data, DataAst], -AstType <: DataAst] { +abstract class DataContextMacros[ + +Data <: DataType[Data, DataAst], -AstType <: DataAst] { - def parseSource(s: List[String], stringsUsed: List[Boolean]): Option[(Int, Int, String)] + def parseSource( + s: List[String], stringsUsed: List[Boolean]): Option[(Int, Int, String)] def companion(c: BlackboxContext): c.Expr[DataCompanion[Data, AstType]] - def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Data]]*) - (parser: c.Expr[Parser[String, AstType]]): c.Expr[Data] = { + def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Data]]*)( + parser: c.Expr[Parser[String, AstType]]): c.Expr[Data] = { import c.universe._ import compatibility._ c.prefix.tree match { case Select(Apply(Apply(_, List(Apply(_, rawParts))), _), _) => val ys = rawParts.to[List] - val text = rawParts map { case lit@Literal(Constant(part: String)) => part } - + val text = + rawParts map { case lit @ Literal(Constant(part: String)) => part } + val listExprs = c.Expr[List[ForcedConversion[Data]]](Apply( - Select(reify(List).tree, termName(c, "apply")), - exprs.map(_.tree).to[List] - )) - + Select(reify(List).tree, termName(c, "apply")), + exprs.map(_.tree).to[List] + )) + val stringsUsed: List[Boolean] = (listExprs.tree match { - case Apply(_, bs) => bs.map { - case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => nme.toString == "forceStringConversion" - } + case Apply(_, bs) => + bs.map { + case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => + nme.toString == "forceStringConversion" + } }) - parseSource(text, stringsUsed) foreach { case (n, offset, msg) => - val oldPos = ys(n).asInstanceOf[Literal].pos - - val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) - c.error(newPos, msg) + parseSource(text, stringsUsed) foreach { + case (n, offset, msg) => + val oldPos = ys(n).asInstanceOf[Literal].pos + + val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) + c.error(newPos, msg) } - + val listParts = c.Expr[List[String]](Apply( - Select(reify(List).tree, termName(c, "apply")), - rawParts - )) - + Select(reify(List).tree, termName(c, "apply")), + rawParts + )) + val comp = companion(c) - + reify { val sb = new StringBuilder val textParts = listParts.splice.iterator - val expressions: Iterator[ForcedConversion[_]] = listExprs.splice.iterator - + val expressions: Iterator[ForcedConversion[_]] = + listExprs.splice.iterator + sb.append(textParts.next()) - - while(textParts.hasNext) { - sb.append(comp.splice.construct(MutableCell(expressions.next.value), - Vector())(parser.splice.ast).toString) + + while (textParts.hasNext) { + sb.append(comp.splice + .construct(MutableCell(expressions.next.value), Vector())( + parser.splice.ast) + .toString) sb.append(textParts.next) } - - comp.splice.construct(MutableCell(parser.splice.parse(sb.toString).get), Vector())( - parser.splice.ast) + + comp.splice.construct( + MutableCell(parser.splice.parse(sb.toString).get), + Vector())(parser.splice.ast) } } } } -class DataContext[+Data <: DataType[Data, DataAst], -AstType <: DataAst] - (companion: DataCompanion[Data, AstType], sc: StringContext) { +class DataContext[+Data <: DataType[Data, DataAst], -AstType <: DataAst]( + companion: DataCompanion[Data, AstType], sc: StringContext) { protected def uniqueNonSubstring(s: String) = { var cur, m = 0 s foreach { c => - cur = if(c == '_') cur + 1 else 0 + cur = if (c == '_') cur + 1 else 0 m = m max cur } - "_"*(m + 1) + "_" * (m + 1) } - def unapplySeq[D <: DataType[D, DataAst]](data: D) - (implicit arrayMatching: ArrayMatchingConfig, objectMatching: ObjectMatchingConfig, - parser: Parser[String, AstType]): Option[Seq[DataType[D, DataAst]]] = try { - val placeholder = uniqueNonSubstring(sc.parts.mkString) - val PlaceholderNumber = (placeholder+"([0-9]+)"+placeholder).r - val count = Iterator.from(0) - val txt = sc.parts.reduceLeft(_ + s""""${placeholder}${count.next()}${placeholder}" """ + _) - - val paths: Array[Vector[Either[Int, String]]] = - Array.fill[Vector[Either[Int, String]]](sc.parts.length - 1)(Vector()) - - val arrayLengths = new collection.mutable.HashMap[Vector[Either[Int, String]], Int] - val objectSizes = new collection.mutable.HashMap[Vector[Either[Int, String]], Int] - - def extract(any: Any, path: Vector[Either[Int, String]]): Unit = { - // FIXME: Avoid using isScalar if possible - if(parser.ast.isScalar(any)) { - val ext = data.$extract(path).as[Any] - if(data.$extract(path).as[Any] != any) throw new Exception("Value doesn't match (1)") - } else if(parser.ast.isObject(any)) { - val obj = parser.ast.getObject(any) - objectSizes(path) = obj.size - obj foreach { case (k, v) => - if(parser.ast.isString(v)) parser.ast.getString(v) match { - case str: CharSequence => str match { - case PlaceholderNumber(n) => - paths(n.toInt) = path :+ Right(k) - case _ => extract(v, path :+ Right(k)) - } - } else extract(v, path :+ Right(k)) - } - } else if(parser.ast.isArray(any)) { - val array = parser.ast.getArray(any) - if(arrayMatching.checkLengths) arrayLengths(path) = array.length - array.zipWithIndex foreach { case (e, i) => - if(parser.ast.isString(e)) parser.ast.getString(e) match { - case str: CharSequence => str match { - case PlaceholderNumber(n) => - paths(n.toInt) = path :+ Left(i) - case _ => extract(e, path :+ Left(i)) - } - } else extract(e, path :+ Left(i)) - } - } else throw new Exception("Value doesn't match (2)") - } + def unapplySeq[D <: DataType[D, DataAst]](data: D)( + implicit arrayMatching: ArrayMatchingConfig, + objectMatching: ObjectMatchingConfig, + parser: Parser[String, AstType]): Option[Seq[DataType[D, DataAst]]] = + try { + val placeholder = uniqueNonSubstring(sc.parts.mkString) + val PlaceholderNumber = (placeholder + "([0-9]+)" + placeholder).r + val count = Iterator.from(0) + val txt = sc.parts.reduceLeft( + _ + s""""${placeholder}${count.next()}${placeholder}" """ + _) + + val paths: Array[Vector[Either[Int, String]]] = + Array.fill[Vector[Either[Int, String]]](sc.parts.length - 1)(Vector()) + + val arrayLengths = + new collection.mutable.HashMap[Vector[Either[Int, String]], Int] + val objectSizes = + new collection.mutable.HashMap[Vector[Either[Int, String]], Int] + + def extract(any: Any, path: Vector[Either[Int, String]]): Unit = { + // FIXME: Avoid using isScalar if possible + if (parser.ast.isScalar(any)) { + val ext = data.$extract(path).as[Any] + if (data.$extract(path).as[Any] != any) + throw new Exception("Value doesn't match (1)") + } else if (parser.ast.isObject(any)) { + val obj = parser.ast.getObject(any) + objectSizes(path) = obj.size + obj foreach { + case (k, v) => + if (parser.ast.isString(v)) + parser.ast.getString(v) match { + case str: CharSequence => + str match { + case PlaceholderNumber(n) => + paths(n.toInt) = path :+ Right(k) + case _ => extract(v, path :+ Right(k)) + } + } else extract(v, path :+ Right(k)) + } + } else if (parser.ast.isArray(any)) { + val array = parser.ast.getArray(any) + if (arrayMatching.checkLengths) arrayLengths(path) = array.length + array.zipWithIndex foreach { + case (e, i) => + if (parser.ast.isString(e)) + parser.ast.getString(e) match { + case str: CharSequence => + str match { + case PlaceholderNumber(n) => + paths(n.toInt) = path :+ Left(i) + case _ => extract(e, path :+ Left(i)) + } + } else extract(e, path :+ Left(i)) + } + } else throw new Exception("Value doesn't match (2)") + } - extract(parser.parse(txt).get, Vector()) + extract(parser.parse(txt).get, Vector()) - // Using a ListBuffer to work around SI-8947 - val extractsBuffer = new collection.mutable.ListBuffer[D] - paths foreach { p => extractsBuffer += data.$extract(p) } - val extracts = extractsBuffer.toList - extracts.foreach(_.$normalize) - val matchedArrayLengths = arrayLengths.forall { case (p, len) => - parser.ast.getArray(data.$extract(p).$normalize).length == len - } - - val matchedObjectSizes = objectSizes.forall { case (p, s) => - if(objectMatching.checkSizes) parser.ast.getObject(data.$extract(p).$normalize).size == s - else parser.ast.getObject(data.$extract(p).$normalize).size >= 0 - } + // Using a ListBuffer to work around SI-8947 + val extractsBuffer = new collection.mutable.ListBuffer[D] + paths foreach { p => + extractsBuffer += data.$extract(p) + } + val extracts = extractsBuffer.toList + extracts.foreach(_.$normalize) + val matchedArrayLengths = arrayLengths.forall { + case (p, len) => + parser.ast.getArray(data.$extract(p).$normalize).length == len + } - if(extracts.exists(_.$root.value == null) || !matchedArrayLengths || !matchedObjectSizes) - None else Some(extracts) - } catch { case e: Exception => - None - } + val matchedObjectSizes = objectSizes.forall { + case (p, s) => + if (objectMatching.checkSizes) + parser.ast.getObject(data.$extract(p).$normalize).size == s + else parser.ast.getObject(data.$extract(p).$normalize).size >= 0 + } + + if (extracts.exists(_.$root.value == null) || !matchedArrayLengths || + !matchedObjectSizes) None else Some(extracts) + } catch { + case e: Exception => + None + } } diff --git a/data/shared/src/main/scala/rapture/data/data.scala b/data/shared/src/main/scala/rapture/data/data.scala index f77b2d4..3001e87 100644 --- a/data/shared/src/main/scala/rapture/data/data.scala +++ b/data/shared/src/main/scala/rapture/data/data.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data @@ -38,14 +38,18 @@ trait DataCompanion[+Type <: DataType[Type, DataAst], -AstType <: DataAst] { def empty(implicit ast: AstType) = construct(MutableCell(ast.fromObject(Map())), Vector()) - def construct(any: MutableCell, path: Vector[Either[Int, String]])(implicit ast: AstType): Type - - def parse[Source: StringSerializer](s: Source)(implicit mode: Mode[ParseMethodConstraint], - parser: Parser[Source, AstType]): mode.Wrap[Type, ParseException] = mode wrap { - construct(try MutableCell(parser.parse(s).get) catch { - case e: NoSuchElementException => mode.exception(ParseException(String(s))) - }, Vector())(parser.ast) - } + def construct(any: MutableCell, path: Vector[Either[Int, String]])( + implicit ast: AstType): Type + + def parse[Source : StringSerializer](s: Source)( + implicit mode: Mode[ParseMethodConstraint], + parser: Parser[Source, AstType]): mode.Wrap[Type, ParseException] = + mode wrap { + construct(try MutableCell(parser.parse(s).get) catch { + case e: NoSuchElementException => + mode.exception(ParseException(String(s))) + }, Vector())(parser.ast) + } def apply[T](t: T)(implicit ast: AstType, ser: Serializer[T, Type]): Type = construct(MutableCell(ser.serialize(t)), Vector()) @@ -53,87 +57,112 @@ trait DataCompanion[+Type <: DataType[Type, DataAst], -AstType <: DataAst] { def raw(value: Any)(implicit ast: AstType): Type = construct(MutableCell(value), Vector()) - def format[T <: DataType[T, AstType]](data: T)(implicit f: Formatter[_ <: AstType]): f.Out = + def format[T <: DataType[T, AstType]](data: T)( + implicit f: Formatter[_ <: AstType]): f.Out = f.format(data.$normalize) - } -case class DynamicApplication[D](path: List[Either[Int, String]], application: ForcedConversion2[D]) +case class DynamicApplication[D]( + path: List[Either[Int, String]], application: ForcedConversion2[D]) case class DynamicPath[D](path: List[Either[Int, String]]) extends Dynamic { def selectDynamic(v: String) = DynamicPath[D](Right(v) :: path) - def applyDynamic(v: String)(i: Int) = DynamicPath[D](Left(i) :: Right(v) :: path) + def applyDynamic(v: String)(i: Int) = + DynamicPath[D](Left(i) :: Right(v) :: path) def apply(i: Int) = DynamicPath[D](Left(i) :: path) def updateDynamic(p: String)(value: ForcedConversion2[D]) = DynamicApplication(Right(p) :: path, value) - + def update(i: Int, value: ForcedConversion2[D]) = DynamicApplication(Left(i) :: path, value) } case class MutableCell(var value: Any) -trait DynamicData[+T <: DynamicData[T, AstType], +AstType <: DataAst] extends Dynamic { +trait DynamicData[+T <: DynamicData[T, AstType], +AstType <: DataAst] + extends Dynamic { /** Assumes the Json object wraps a `Map`, and extracts the element `key`. */ def selectDynamic(key: String): T = $deref(Right(key) +: $path) - def applyDynamic(key: String)(i: Int = 0): T = $deref(Left(i) +: Right(key) +: $path) + def applyDynamic(key: String)(i: Int = 0): T = + $deref(Left(i) +: Right(key) +: $path) def $deref($path: Vector[Either[Int, String]]): T def $path: Vector[Either[Int, String]] - } object DataType { - class DataClassOperations[T <: DataType[T, AstType], AstType <: DataAst](dataType: T) { + class DataClassOperations[T <: DataType[T, AstType], AstType <: DataAst]( + dataType: T) { def ++[S <: DataType[S, Rep] forSome { type Rep }](b: S): T = { val ast = dataType.$ast - + def merge(a: Any, b: Any): Any = { - if(ast.isObject(a) && ast.isObject(b)) { - ast.fromObject(ast.getKeys(b).foldLeft(ast.getObject(a)) { case (as, k) => - as + (k -> { - if(as contains k) merge(as(k), ast.dereferenceObject(b, k)) else ast.dereferenceObject(b, k) + if (ast.isObject(a) && ast.isObject(b)) { + ast.fromObject( + ast + .getKeys(b) + .foldLeft(ast.getObject(a)) { + case (as, k) => + as + + (k -> { + if (as contains k) + merge(as(k), ast.dereferenceObject(b, k)) + else ast.dereferenceObject(b, k) + }) }) - }) - } else if(ast.isArray(a) && ast.isArray(b)) ast.fromArray(ast.getArray(a) ++ ast.getArray(b)) + } else if (ast.isArray(a) && ast.isArray(b)) + ast.fromArray(ast.getArray(a) ++ ast.getArray(b)) else b } val left = dataType.$normalize - val right = if(ast != b.$ast) ast.convert(b.$normalize, b.$ast.asInstanceOf[DataAst]) else b.$normalize - + val right = + if (ast != b.$ast) + ast.convert(b.$normalize, b.$ast.asInstanceOf[DataAst]) + else b.$normalize + dataType.$wrap(merge(left, right), Vector()) } - def copy(pvs: (DynamicPath[T] => DynamicApplication[_ <: DataType[T, _ <: AstType]])*): T = { - dataType.$wrap(pvs.foldLeft(dataType.$normalize) { case (cur, pv) => - - val dPath = pv(DynamicPath(Nil)) - val ast = dataType.$ast - - if(dPath.application.nothing) cur else { - - def nav(path: List[Either[Int, String]], dest: Any, v: Any): Any = path match { - case Nil => - v - - case Right(next) :: list => - val d = try ast.dereferenceObject(dest, next) catch { case e: Exception => ast.fromObject(Map()) } - val src = ast.getObject(if(ast.isObject(dest)) dest else Map()) - ast.fromObject(src + ((next, nav(list, d, v)))) - - case Left(next) :: list => - val d = try ast.dereferenceArray(dest, next) catch { case e: Exception => ast.fromArray(List()) } - val src = if(ast.isArray(dest)) ast.getArray(dest) else Nil - ast.fromArray(src.padTo(next + 1, ast.fromObject(Map())).updated(next, nav(list, d, v))) - } - - nav(dPath.path.reverse, cur, dPath.application.value) - } + def copy(pvs: (DynamicPath[T] => DynamicApplication[ + _ <: DataType[T, _ <: AstType]])*): T = { + dataType.$wrap(pvs.foldLeft(dataType.$normalize) { + case (cur, pv) => + val dPath = pv(DynamicPath(Nil)) + val ast = dataType.$ast + + if (dPath.application.nothing) cur + else { + + def nav(path: List[Either[Int, String]], dest: Any, v: Any): Any = + path match { + case Nil => + v + + case Right(next) :: list => + val d = try ast.dereferenceObject(dest, next) catch { + case e: Exception => ast.fromObject(Map()) + } + val src = + ast.getObject(if (ast.isObject(dest)) dest else Map()) + ast.fromObject(src + ((next, nav(list, d, v)))) + + case Left(next) :: list => + val d = try ast.dereferenceArray(dest, next) catch { + case e: Exception => ast.fromArray(List()) + } + val src = if (ast.isArray(dest)) ast.getArray(dest) else Nil + ast.fromArray(src + .padTo(next + 1, ast.fromObject(Map())) + .updated(next, nav(list, d, v))) + } + + nav(dPath.path.reverse, cur, dPath.application.value) + } }) } } @@ -150,54 +179,66 @@ trait DataType[+T <: DataType[T, AstType], +AstType <: DataAst] { def \(key: String): T = $deref(Right(key) +: $path) - def \\(key: String): T = $wrap($ast.fromArray(derefRecursive(key, $normalize))) + def \\(key: String): T = + $wrap($ast.fromArray(derefRecursive(key, $normalize))) private def derefRecursive(key: String, any: Any): List[Any] = - if(!$ast.isObject(any)) Nil else $ast.getKeys(any).to[List].flatMap { - case k if k == key => List($ast.dereferenceObject(any, k)) - case k => derefRecursive(key, $ast.dereferenceObject(any, k)) - } + if (!$ast.isObject(any)) Nil + else + $ast.getKeys(any).to[List].flatMap { + case k if k == key => List($ast.dereferenceObject(any, k)) + case k => derefRecursive(key, $ast.dereferenceObject(any, k)) + } protected def doNormalize(orEmpty: Boolean): Any = { - yCombinator[(Any, Vector[Either[Int, String]]), Any] { fn => _ match { - case (j, Vector()) => j: Any - case (j, t :+ e) => - fn(({ - if(e.bimap(x => $ast.isArray(j), x => $ast.isObject(j))) { - try e.bimap($ast.dereferenceArray(j, _), $ast.dereferenceObject(j, _)) catch { - case TypeMismatchException(exp, fnd) => throw TypeMismatchException(exp, fnd) - case e: Exception => - if(orEmpty) DataCompanion.Empty - else throw MissingValueException() - } - } else throw TypeMismatchException( - if($ast.isArray(j)) DataTypes.Array else DataTypes.Object, - e.bimap(l => DataTypes.Array, r => DataTypes.Object) - ) - }, t)) - } } ($root.value -> $path) + yCombinator[(Any, Vector[Either[Int, String]]), Any] { fn => + _ match { + case (j, Vector()) => j: Any + case (j, t :+ e) => + fn(({ + if (e.bimap(x => $ast.isArray(j), x => $ast.isObject(j))) { + try e.bimap($ast.dereferenceArray(j, _), + $ast.dereferenceObject(j, _)) catch { + case TypeMismatchException(exp, fnd) => + throw TypeMismatchException(exp, fnd) + case e: Exception => + if (orEmpty) DataCompanion.Empty + else throw MissingValueException() + } + } else + throw TypeMismatchException( + if ($ast.isArray(j)) DataTypes.Array else DataTypes.Object, + e.bimap(l => DataTypes.Array, r => DataTypes.Object) + ) + }, t)) + } + }($root.value -> $path) } /** Assumes the Json object is wrapping a `T`, and casts (intelligently) to that type. */ - def as[S](implicit ext: Extractor[S, T], mode: Mode[`Data#as`]): - mode.Wrap[S, ext.Throws] = ext.extract(this.asInstanceOf[T], $ast, mode) - - def is[S](implicit ext: Extractor[S, T]): Boolean = try { - ext.extract(this.asInstanceOf[T], $ast, modes.throwExceptions()) - true - } catch { - case e: Exception => false - } + def as[S](implicit ext: Extractor[S, T], + mode: Mode[`Data#as`]): mode.Wrap[S, ext.Throws] = + ext.extract(this.asInstanceOf[T], $ast, mode) + + def is[S](implicit ext: Extractor[S, T]): Boolean = + try { + ext.extract(this.asInstanceOf[T], $ast, modes.throwExceptions()) + true + } catch { + case e: Exception => false + } def apply(i: Int = 0): T = $deref(Left(i) +: $path) - override def equals(any: Any) = try { any match { - case any: DataType[_, _] => $normalize == any.$normalize - case _ => false - } } catch { case e: Exception => false } + override def equals(any: Any) = + try { + any match { + case any: DataType [_, _] => $normalize == any.$normalize + case _ => false + } + } catch { case e: Exception => false } override def hashCode = $root.value.hashCode ^ 3271912 - } trait MutableDataType[+T <: DataType[T, AstType], AstType <: MutableDataAst] @@ -209,47 +250,56 @@ trait MutableDataType[+T <: DataType[T, AstType], AstType <: MutableDataAst] $root.value = newVal case Left(idx) +: init => val jb = $deref(init) - val newJb = $ast.setArrayValue(Try(jb.$normalize).getOrElse($ast.fromArray(Nil)), idx, - newVal) - - if(jb match { - case jb: AnyRef => newJb match { - case newJb: AnyRef => jb ne newJb - case _ => false - } - case jb => jb == newJb - }) $updateParents(init, newJb) + val newJb = $ast.setArrayValue( + Try(jb.$normalize).getOrElse($ast.fromArray(Nil)), idx, newVal) + + if (jb match { + case jb: AnyRef => + newJb match { + case newJb: AnyRef => jb ne newJb + case _ => false + } + case jb => jb == newJb + }) $updateParents(init, newJb) case Right(key) +: init => val jb = $deref(init) - val newJb = $ast.setObjectValue(Try(jb.$normalize).getOrElse($ast.fromObject(Map())), - key, newVal) - - if(jb match { - case jb: AnyRef => newJb match { - case newJb: AnyRef => jb ne newJb - case _ => false - } - case jb => jb == newJb - }) $updateParents(init, newJb) + val newJb = $ast.setObjectValue( + Try(jb.$normalize).getOrElse($ast.fromObject(Map())), key, newVal) + + if (jb match { + case jb: AnyRef => + newJb match { + case newJb: AnyRef => jb ne newJb + case _ => false + } + case jb => jb == newJb + }) $updateParents(init, newJb) } /** Updates the element `key` of the JSON object with the value `v` */ def updateDynamic(key: String)(v: ForcedConversion2[T]): Unit = - if(!v.nothing) $updateParents($path, - $ast.setObjectValue(Try($normalize).getOrElse($ast.fromObject(Map())), key, v.value)) + if (!v.nothing) + $updateParents( + $path, + $ast.setObjectValue( + Try($normalize).getOrElse($ast.fromObject(Map())), key, v.value)) /** Updates the `i`th element of the JSON array with the value `v` */ def update[T2](i: Int, v: T2)(implicit ser: Serializer[T2, T]): Unit = - $updateParents($path, $ast.setArrayValue(Try($normalize).getOrElse($ast.fromArray(Nil)), i, - ser.serialize(v))) + $updateParents( + $path, + $ast.setArrayValue(Try($normalize).getOrElse($ast.fromArray(Nil)), + i, + ser.serialize(v))) /** Removes the specified key from the JSON object */ - def -=(k: String): Unit = $updateParents($path, $ast.removeObjectValue(doNormalize(true), k)) + def -=(k: String): Unit = + $updateParents($path, $ast.removeObjectValue(doNormalize(true), k)) /** Adds the specified value to the JSON array */ def +=[T2](v: T2)(implicit ser: Serializer[T2, T]): Unit = { val r = doNormalize(true) - val insert = if(r == DataCompanion.Empty) $ast.fromArray(Nil) else r + val insert = if (r == DataCompanion.Empty) $ast.fromArray(Nil) else r $updateParents($path, $ast.addArrayValue(insert, ser.serialize(v))) } } @@ -258,9 +308,10 @@ trait `Data#as` extends MethodConstraint trait `Data#normalize` extends MethodConstraint object ForcedConversion2 extends ForcedConversion2_1 { - implicit def forceOptConversion[T, D](opt: Option[T])(implicit ser: Serializer[T, D]) = - opt.map(t => ForcedConversion2[D](ser.serialize(t), false)) getOrElse - ForcedConversion2[D](null, true) + implicit def forceOptConversion[T, D](opt: Option[T])( + implicit ser: Serializer[T, D]) = + opt.map(t => ForcedConversion2[D](ser.serialize(t), false)) getOrElse ForcedConversion2[ + D](null, true) } trait ForcedConversion2_1 { @@ -271,9 +322,10 @@ trait ForcedConversion2_1 { case class ForcedConversion2[-D](value: Any, nothing: Boolean) object ForcedConversion extends ForcedConversion_1 { - implicit def forceOptConversion[T, D](opt: Option[T])(implicit ser: Serializer[T, D]) = - opt.map(t => ForcedConversion[D](ser.serialize(t), false)) getOrElse - ForcedConversion[D](null, true) + implicit def forceOptConversion[T, D](opt: Option[T])( + implicit ser: Serializer[T, D]) = + opt.map(t => ForcedConversion[D](ser.serialize(t), false)) getOrElse ForcedConversion[ + D](null, true) } trait ForcedConversion_1 extends ForcedConversion_2 { @@ -283,11 +335,14 @@ trait ForcedConversion_1 extends ForcedConversion_2 { trait ForcedConversion_2 { // The name of this method is significant for some additional checking done in the macro `contextMacro`. - implicit def forceStringConversion[D, T: StringSerializer](value: T)(implicit ser: Serializer[String, D]) = - ForcedConversion[D](ser.serialize(?[StringSerializer[T]].serialize(value)), false) + implicit def forceStringConversion[D, T : StringSerializer](value: T)( + implicit ser: Serializer[String, D]) = + ForcedConversion[D]( + ser.serialize(?[StringSerializer[T]].serialize(value)), false) } case class ForcedConversion[-D](value: Any, nothing: Boolean) -case class ParseException(source: String, line: Option[Int] = None, column: Option[Int] = None) +case class ParseException( + source: String, line: Option[Int] = None, column: Option[Int] = None) extends Exception("Failed to parse source") diff --git a/data/shared/src/main/scala/rapture/data/exceptions.scala b/data/shared/src/main/scala/rapture/data/exceptions.scala index 7f410ca..e88f9e6 100644 --- a/data/shared/src/main/scala/rapture/data/exceptions.scala +++ b/data/shared/src/main/scala/rapture/data/exceptions.scala @@ -13,14 +13,16 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data -sealed abstract class DataGetException(msg: String) extends RuntimeException(msg) +sealed abstract class DataGetException(msg: String) + extends RuntimeException(msg) -case class TypeMismatchException(found: DataTypes.DataType, expected: DataTypes.DataType) extends - DataGetException(s"type mismatch: Expected ${expected.name} but found ${found.name}") +case class TypeMismatchException( + found: DataTypes.DataType, expected: DataTypes.DataType) + extends DataGetException( + s"type mismatch: Expected ${expected.name} but found ${found.name}") -case class MissingValueException() extends DataGetException( - s"missing value") +case class MissingValueException() extends DataGetException(s"missing value") diff --git a/data/shared/src/main/scala/rapture/data/extractors.scala b/data/shared/src/main/scala/rapture/data/extractors.scala index 4d0abae..242f226 100644 --- a/data/shared/src/main/scala/rapture/data/extractors.scala +++ b/data/shared/src/main/scala/rapture/data/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data @@ -29,125 +29,197 @@ case class FilterException() extends Exception("value was removed by filter") case class NotEmptyException() extends Exception object GeneralExtractors { - - def tryExtractor[Data <: DataType[Data, _ <: DataAst ], T] - (implicit ext: Extractor[T, Data]): Extractor[Try[T], Data] { type Throws = Nothing } = + + def tryExtractor[Data <: DataType[Data, _ <: DataAst], T]( + implicit ext: Extractor[T, Data] + ): Extractor[Try[T], Data] { type Throws = Nothing } = new Extractor[Try[T], Data] { type Throws = Nothing - def extract(any: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Try[T], Throws] = mode.wrap { - try ext.extract(any.$wrap(any.$normalize), any.$ast, modes.returnTry()) catch { - case e: Exception => Failure(e) + def extract( + any: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Try[T], Throws] = + mode.wrap { + try ext.extract( + any.$wrap(any.$normalize), any.$ast, modes.returnTry()) catch { + case e: Exception => Failure(e) + } } - } } - def optionExtractor[Data <: DataType[Data, _ <: DataAst], T](implicit ext: Extractor[T, Data]): - Extractor[Option[T], Data] { type Throws = Nothing } = { + def optionExtractor[Data <: DataType[Data, _ <: DataAst], T]( + implicit ext: Extractor[T, Data] + ): Extractor[Option[T], Data] { type Throws = Nothing } = { new Extractor[Option[T], Data] { type Throws = Nothing - def extract(any: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Option[T], Throws] = mode.wrap { - try ext.extract(any.$wrap(any.$normalize), any.$ast, modes.returnOption()) catch { - case e: Exception => None + def extract( + any: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Option[T], Throws] = + mode.wrap { + try ext.extract(any.$wrap(any.$normalize), + any.$ast, + modes.returnOption()) catch { + case e: Exception => None + } } - } } } - - def noneExtractor[Data <: DataType[_, DataAst]]: Extractor[None.type, Data] { type Throws = DataGetException with NotEmptyException } = + + def noneExtractor[Data <: DataType[_, DataAst]]: Extractor[None.type, Data] { + type Throws = DataGetException with NotEmptyException + } = new Extractor[None.type, Data] { type Throws = DataGetException with NotEmptyException - def extract(value: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[None.type, Throws] = mode.wrap { - val v = value.$wrap(value.$normalize) - if(ast.isObject(v) && ast.getKeys(v).size == 0) None - else mode.exception[None.type, NotEmptyException](NotEmptyException()) - } + def extract( + value: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[None.type, Throws] = + mode.wrap { + val v = value.$wrap(value.$normalize) + if (ast.isObject(v) && ast.getKeys(v).size == 0) None + else + mode.exception[None.type, NotEmptyException](NotEmptyException()) + } } - def genSeqExtractor[T, Coll[_], Data <: DataType[Data, _ <: DataAst]] - (implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], ext: Extractor[T, Data]): - Extractor[Coll[T], Data] { type Throws = ext.Throws } = { - + def genSeqExtractor[T, Coll[_], Data <: DataType[Data, _ <: DataAst]]( + implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], + ext: Extractor[T, Data] + ): Extractor[Coll[T], Data] { type Throws = ext.Throws } = { + new Extractor[Coll[T], Data] { type Throws = ext.Throws - def extract(value: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Coll[T], Throws] = mode.wrap { - mode.catching[DataGetException, Coll[T]] { - val v = value.$wrap(value.$normalize) - v.$ast.getArray(v.$root.value).to[List].zipWithIndex.map { case (e, i) => - mode.unwrap(ext.safeExtract(v.$wrap(e), v.$ast, Some(Left(i)), mode), s"($i)") - }.to[Coll] + def extract( + value: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Coll[T], Throws] = + mode.wrap { + mode.catching[DataGetException, Coll[T]] { + val v = value.$wrap(value.$normalize) + v.$ast + .getArray(v.$root.value) + .to[List] + .zipWithIndex + .map { + case (e, i) => + mode.unwrap( + ext.safeExtract(v.$wrap(e), v.$ast, Some(Left(i)), mode), + s"($i)") + } + .to[Coll] + } } - } } } - def mapExtractor[K, T, Data <: DataType[Data, _ <: DataAst ]] - (implicit ext: Extractor[T, Data], ext2: StringParser[K]): Extractor[Map[K, T], Data] { type Throws = ext.Throws with ext2.Throws } = + def mapExtractor[K, T, Data <: DataType[Data, _ <: DataAst]]( + implicit ext: Extractor[T, Data], + ext2: StringParser[K] + ): Extractor[Map[K, T], Data] { + type Throws = ext.Throws with ext2.Throws + } = new Extractor[Map[K, T], Data] { type Throws = ext.Throws with ext2.Throws - def extract(value: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Map[K, T], Throws] = + def extract( + value: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Map[K, T], Throws] = mode.wrap { value.$ast.getObject(value.$normalize) map { - case (k, v) => mode.unwrap(ext2.parse(k, mode)) -> mode.unwrap(ext.safeExtract(value.$wrap(v), value.$ast, Some(Right(k)), mode)) + case (k, v) => + mode.unwrap(ext2.parse(k, mode)) -> mode.unwrap(ext.safeExtract( + value.$wrap(v), value.$ast, Some(Right(k)), mode)) } } - } + } } object Extractor { - implicit def floatExtractor[Data](implicit ext: Extractor[Double, Data]): Extractor[Float, Data] { type Throws = ext.Throws } = + implicit def floatExtractor[Data](implicit ext: Extractor[Double, Data] + ): Extractor[Float, Data] { type Throws = ext.Throws } = ext.smap(_.toFloat) - implicit def shortExtractor[Data](implicit ext: Extractor[Double, Data]): Extractor[Short, Data] { type Throws = ext.Throws } = + implicit def shortExtractor[Data](implicit ext: Extractor[Double, Data] + ): Extractor[Short, Data] { type Throws = ext.Throws } = ext.smap(_.toShort) - implicit def longExtractor[Data](implicit ext: Extractor[Double, Data]): Extractor[Long, Data] { type Throws = ext.Throws } = ext.smap(_.toLong) + implicit def longExtractor[Data](implicit ext: Extractor[Double, Data] + ): Extractor[Long, Data] { type Throws = ext.Throws } = + ext.smap(_.toLong) - implicit def byteExtractor[Data](implicit ext: Extractor[Double, Data]): Extractor[Byte, Data] { type Throws = ext.Throws } = + implicit def byteExtractor[Data](implicit ext: Extractor[Double, Data] + ): Extractor[Byte, Data] { type Throws = ext.Throws } = ext.smap(_.toInt.toByte) - implicit def anyExtractor[Data <: DataType[_, DataAst]]: Extractor[Any, Data] { type Throws = Nothing } = + implicit def anyExtractor[ + Data <: DataType[_, DataAst]]: Extractor[Any, Data] { + type Throws = Nothing + } = new Extractor[Any, Data] { type Throws = Nothing - def extract(value: Data, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Any, Throws] = + def extract(value: Data, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[Any, Throws] = mode.wrap(value.$normalize) } } @implicitNotFound("cannot extract type ${T} from ${D}.") -abstract class Extractor[T, -D] extends Functor[({ type L[x] = Extractor[x, D] })#L, T] { ext => +abstract class Extractor[T, -D] + extends Functor[({ type L[x] = Extractor[x, D] })#L, T] { ext => type Throws <: Exception - - def safeExtract(any: D, ast: DataAst, prefix: Option[Either[Int, String]], mode: Mode[_ <: MethodConstraint]): - mode.Wrap[T, Throws] = mode.wrap { - try mode.unwrap(extract(any, ast, mode)) catch { - case e@TypeMismatchException(_, _) => mode.exception(e) - case e@MissingValueException() => mode.exception(e) + + def safeExtract(any: D, + ast: DataAst, + prefix: Option[Either[Int, String]], + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] = + mode.wrap { + try mode.unwrap(extract(any, ast, mode)) catch { + case e @ TypeMismatchException(_, _) => mode.exception(e) + case e @ MissingValueException() => mode.exception(e) + } } - } - - def extract(any: D, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] - def rawMap[T2](fn: (T, Mode[_ <: MethodConstraint]) => T2): Extractor[T2, D] = new Extractor[T2, D] { - def extract(any: D, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T2, Throws] = - mode.wrap(fn(mode.unwrap(ext.extract(any, ast, mode)), mode.generic)) - } + def extract(any: D, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] + + def rawMap[T2]( + fn: (T, Mode[_ <: MethodConstraint]) => T2): Extractor[T2, D] = + new Extractor[T2, D] { + def extract(any: D, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T2, Throws] = + mode.wrap(fn(mode.unwrap(ext.extract(any, ast, mode)), mode.generic)) + } - def filter(pred: T => Boolean): Extractor[T, D] { type Throws = ext.Throws with FilterException } = new Extractor[T, D] { - type Throws = ext.Throws with FilterException - def extract(any: D, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] = mode.wrap { - val result = mode.unwrap(ext.extract(any, ast, mode)) - if(pred(result)) result else mode.exception[T, FilterException](FilterException()) + def filter(pred: T => Boolean + ): Extractor[T, D] { type Throws = ext.Throws with FilterException } = + new Extractor[T, D] { + type Throws = ext.Throws with FilterException + def extract(any: D, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, Throws] = + mode.wrap { + val result = mode.unwrap(ext.extract(any, ast, mode)) + if (pred(result)) result + else mode.exception[T, FilterException](FilterException()) + } } - } - def orElse[TS >: T, T2 <: TS, D2 <: D](ext2: => Extractor[T2, D2]): Extractor[TS, D2] { type Throws = DataGetException } = + def orElse[TS >: T, T2 <: TS, D2 <: D](ext2: => Extractor[T2, D2] + ): Extractor[TS, D2] { type Throws = DataGetException } = new Extractor[TS, D2] { type Throws = DataGetException - def extract(any: D2, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[TS, Throws] = mode.wrap { - try mode.unwrap(ext.extract(any, ast, mode)) catch { - case e: Exception => mode.unwrap(ext2.extract(any, ast, mode)) + def extract(any: D2, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[TS, Throws] = + mode.wrap { + try mode.unwrap(ext.extract(any, ast, mode)) catch { + case e: Exception => mode.unwrap(ext2.extract(any, ast, mode)) + } } - } - } + } } diff --git a/data/shared/src/main/scala/rapture/data/macros.scala b/data/shared/src/main/scala/rapture/data/macros.scala index 3360526..bdaed61 100644 --- a/data/shared/src/main/scala/rapture/data/macros.scala +++ b/data/shared/src/main/scala/rapture/data/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data @@ -40,8 +40,8 @@ object Macros { // } // def numChildren[T]: Int = macro impl[T] - - def extractorMacro[T: c.WeakTypeTag, Data: c.WeakTypeTag, Th](c: WhiteboxContext): c.Expr[Extractor[T, Data] { type Throws = Th }] = { + def extractorMacro[T : c.WeakTypeTag, Data : c.WeakTypeTag, Th]( + c: WhiteboxContext): c.Expr[Extractor[T, Data] { type Throws = Th }] = { import c.universe._ import compatibility._ @@ -50,267 +50,316 @@ object Macros { val implicitSearchFailures = collection.mutable.ListMap[String, List[String]]().withDefault(_ => Nil) - if(weakTypeOf[T] <:< typeOf[AnyVal]) { - val param = paramLists(c)(declarations(c)(weakTypeOf[T]).collect { + if (weakTypeOf[T] <:< typeOf[AnyVal]) { + val param = paramLists(c)( + declarations(c)(weakTypeOf[T]).collect { case t: MethodSymbol => t.asMethod }.find(_.isPrimaryConstructor).get).head.head - + val paramType = param.typeSignature - - val inferredExtractor = c.inferImplicitValue(appliedType(extractor, List(paramType, - weakTypeOf[Data])), false, false) - + + val inferredExtractor = c.inferImplicitValue( + appliedType(extractor, List(paramType, weakTypeOf[Data])), + false, + false) + val newName = termName(c, freshName(c)("param$")) - - c.Expr(Apply( - Select( - inferredExtractor, termName(c, "map") - ), - List( - Function( - List( - ValDef( - Modifiers(Flag.PARAM), - newName, - TypeTree(), - EmptyTree - ) - ), - Apply( + + c.Expr( + Apply( Select( - New(TypeTree(weakTypeOf[T])), - constructor(c) + inferredExtractor, + termName(c, "map") ), List( - Ident(newName) + Function( + List( + ValDef( + Modifiers(Flag.PARAM), + newName, + TypeTree(), + EmptyTree + ) + ), + Apply( + Select( + New(TypeTree(weakTypeOf[T])), + constructor(c) + ), + List( + Ident(newName) + ) + ) + ) ) - ) - ) - ) - )) + )) } else { require(weakTypeOf[T].typeSymbol.asClass.isCaseClass) - val defaults = weakTypeOf[T].typeSymbol.companionSymbol.typeSignature.declarations.to[List].map(_.name.decodedName.toString).filter(_ startsWith "apply$default$").map(_.substring(14).toInt).to[Set] + val defaults = + weakTypeOf[T].typeSymbol.companionSymbol.typeSignature.declarations + .to[List] + .map(_.name.decodedName.toString) + .filter(_ startsWith "apply$default$") + .map(_.substring(14).toInt) + .to[Set] // FIXME integrate these into a fold var throwsTypes: Set[Type] = Set(typeOf[DataGetException]) - val params = declarations(c)(weakTypeOf[T]).collect { - case m: MethodSymbol if m.isCaseAccessor => m.asMethod - }.zipWithIndex map { case (p, idx) => - val deref = q"""data.selectDynamic(${Literal(Constant(p.name.decodedName.toString))})""" - - val NothingType = weakTypeOf[Nothing] - - val imp = try c.inferImplicitValue(appliedType(extractor, List(p.returnType, weakTypeOf[Data])), false, - false) catch { - - case e: Exception => - implicitSearchFailures(p.returnType.toString) ::= p.name.decodedName.toString - null - } + val params = + declarations(c)(weakTypeOf[T]).collect { + case m: MethodSymbol if m.isCaseAccessor => m.asMethod + }.zipWithIndex map { + case (p, idx) => + val deref = q"""data.selectDynamic(${Literal( + Constant(p.name.decodedName.toString))})""" - val t = try { - imp.tpe.member(typeName(c, "Throws")).typeSignature match { - case NothingType => List() - case refinedType: RefinedType => refinedType.parents - case typ: Type => List(typ) - case _ => ??? - } - } catch { - case e: Exception => - List() - } + val NothingType = weakTypeOf[Nothing] - throwsTypes ++= t - - // Borrowed from Shapeless - def companionRef(tpe: Type): Tree = { - val global = c.universe.asInstanceOf[scala.tools.nsc.Global] - val gTpe = tpe.asInstanceOf[global.Type] - val pre = gTpe.prefix - val sym = gTpe.typeSymbol - val cSym = sym.companionSymbol - if(cSym != NoSymbol) global.gen.mkAttributedRef(pre, cSym).asInstanceOf[Tree] - else Ident(tpe.typeSymbol.name.toTermName) - } - - if(defaults.contains(idx + 1)) q""" - mode.unwrap(if($deref.is($imp)) $deref.as($imp, mode.generic) else mode.wrap(${companionRef(weakTypeOf[T])}.${termName(c, "apply$default$"+(idx + 1))}.asInstanceOf[${p.returnType}]), ${Literal(Constant("."+p.name.decodedName))}) - """ else q""" - mode.unwrap($deref.as($imp, mode.generic), ${Literal(Constant("."+p.name.decodedName))}) - """ - } + val imp = try c.inferImplicitValue( + appliedType(extractor, List(p.returnType, weakTypeOf[Data])), + false, + false) catch { - if(!implicitSearchFailures.isEmpty) { - val paramStrings = implicitSearchFailures map { - case (t, p1 :: Nil) => - s"parameter `$p1' of type $t" - case (t, p1 :: ps) => - s"parameters ${ps.map(v => s"`$v'").mkString(", ")} and `$p1' of type $t" - case (t, Nil) => - ??? // Doesn't happen + case e: Exception => + implicitSearchFailures(p.returnType.toString) ::= + p.name.decodedName.toString + null + } + + val t = try { + imp.tpe.member(typeName(c, "Throws")).typeSignature match { + case NothingType => List() + case refinedType: RefinedType => refinedType.parents + case typ: Type => List(typ) + case _ => ??? + } + } catch { + case e: Exception => + List() + } + + throwsTypes ++= t + + // Borrowed from Shapeless + def companionRef(tpe: Type): Tree = { + val global = c.universe.asInstanceOf[scala.tools.nsc.Global] + val gTpe = tpe.asInstanceOf[global.Type] + val pre = gTpe.prefix + val sym = gTpe.typeSymbol + val cSym = sym.companionSymbol + if (cSym != NoSymbol) + global.gen.mkAttributedRef(pre, cSym).asInstanceOf[Tree] + else Ident(tpe.typeSymbol.name.toTermName) + } + + if (defaults.contains(idx + 1)) + q""" + mode.unwrap(if($deref.is($imp)) $deref.as($imp, mode.generic) else mode.wrap(${companionRef( + weakTypeOf[T])}.${termName(c, "apply$default$" + (idx + 1))}.asInstanceOf[${p.returnType}]), ${Literal( + Constant("." + p.name.decodedName))}) + """ + else + q""" + mode.unwrap($deref.as($imp, mode.generic), ${Literal( + Constant("." + p.name.decodedName))}) + """ } + + if (!implicitSearchFailures.isEmpty) { + val paramStrings = + implicitSearchFailures map { + case (t, p1 :: Nil) => + s"parameter `$p1' of type $t" + case (t, p1 :: ps) => + s"parameters ${ps.map(v => s"`$v'").mkString(", ")} and `$p1' of type $t" + case (t, Nil) => + ??? // Doesn't happen + } val errorString = paramStrings.to[List].reverse match { case t1 :: Nil => t1 case t1 :: ts => s"${ts.mkString(", ")} and $t1" case Nil => ??? // Doesn't happen } - val plural = if(implicitSearchFailures.flatMap(_._2).size > 1) - s"${weakTypeOf[Data].typeSymbol.name} extractors" else - s"a ${weakTypeOf[Data].typeSymbol.name} extractor" - - val err = s"Could not generate a ${weakTypeOf[Data].typeSymbol.name} extractor for case "+ - s"class ${weakTypeOf[T].typeSymbol.name} because $plural for $errorString could not "+ - s"be found" - - if(!emittedWarnings.contains(err)) { + val plural = + if (implicitSearchFailures.flatMap(_._2).size > 1) + s"${weakTypeOf[Data].typeSymbol.name} extractors" + else s"a ${weakTypeOf[Data].typeSymbol.name} extractor" + + val err = + s"Could not generate a ${weakTypeOf[Data].typeSymbol.name} extractor for case " + + s"class ${weakTypeOf[T].typeSymbol.name} because $plural for $errorString could not " + + s"be found" + + if (!emittedWarnings.contains(err)) { emittedWarnings += err c.warning(NoPosition, err) } } require(implicitSearchFailures.isEmpty) - + val construction = c.Expr[T]( - Apply( - Select( - New( - TypeTree(weakTypeOf[T]) - ), - constructor(c) - ), - params.to[List] - ) + Apply( + Select( + New( + TypeTree(weakTypeOf[T]) + ), + constructor(c) + ), + params.to[List] + ) ) - c.Expr(q""" + c.Expr( + q""" (new _root_.rapture.data.Extractor[${weakTypeOf[T]}, ${weakTypeOf[Data]}] { - def extract(data: ${weakTypeOf[Data]}, ast: _root_.rapture.data.DataAst, mode: _root_.rapture.core.Mode[_ <: _root_.rapture.core.MethodConstraint]): mode.Wrap[${weakTypeOf[T]}, Throws] = mode.wrap { ${construction} } - }).asInstanceOf[_root_.rapture.data.Extractor[${weakTypeOf[T]}, ${weakTypeOf[Data]}] { - type Throws = ${normalize(c)(typeIntersection(c)(throwsTypes.to[List]))} + def extract(data: ${weakTypeOf[Data]}, ast: _root_.rapture.data.DataAst, mode: _root_.rapture.core.Mode[_ <: _root_.rapture.core.MethodConstraint]): mode.Wrap[${weakTypeOf[ + T]}, Throws] = mode.wrap { ${construction} } + }).asInstanceOf[_root_.rapture.data.Extractor[${weakTypeOf[T]}, ${weakTypeOf[ + Data]}] { + type Throws = ${normalize(c)( + typeIntersection(c)(throwsTypes.to[List]))} }] """) } } - def serializerMacro[T: c.WeakTypeTag, Data: c.WeakTypeTag](c: WhiteboxContext)(ast: c.Expr[DataAst]): - c.Expr[Serializer[T, Data]] = { + def serializerMacro[ + T : c.WeakTypeTag, Data : c.WeakTypeTag](c: WhiteboxContext)( + ast: c.Expr[DataAst]): c.Expr[Serializer[T, Data]] = { import c.universe._ import compatibility._ val tpe = weakTypeOf[T].typeSymbol.asClass - val serializer = typeOf[Serializer[_, _]].typeSymbol.asType.toTypeConstructor + val serializer = + typeOf[Serializer[_, _]].typeSymbol.asType.toTypeConstructor + + if (weakTypeOf[T] <:< typeOf[AnyVal]) { - if(weakTypeOf[T] <:< typeOf[AnyVal]) { - - val param = paramLists(c)(declarations(c)(weakTypeOf[T]).collect { + val param = paramLists(c)( + declarations(c)(weakTypeOf[T]).collect { case t: MethodSymbol => t.asMethod }.find(_.isPrimaryConstructor).get).head.head - + val paramName = param.name.decodedName.toString val paramType = param.typeSignature - val inferredSerializer = c.inferImplicitValue(appliedType(serializer, List(paramType, - weakTypeOf[Data])), false, false) + val inferredSerializer = c.inferImplicitValue( + appliedType(serializer, List(paramType, weakTypeOf[Data])), + false, + false) val newName = termName(c, freshName(c)("param$")) - - c.Expr(Apply( - Select( - inferredSerializer, termName(c, "contramap") - ), - List( - Function( - List( - ValDef( - Modifiers(Flag.PARAM), - newName, - TypeTree(weakTypeOf[T]), - EmptyTree + + c.Expr( + Apply( + Select( + inferredSerializer, + termName(c, "contramap") + ), + List( + Function( + List( + ValDef( + Modifiers(Flag.PARAM), + newName, + TypeTree(weakTypeOf[T]), + EmptyTree + ) + ), + Select( + Ident(newName), + termName(c, paramName) + ) + ) ) - ), - Select( - Ident(newName), - termName(c, paramName) - ) - ) - ) - )) + )) } else { - val construction = if(tpe.isCaseClass) { + val construction = + if (tpe.isCaseClass) { - val params = declarations(c)(weakTypeOf[T]) collect { - case m: MethodSymbol if m.isCaseAccessor => m.asMethod - } map { p => - Apply( - Select( - Ident("scala"), - termName(c, "Tuple2") - ), - List( - Literal(Constant(p.name.decodedName.toString)), + val params = + declarations(c)(weakTypeOf[T]) collect { + case m: MethodSymbol if m.isCaseAccessor => m.asMethod + } map { p => Apply( - Select( - c.inferImplicitValue(appliedType(serializer, List(p.returnType, - weakTypeOf[Data])), false, false), - termName(c, "serialize") - ), - List( Select( - Ident(termName(c, "t")), - p.name + Ident("scala"), + termName(c, "Tuple2") + ), + List( + Literal(Constant(p.name.decodedName.toString)), + Apply( + Select( + c.inferImplicitValue( + appliedType(serializer, + List(p.returnType, + weakTypeOf[Data])), + false, + false), + termName(c, "serialize") + ), + List( + Select( + Ident(termName(c, "t")), + p.name + ) + ) + ) ) - ) ) - ) - ) - } + } - c.Expr[Map[String, Any]]( - Apply( - Select( - Select( - Ident(definitions.PredefModule), - termName(c, "Map") - ), - termName(c, "apply") - ), - params.to[List] - ) - ) - } else if(tpe.isSealed) { - c.Expr[Map[String, Any]]( - Match( - Ident(termName(c, "t")), - tpe.knownDirectSubclasses.to[List] map { sc => - CaseDef( - Bind( - termName(c, "v"), - Typed( - Ident(wildcard(c)), - Ident(sc.asClass) - ) - ), - EmptyTree, - Apply( + c.Expr[Map[String, Any]]( + Apply( Select( - c.inferImplicitValue(appliedType(serializer, List(sc.asType.toType)), false, - false), - termName(c, "serialize") + Select( + Ident(definitions.PredefModule), + termName(c, "Map") + ), + termName(c, "apply") ), - List(Ident(termName(c, "v"))) - ) + params.to[List] + ) + ) + } else if (tpe.isSealed) { + c.Expr[Map[String, Any]]( + Match( + Ident(termName(c, "t")), + tpe.knownDirectSubclasses.to[List] map { sc => + CaseDef( + Bind( + termName(c, "v"), + Typed( + Ident(wildcard(c)), + Ident(sc.asClass) + ) + ), + EmptyTree, + Apply( + Select( + c.inferImplicitValue( + appliedType(serializer, + List(sc.asType.toType)), + false, + false), + termName(c, "serialize") + ), + List(Ident(termName(c, "v"))) + ) + ) + } ) - } ) - ) - } else throw new Exception() + } else throw new Exception() - reify(new Serializer[T, Data] { - def serialize(t: T): Any = ast.splice.fromObject(construction.splice.filterNot { v => - ast.splice.isNull(v._2) - }) + reify( + new Serializer[T, Data] { + def serialize(t: T): Any = + ast.splice.fromObject(construction.splice.filterNot { v => + ast.splice.isNull(v._2) + }) }) } } diff --git a/data/shared/src/main/scala/rapture/data/serializers.scala b/data/shared/src/main/scala/rapture/data/serializers.scala index eeee2cc..2c06961 100644 --- a/data/shared/src/main/scala/rapture/data/serializers.scala +++ b/data/shared/src/main/scala/rapture/data/serializers.scala @@ -13,14 +13,15 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.data import rapture.core._ import scala.annotation._ -@implicitNotFound("Cannot serialize type ${T} to ${D}. Please provide an implicit Serializer "+ +@implicitNotFound( + "Cannot serialize type ${T} to ${D}. Please provide an implicit Serializer " + "of type ${T}.") trait Serializer[T, -D] { ser => def serialize(t: T): Any @@ -28,6 +29,4 @@ trait Serializer[T, -D] { ser => def contramap[T2](fn: T2 => T) = new Serializer[T2, D] { def serialize(t: T2): Any = ser.serialize(fn(t)) } - } - diff --git a/dom/shared/src/main/scala/rapture/dom/dom.scala b/dom/shared/src/main/scala/rapture/dom/dom.scala index 9e16259..3d70ff7 100644 --- a/dom/shared/src/main/scala/rapture/dom/dom.scala +++ b/dom/shared/src/main/scala/rapture/dom/dom.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.dom @@ -34,122 +34,166 @@ trait `DomNodes#apply` extends MethodConstraint trait `Element#selectDynamic` extends MethodConstraint object Applicable { - implicit def reportElementError[Child <: ElementType, Att <: AttributeType, Child2 <: ElementType, Elem <: ElementType, - Att2 <: AttributeType](value: DomNode[Child2, Elem, Att]): Any = - macro DomMacros.reportElementErrorMacro[Child, Att, Child2, Elem, Att2] - - implicit def listToApplicable[Child <: ElementType, Elem <: ElementType, Att <: AttributeType, Ap <: Element[Child, Elem, Att]](apps: List[Ap]): Element[Child, Elem, Att] = apps.head - - implicit def wrapIterable[Child <: ElementType, This <: ElementType, Att <: AttributeType](xs: - Iterable[Element[Child, This, Att]]): ElementLike[Child, This, Att] = ElementSeq[Child, This, Att](xs) - + implicit def reportElementError[ + Child <: ElementType, Att <: AttributeType, Child2 <: ElementType, Elem <: ElementType, Att2 <: AttributeType]( + value: DomNode[Child2, Elem, Att]): Any = macro DomMacros + .reportElementErrorMacro[Child, Att, Child2, Elem, Att2] + + implicit def listToApplicable[ + Child <: ElementType, Elem <: ElementType, Att <: AttributeType, Ap <: Element[ + Child, Elem, Att]](apps: List[Ap]): Element[Child, Elem, Att] = + apps.head + + implicit def wrapIterable[ + Child <: ElementType, This <: ElementType, Att <: AttributeType]( + xs: Iterable[Element[Child, This, Att]]): ElementLike[Child, This, Att] = + ElementSeq[Child, This, Att](xs) } -trait Applicable[+ChildType, +ThisAttType, AppliedType[_ <: ElementType, _ <: ElementType, - _ <: AttributeType]] { - def application[Child <: ElementType, This <: ElementType, Att <: AttributeType] - (element: Element[Child, This, Att], applied: Applicable[Child, Att, AppliedType]*): - AppliedType[Child, This, Att] +trait Applicable[+ChildType, + +ThisAttType, + AppliedType[ + _ <: ElementType, _ <: ElementType, _ <: AttributeType]] { + def application[ + Child <: ElementType, This <: ElementType, Att <: AttributeType]( + element: Element[Child, This, Att], + applied: Applicable[Child, Att, AppliedType]* + ): AppliedType[Child, This, Att] } -sealed abstract class DomNode[+ChildType <: ElementType, +ThisType <: ElementType, ThisAttType <: AttributeType] +sealed abstract class DomNode[+ChildType <: ElementType, + +ThisType <: ElementType, + ThisAttType <: AttributeType] extends Applicable[ThisType, Nothing, AppliedElement] { - + def block = true - def application[Child <: ElementType, This <: ElementType, Att <: AttributeType] - (element: Element[Child, This, Att], applied: Applicable[Child, Att, AppliedElement]*): - AppliedElement[Child, This, Att] = + def application[ + Child <: ElementType, This <: ElementType, Att <: AttributeType]( + element: Element[Child, This, Att], + applied: Applicable[Child, Att, AppliedElement]* + ): AppliedElement[Child, This, Att] = AppliedElement[Child, This, Att]( - element.tagName, - element.attributes, - applied.to[List].asInstanceOf[List[Element[_ <: ElementType, Child, _ <: AttributeType]]], - element.forceClosingTag, - element.block + element.tagName, + element.attributes, + applied + .to[List] + .asInstanceOf[List[Element[ + _ <: ElementType, Child, _ <: AttributeType]]], + element.forceClosingTag, + element.block ) } -case class DomNodes[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType] - (elements: Vector[Element[ChildType, ThisType, AttType]]) extends AnyVal { - - def apply(i: Int = 0)(implicit mode: Mode[`DomNodes#apply`]) = mode.wrap(elements(i)) - +case class DomNodes[ + ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType]( + elements: Vector[Element[ChildType, ThisType, AttType]]) + extends AnyVal { + + def apply(i: Int = 0)(implicit mode: Mode[`DomNodes#apply`]) = + mode.wrap(elements(i)) + override def toString = elements.mkString("\n") - - def \[Child <: ElementType, This <: ElementType, Att <: AttributeType](tag: Tag[Child, This, Att]): - DomNodes[Child, This, Att] = DomNodes(elements.flatMap { xs => (xs \ tag).elements }) - def \\[Child <: ElementType, This <: ElementType, Att <: AttributeType](tag: Tag[Child, This, Att]): - DomNodes[Child, This, Att] = DomNodes(elements.flatMap { xs => (xs \\ tag).elements }) + def \[Child <: ElementType, This <: ElementType, Att <: AttributeType]( + tag: Tag[Child, This, Att]): DomNodes[Child, This, Att] = + DomNodes( + elements.flatMap { xs => + (xs \ tag).elements + }) + + def \\[Child <: ElementType, This <: ElementType, Att <: AttributeType]( + tag: Tag[Child, This, Att]): DomNodes[Child, This, Att] = + DomNodes( + elements.flatMap { xs => + (xs \\ tag).elements + }) } -case class MissingAttributeException(name: String) extends Exception(s"The attribute $name was not found") +case class MissingAttributeException(name: String) + extends Exception(s"The attribute $name was not found") -case class TextNode[ThisType <: ElementType, ThisAttType <: AttributeType, Position <: ElementType] - (text: String) extends DomNode[Position, ThisType, ThisAttType] { - def format[Output](implicit formatter: DomFormatter[Output]): Output = formatter.format(this) +case class TextNode[ + ThisType <: ElementType, ThisAttType <: AttributeType, Position <: ElementType]( + text: String) + extends DomNode[Position, ThisType, ThisAttType] { + def format[Output](implicit formatter: DomFormatter[Output]): Output = + formatter.format(this) override def toString = DomFormatter.domFormatterImplicit.format(this) override def block = false } case class Comment(comment: String) extends DomNode { - def format[Output](implicit formatter: DomFormatter[Output]): Output = formatter.format(this) + def format[Output](implicit formatter: DomFormatter[Output]): Output = + formatter.format(this) override def toString = DomFormatter.domFormatterImplicit.format(this) } object Element { - implicit def reportElementError2[Child <: ElementType, Att <: AttributeType, Child2 <: ElementType, Elem <: ElementType] - (value: DomNode[Child2, Elem, Att]): Any = - macro DomMacros.reportElementError2Macro[Child, Att, Child2, Elem] + implicit def reportElementError2[ + Child <: ElementType, Att <: AttributeType, Child2 <: ElementType, Elem <: ElementType]( + value: DomNode[Child2, Elem, Att]): Any = macro DomMacros + .reportElementError2Macro[Child, Att, Child2, Elem] } -sealed abstract class ElementLike[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType] - extends DomNode[ChildType, ThisType, AttType] with Applicable[ThisType, Nothing, AppliedElement] - with Dynamic with Product with Serializable { - -} +sealed abstract class ElementLike[ChildType <: ElementType, + ThisType <: ElementType, + AttType <: AttributeType] + extends DomNode[ChildType, ThisType, AttType] + with Applicable[ThisType, Nothing, AppliedElement] with Dynamic + with Product with Serializable {} -sealed abstract class Element[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType] +sealed abstract class Element[ChildType <: ElementType, + ThisType <: ElementType, + AttType <: AttributeType] extends ElementLike[ChildType, ThisType, AttType] { - + def tagName: String def attributes: Map[AttributeKey[String, AttributeType], Any] def children: List[DomNode[_ <: ElementType, ChildType, _ <: AttributeType]] def forceClosingTag: Boolean def block: Boolean - def format[Output](implicit formatter: DomFormatter[Output]): Output = formatter.format(this) - - def selectDynamic(s: String)(implicit ar: AttributeKey[s.type, AttType], mode: Mode[`Element#selectDynamic`]) = + def format[Output](implicit formatter: DomFormatter[Output]): Output = + formatter.format(this) + + def selectDynamic(s: String)(implicit ar: AttributeKey[s.type, AttType], + mode: Mode[`Element#selectDynamic`]) = mode.wrap { val ar2 = ar.asInstanceOf[AttributeKey[String, AttributeType]] - if(attributes.contains(ar2)) attributes(ar2).asInstanceOf[ar.Value] + if (attributes.contains(ar2)) attributes(ar2).asInstanceOf[ar.Value] else mode.exception(MissingAttributeException(ar2.name)) } - def \[Child <: ElementType, This <: ElementType, Att <: AttributeType](tag: Tag[Child, This, Att]): - DomNodes[Child, This, Att] = - DomNodes[Child, This, Att](children.filter { - case elem: Element[_, _, _] => elem.tagName == tag.tagName + def \[Child <: ElementType, This <: ElementType, Att <: AttributeType]( + tag: Tag[Child, This, Att]): DomNodes[Child, This, Att] = + DomNodes[Child, This, Att]( + children.filter { + case elem: Element [_, _, _] => elem.tagName == tag.tagName case _ => false }.map(_.asInstanceOf[Element[Child, This, Att]]).to[Vector]) - def \\[Child <: ElementType, This <: ElementType, Att <: AttributeType](tag: Tag[Child, This, Att]): - DomNodes[Child, This, Att] = - DomNodes(children.to[Vector].flatMap { - case e: Element[_, _, _] => - val found = (e \ tag) - found.elements ++ (e \\ tag).elements - case _ => Vector() - }) + def \\[Child <: ElementType, This <: ElementType, Att <: AttributeType]( + tag: Tag[Child, This, Att]): DomNodes[Child, This, Att] = + DomNodes( + children + .to[Vector] + .flatMap { + case e: Element [_, _, _] => + val found = (e \ tag) + found.elements ++ (e \\ tag).elements + case _ => Vector() + }) override def toString = DomFormatter.domFormatterImplicit.format(this) - } -case class Tag[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType] - (forceClosingTag: Boolean = false, override val block: Boolean = true)(implicit assigned: AssignedName) extends - Element[ChildType, ThisType, AttType] { +case class Tag[ChildType <: ElementType, + ThisType <: ElementType, + AttType <: AttributeType]( + forceClosingTag: Boolean = false, override val block: Boolean = true)( + implicit assigned: AssignedName) + extends Element[ChildType, ThisType, AttType] { type Content = AppliedElement[_ <: ElementType, ChildType, _ <: AttType] @@ -157,74 +201,98 @@ case class Tag[ChildType <: ElementType, ThisType <: ElementType, AttType <: Att def attributes = Map() def children = List() - def apply[AppliedType[_ <: ElementType, _ <: ElementType, _ <: AttributeType] <: DomNode[_, _, _]]( - first: Applicable[ChildType, AttType, AppliedType], applied: Applicable[ChildType, AttType, AppliedType]*): - AppliedType[ChildType, ThisType, AttType] = first.application(this, (first +: applied): _*) + def apply[AppliedType[_ <: ElementType, + _ <: ElementType, + _ <: AttributeType] <: DomNode[_, _, _]]( + first: Applicable[ChildType, AttType, AppliedType], + applied: Applicable[ChildType, AttType, AppliedType]* + ): AppliedType[ChildType, ThisType, AttType] = + first.application(this, (first +: applied): _*) } -case class ElementSeq[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType](elems: - Iterable[Element[ChildType, ThisType, AttType]]) extends ElementLike[ChildType, ThisType, AttType] - -case class EmptyElement[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType]( - tagName: String, - attributes: Map[AttributeKey[String, AttributeType], Any], - forceClosingTag: Boolean = false, - override val block: Boolean = true -) extends Element[ChildType, ThisType, AttType] { +case class ElementSeq[ + ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType]( + elems: Iterable[Element[ChildType, ThisType, AttType]]) + extends ElementLike[ChildType, ThisType, AttType] + +case class EmptyElement[ChildType <: ElementType, + ThisType <: ElementType, + AttType <: AttributeType]( + tagName: String, + attributes: Map[AttributeKey[String, AttributeType], Any], + forceClosingTag: Boolean = false, + override val block: Boolean = true +) + extends Element[ChildType, ThisType, AttType] { def children = List() - - def apply(elements: DomNode[_ <: ElementType, ChildType, _ <: AttributeType]*): AppliedElement[ChildType, ThisType, AttType] = - AppliedElement[ChildType, ThisType, AttType](tagName, attributes, elements.to[List], forceClosingTag, block) -} - -case class AppliedElement[ChildType <: ElementType, ThisType <: ElementType, AttType <: AttributeType]( - tagName: String, - attributes: Map[AttributeKey[String, AttributeType], Any] = Map(), - children: List[DomNode[_ <: ElementType, ChildType, _ <: AttributeType]] = Nil, - forceClosingTag: Boolean, - override val block: Boolean -) extends Element[ChildType, ThisType, AttType] + def apply(elements: DomNode[_ <: ElementType, ChildType, _ <: AttributeType]* + ): AppliedElement[ChildType, ThisType, AttType] = + AppliedElement[ChildType, ThisType, AttType]( + tagName, attributes, elements.to[List], forceClosingTag, block) +} -@implicitNotFound("Cannot access the attribute ${Name} on ${AttType} DOM nodes") -abstract class AttributeKey[+Name <: String, AttType <: AttributeType](val name: String, actualName: String = null) { +case class AppliedElement[ChildType <: ElementType, + ThisType <: ElementType, + AttType <: AttributeType]( + tagName: String, + attributes: Map[AttributeKey[String, AttributeType], Any] = Map(), + children: List[DomNode[_ <: ElementType, ChildType, _ <: AttributeType]] = Nil, + forceClosingTag: Boolean, + override val block: Boolean +) + extends Element[ChildType, ThisType, AttType] + +@implicitNotFound( + "Cannot access the attribute ${Name} on ${AttType} DOM nodes") +abstract class AttributeKey[+Name <: String, AttType <: AttributeType]( + val name: String, actualName: String = null) { type Value - override def toString = if(actualName == null) name else actualName + override def toString = if (actualName == null) name else actualName def serialize(t: Value): String - def set[Elem <: ElementType](v: Value) = new Attribute[Elem, AttType, Value](this.asInstanceOf[AttributeKey[String, AttributeType]], v) + def set[Elem <: ElementType](v: Value) = + new Attribute[Elem, AttType, Value]( + this.asInstanceOf[AttributeKey[String, AttributeType]], v) override def hashCode = name.hashCode override def equals(that: Any) = that match { - case ar: AttributeKey[typ, attType] => ar.name == name + case ar: AttributeKey [typ, attType] => ar.name == name case _ => false } } object Attribute { - def apply[Att <: AttributeType, V](name: String, actualName: String = null)(serializer: V => String): - AttributeKey[name.type, Att] { type Value = V } = - new AttributeKey[name.type, Att](if(actualName == null) name else actualName) { + def apply[Att <: AttributeType, V]( + name: String, actualName: String = null)(serializer: V => String + ): AttributeKey[name.type, Att] { type Value = V } = + new AttributeKey[name.type, Att]( + if (actualName == null) name else actualName) { type Value = V def serialize(v: Value): String = serializer(v) } } -class Attribute[Elem <: ElementType, AttType <: AttributeType, Value] - (val id: AttributeKey[String, AttributeType], val value: Value) extends - Applicable[Elem, AttType, EmptyElement] { - +class Attribute[Elem <: ElementType, AttType <: AttributeType, Value]( + val id: AttributeKey[String, AttributeType], val value: Value) + extends Applicable[Elem, AttType, EmptyElement] { + def name = id.name - - def application[Child <: ElementType, This <: ElementType, Att <: AttributeType] - (element: Element[Child, This, Att], applied: Applicable[Child, Att, EmptyElement]*): - EmptyElement[Child, This, Att] = { - - val as = applied.to[List].map { x => - val y = x.asInstanceOf[Attribute[ElementType, AttributeType, Any]] - y.id -> y.value.asInstanceOf[Any] - }.toMap + + def application[ + Child <: ElementType, This <: ElementType, Att <: AttributeType]( + element: Element[Child, This, Att], + applied: Applicable[Child, Att, EmptyElement]* + ): EmptyElement[Child, This, Att] = { + + val as = applied + .to[List] + .map { x => + val y = x.asInstanceOf[Attribute[ElementType, AttributeType, Any]] + y.id -> y.value.asInstanceOf[Any] + } + .toMap EmptyElement(element.tagName, as, element.forceClosingTag, element.block) } diff --git a/dom/shared/src/main/scala/rapture/dom/format.scala b/dom/shared/src/main/scala/rapture/dom/format.scala index 6210a6c..45a2fb5 100644 --- a/dom/shared/src/main/scala/rapture/dom/format.scala +++ b/dom/shared/src/main/scala/rapture/dom/format.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.dom @@ -25,31 +25,38 @@ package domFormatters { def format(element: DomNode[_, _, _]): String = element match { case TextNode(t) => text(t) - + case Comment(c) => comment(c) - - case elems: ElementSeq[_, _, _] => - elems.elems.map { elem => - + + case elems: ElementSeq [_, _, _] => + elems.elems.map { elem => val xs = elem.children.map(format).mkString - - val as = elem.tagName +: elem.attributes.to[List].filter(_._2 != null).map { case (k, v) => - k.name+"=\""+k.serialize(v.asInstanceOf[k.Value])+"\"" - } - - if(xs.isEmpty && !elem.forceClosingTag) s"<${as.mkString(" ")}/>" + + val as = + elem.tagName +: elem.attributes + .to[List] + .filter(_._2 != null) + .map { + case (k, v) => + k.name + "=\"" + k.serialize(v.asInstanceOf[k.Value]) + + "\"" + } + + if (xs.isEmpty && !elem.forceClosingTag) s"<${as.mkString(" ")}/>" else s"<${as.mkString(" ")}>$xs" - }.mkString - - case elem: Element[_, _, _] => + }.mkString + + case elem: Element [_, _, _] => val xs = elem.children.map(format).mkString - - val as = elem.tagName +: elem.attributes.to[List].filter(_._2 != null).map { case (k, v) => - k.name+"=\""+k.serialize(v.asInstanceOf[k.Value])+"\"" - } - - if(xs.isEmpty && !elem.forceClosingTag) s"<${as.mkString(" ")}/>" + + val as = + elem.tagName +: elem.attributes.to[List].filter(_._2 != null).map { + case (k, v) => + k.name + "=\"" + k.serialize(v.asInstanceOf[k.Value]) + "\"" + } + + if (xs.isEmpty && !elem.forceClosingTag) s"<${as.mkString(" ")}/>" else s"<${as.mkString(" ")}>$xs" } } @@ -57,53 +64,73 @@ package domFormatters { } object DomFormatter { - implicit val domFormatterImplicit: DomFormatter[String] = new DomFormatter[String] { - - def format(element: DomNode[_, _, _]): String = format(0, element).map { case (i, s) => - (" "*i)+s - }.mkString("\n") - - protected def format(indent: Int, element: DomNode[_, _, _]): Vector[(Int, String)] = element match { - case TextNode(t) => - Vector(indent -> text(t)) - - case Comment(c) => - Vector(indent -> comment(c)) - - case elem: Element[_, _, _] => - val children = elem.children.to[Vector] - //.asInstanceOf[Vector[DomNode[ElementType, ElementType, AttributeType]]] - val xs = children.foldLeft(Vector[(Int, String)]() -> false) { - case ((Vector(), _), child) => - (format(indent + 1, child), child.block) - case ((acc, blk), child) => - val cs = format(indent + 1, child) - val join = cs.length == 1 && !blk - if(join) (acc.init :+ ((acc.last._1, acc.last._2 + cs(0)._2)), !join) - else (acc ++ cs, !join) - }._1 - - val hasBlock = elem.children.exists(_.block) - - val as = elem.tagName +: elem.attributes.to[List].filter(_._2 != null).map { case (k, v) => - k.name+"=\""+k.serialize(v.asInstanceOf[k.Value])+"\"" + implicit val domFormatterImplicit: DomFormatter[String] = + new DomFormatter[String] { + + def format(element: DomNode[_, _, _]): String = + format(0, element).map { + case (i, s) => + (" " * i) + s + }.mkString("\n") + + protected def format( + indent: Int, element: DomNode[_, _, _]): Vector[(Int, String)] = + element match { + case TextNode(t) => + Vector(indent -> text(t)) + + case Comment(c) => + Vector(indent -> comment(c)) + + case elem: Element [_, _, _] => + val children = elem.children.to[Vector] + //.asInstanceOf[Vector[DomNode[ElementType, ElementType, AttributeType]]] + val xs = children + .foldLeft(Vector[(Int, String)]() -> false) { + case ((Vector(), _), child) => + (format(indent + 1, child), child.block) + case ((acc, blk), child) => + val cs = format(indent + 1, child) + val join = cs.length == 1 && !blk + if (join) + (acc.init :+ ((acc.last._1, acc.last._2 + cs(0)._2)), + !join) + else (acc ++ cs, !join) + } + ._1 + + val hasBlock = elem.children.exists(_.block) + + val as = + elem.tagName +: elem.attributes + .to[List] + .filter(_._2 != null) + .map { + case (k, v) => + k.name + "=\"" + k.serialize(v.asInstanceOf[k.Value]) + + "\"" + } + + if (xs.isEmpty && !elem.forceClosingTag) + Vector((indent -> s"<${as.mkString(" ")}/>")) + else if (hasBlock || elem.block) + (indent -> s"<${as.mkString(" ")}>") +: xs :+ + (indent -> s"") + else + Vector( + indent -> s"<${as.mkString(" ")}>${xs.map(_._2).mkString}") + + case elem: ElementSeq [_, _, _] => + elem.elems.to[Vector].flatMap(format(indent, _)) } - - if(xs.isEmpty && !elem.forceClosingTag) Vector((indent -> s"<${as.mkString(" ")}/>")) - else if(hasBlock || elem.block) - (indent -> s"<${as.mkString(" ")}>") +: xs :+ (indent -> s"") - else Vector(indent -> s"<${as.mkString(" ")}>${xs.map(_._2).mkString}") - - case elem: ElementSeq[_, _, _] => - elem.elems.to[Vector].flatMap(format(indent, _)) } - } } trait DomFormatter[Output] { - protected def text(string: String): String = string.replaceAll("&", "&").replaceAll("<", "<") - protected def comment(string: String) = "" - + protected def text(string: String): String = + string.replaceAll("&", "&").replaceAll("<", "<") + protected def comment(string: String) = + "" + def format(element: DomNode[_, _, _]): Output } - diff --git a/dom/shared/src/main/scala/rapture/dom/macro.scala b/dom/shared/src/main/scala/rapture/dom/macro.scala index a555795..d64dc31 100644 --- a/dom/shared/src/main/scala/rapture/dom/macro.scala +++ b/dom/shared/src/main/scala/rapture/dom/macro.scala @@ -13,59 +13,84 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.dom import rapture.base._ object DomMacros { - + // The macro is invoked primarily to provide meaningful errors - def reportElementErrorMacro[Child <: ElementType: c.WeakTypeTag, Att <: AttributeType: c.WeakTypeTag, - Child2 <: ElementType: c.WeakTypeTag, Elem <: ElementType: c.WeakTypeTag, - Att2 <: AttributeType: c.WeakTypeTag](c: WhiteboxContext)(value: c.Expr[DomNode[Child2, Elem, Att]]): c.Expr[Any] = { - //c.Expr[Applicable[Child, Att2, DomNode]] = { + def reportElementErrorMacro[Child <: ElementType : c.WeakTypeTag, + Att <: AttributeType : c.WeakTypeTag, + Child2 <: ElementType : c.WeakTypeTag, + Elem <: ElementType : c.WeakTypeTag, + Att2 <: AttributeType : c.WeakTypeTag]( + c: WhiteboxContext)( + value: c.Expr[DomNode[Child2, Elem, Att]]): c.Expr[Any] = { + //c.Expr[Applicable[Child, Att2, DomNode]] = { import c.universe._ - - if(weakTypeOf[Elem].weak_<:<(weakTypeOf[Child])) { + + if (weakTypeOf[Elem].weak_<:<(weakTypeOf[Child])) { reify { value.splice.asInstanceOf[Applicable[Child, Att2, DomNode]] } } else { - val found = weakTypeOf[Elem].toString.split(" with ").map(_.split("\\.").last).to[Vector] match { + val found = weakTypeOf[Elem].toString + .split(" with ") + .map(_.split("\\.").last) + .to[Vector] match { case Vector(one) => one - case init :+ last => init.mkString(", ")+" or "+last + case init :+ last => init.mkString(", ") + " or " + last } - val expected = weakTypeOf[Child].toString.split(" with ").map(_.split("\\.").last).to[Vector] match { + val expected = weakTypeOf[Child].toString + .split(" with ") + .map(_.split("\\.").last) + .to[Vector] match { case Vector(one) => one - case init :+ last => init.mkString(", ")+" or "+last + case init :+ last => init.mkString(", ") + " or " + last } - - c.abort(c.enclosingPosition, s"Attempted to nest a $found node in a position where only $expected nodes are "+ + + c.abort( + c.enclosingPosition, + s"Attempted to nest a $found node in a position where only $expected nodes are " + "permitted") } } - - def reportElementError2Macro[Child <: ElementType: c.WeakTypeTag, Att <: AttributeType: c.WeakTypeTag, - Child2 <: ElementType: c.WeakTypeTag, Elem <: ElementType: c.WeakTypeTag] - (c: WhiteboxContext)(value: c.Expr[DomNode[Child2, Elem, Att]]): - c.Expr[Element[_, Child, _]] = { + + def reportElementError2Macro[Child <: ElementType : c.WeakTypeTag, + Att <: AttributeType : c.WeakTypeTag, + Child2 <: ElementType : c.WeakTypeTag, + Elem <: ElementType : c.WeakTypeTag]( + c: WhiteboxContext)(value: c.Expr[DomNode[Child2, Elem, Att]] + ): c.Expr[Element[_, Child, _]] = { import c.universe._ - - if(weakTypeOf[Elem].weak_<:<(weakTypeOf[Child])) { - reify { value.splice.asInstanceOf[Element[_ <: ElementType, Child, _ <: AttributeType]] } + + if (weakTypeOf[Elem].weak_<:<(weakTypeOf[Child])) { + reify { + value.splice + .asInstanceOf[Element[_ <: ElementType, Child, _ <: AttributeType]] + } } else { - val found = weakTypeOf[Elem].toString.split(" with ").map(_.split("\\.").last).to[Vector] match { + val found = weakTypeOf[Elem].toString + .split(" with ") + .map(_.split("\\.").last) + .to[Vector] match { case Vector(one) => one - case init :+ last => init.mkString(", ")+" or "+last + case init :+ last => init.mkString(", ") + " or " + last } - val expected = weakTypeOf[Child].toString.split(" with ").map(_.split("\\.").last).to[Vector] match { + val expected = weakTypeOf[Child].toString + .split(" with ") + .map(_.split("\\.").last) + .to[Vector] match { case Vector(one) => one - case init :+ last => init.mkString(", ")+" or "+last + case init :+ last => init.mkString(", ") + " or " + last } - - c.abort(c.enclosingPosition, s"Attempted to nest a $found node in a position where only $expected nodes are "+ + + c.abort( + c.enclosingPosition, + s"Attempted to nest a $found node in a position where only $expected nodes are " + "permitted") } } diff --git a/fs/shared/src/main/scala/rapture/fs/files.scala b/fs/shared/src/main/scala/rapture/fs/files.scala index b0dad28..fc2eae4 100644 --- a/fs/shared/src/main/scala/rapture/fs/files.scala +++ b/fs/shared/src/main/scala/rapture/fs/files.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.fs @@ -33,7 +33,7 @@ trait LowerPriorityImplicits { /** Type class object for writing `FsUrl`s as `Output[Stream]`s */ implicit object FileStreamCharWriter extends Writer[FsUrl, Char] { def output(url: FsUrl): Output[Char] = - new CharOutput(new BufferedWriter(new FileWriter(url.javaFile))) + new CharOutput(new BufferedWriter(new FileWriter(url.javaFile))) } implicit object FileStreamCharAppender extends Appender[FsUrl, Char] { @@ -42,26 +42,31 @@ trait LowerPriorityImplicits { } implicit val fileSizable: Sizable[FsUrl, Byte] = new Sizable[FsUrl, Byte] { + /** Returns the size of the file in bytes. */ def size(file: FsUrl): Long = file.length(modes.throwExceptions()) } - + implicit val fileDeletable: Deleter[FsUrl] = new Deleter[FsUrl] { + /** Returns the size of the file in bytes. */ def delete(file: FsUrl): Unit = file.javaFile.delete() } } trait LowPriorityImplicits extends LowerPriorityImplicits { + /** Type class object for writing `Byte`s to `FsUrl`s */ implicit object FileStreamByteWriter extends Writer[FsUrl, Byte] { def output(url: FsUrl): Output[Byte] = - new ByteOutput(new BufferedOutputStream(new FileOutputStream(url.javaFile))) + new ByteOutput( + new BufferedOutputStream(new FileOutputStream(url.javaFile))) } implicit object FileStreamByteAppender extends Appender[FsUrl, Byte] { def appendOutput(url: FsUrl): Output[Byte] = - new ByteOutput(new BufferedOutputStream(new FileOutputStream(url.javaFile, true))) + new ByteOutput( + new BufferedOutputStream(new FileOutputStream(url.javaFile, true))) } implicit val fileMovable: Movable[FsUrl, FsUrl] = new Movable[FsUrl, FsUrl] { @@ -102,14 +107,14 @@ trait LowPriorityImplicits extends LowerPriorityImplicits { } /** Moves this file to a new location specified by the dest parameter. This will first attempt - * to move the file by renaming it, but will attempt copying and deletion if renaming fails. */ + * to move the file by renaming it, but will attempt copying and deletion if renaming fails. */ def moveTo(dest: FsUrl)(implicit sr: Reader[FsUrl, Byte], mode: Mode[FsMethods]): mode.Wrap[Boolean, Exception] = mode.wrap(renameTo(dest) || (copyTo(dest)(sr, raw) > 0) && delete()(raw)) /** Deletes the file represented by this FsUrl. If the recursive flag is set and the - * filesystem object is a directory, all subfolders and their contents will also be - * deleted. */ + * filesystem object is a directory, all subfolders and their contents will also be + * deleted. */ def delete(recursive: Boolean = false)(implicit mode: Mode[FsMethods]): mode.Wrap[Boolean, Exception] = mode.wrap(if(recursive) deleteRecursively(f) else f.javaFile.delete()) @@ -124,32 +129,45 @@ trait LowPriorityImplicits extends LowerPriorityImplicits { /** Specifies how file: URLs should be navigable. */ implicit object NavigableFile extends Navigable[FsUrl] { - def children(url: FsUrl)(implicit mode: Mode[`Navigable#children`]): mode.Wrap[List[FsUrl], Exception] = - mode.wrap { if(url.isFile) Nil else url.javaFile.list().to[List].map(url / _) } - - def isDirectory(url: FsUrl)(implicit mode: Mode[`Navigable#isDirectory`]): mode.Wrap[Boolean, Exception] = + def children(url: FsUrl)(implicit mode: Mode[`Navigable#children`] + ): mode.Wrap[List[FsUrl], Exception] = + mode.wrap { + if (url.isFile) Nil else url.javaFile.list().to[List].map(url / _) + } + + def isDirectory(url: FsUrl)(implicit mode: Mode[`Navigable#isDirectory`] + ): mode.Wrap[Boolean, Exception] = mode.wrap { url.javaFile.isDirectory() } } - } object `package` extends LowPriorityImplicits { + /** Type class object for reading `Byte`s from `FsUrl`s */ - implicit object FileStreamByteReader extends JavaInputStreamReader[FsUrl](f => - new FileInputStream(f.javaFile)) + implicit object FileStreamByteReader + extends JavaInputStreamReader[FsUrl]( + f => new FileInputStream(f.javaFile)) implicit class EnrichedFileUriContext(uc: UriContext.type) { def file(constants: List[String])(variables: List[String]) = { - val fileUrl = constants.zip(variables :+ "").map { case (a, b) => a+b }.mkString.split("/").filter(_ != "").to[Vector] + val fileUrl = constants + .zip(variables :+ "") + .map { case (a, b) => a + b } + .mkString + .split("/") + .filter(_ != "") + .to[Vector] FsUrl(fileUrl) } } } object FsUrl { - implicit val fileCpUrl: ClasspathUrlable[FsUrl] = new ClasspathUrlable[FsUrl] { - def toClasspathUrlItem(f: FsUrl) = ClasspathUrlItem(List(new java.net.URL(f.toString))) - } + implicit val fileCpUrl: ClasspathUrlable[FsUrl] = + new ClasspathUrlable[FsUrl] { + def toClasspathUrlItem(f: FsUrl) = + ClasspathUrlItem(List(new java.net.URL(f.toString))) + } implicit def uriCapable: UriCapable[FsUrl] = new UriCapable[FsUrl] { def uri(f: FsUrl): Uri = @@ -159,27 +177,35 @@ object FsUrl { implicit def fileSlashString: Dereferenceable[FsUrl, String, FsUrl] = new Dereferenceable[FsUrl, String, FsUrl] { def dereference(p1: FsUrl, p2: String) = { - val start = if(p1.elements.lastOption == Some("")) p1.elements.init else p1.elements - FsUrl(start :+ p2) + val start = + if (p1.elements.lastOption == Some("")) p1.elements.init + else p1.elements + FsUrl(start :+ p2) } } - implicit def fileSlashRelativePath[RP <: RelativePath]: Dereferenceable[FsUrl, RP, FsUrl] = + implicit def fileSlashRelativePath[RP <: RelativePath]: Dereferenceable[ + FsUrl, RP, FsUrl] = new Dereferenceable[FsUrl, RP, FsUrl] { - def dereference(p1: FsUrl, p2: RP) = FsUrl(p1.elements.dropRight(p2.ascent) ++ p2.elements) + def dereference(p1: FsUrl, p2: RP) = + FsUrl(p1.elements.dropRight(p2.ascent) ++ p2.elements) } - - implicit def fileSlashRootedPath[RP <: RootedPath]: Dereferenceable[FsUrl, RP, FsUrl] = + + implicit def fileSlashRootedPath[RP <: RootedPath]: Dereferenceable[ + FsUrl, RP, FsUrl] = new Dereferenceable[FsUrl, RP, FsUrl] { def dereference(p1: FsUrl, p2: RP) = { - val start = if(p1.elements.lastOption == Some("")) p1.elements.init else p1.elements + val start = + if (p1.elements.lastOption == Some("")) p1.elements.init + else p1.elements FsUrl(start ++ p2.elements) } } - implicit def fileParentable: Parentable[FsUrl, FsUrl] = new Parentable[FsUrl, FsUrl] { - def parent(fsUrl: FsUrl): FsUrl = FsUrl(fsUrl.elements.dropRight(1)) - } + implicit def fileParentable: Parentable[FsUrl, FsUrl] = + new Parentable[FsUrl, FsUrl] { + def parent(fsUrl: FsUrl): FsUrl = FsUrl(fsUrl.elements.dropRight(1)) + } } /** Defines a URL for the file: scheme, and provides standard filesystem operations on the file @@ -189,55 +215,61 @@ case class FsUrl(val elements: Seq[String]) { override def toString = s"file:///${elements.mkString("/")}" /** The java.io.File corresponding to this FsUrl. */ - lazy val javaFile: java.io.File = new java.io.File(this.uri.schemeSpecificPart.drop(2)) - + lazy val javaFile: java.io.File = + new java.io.File(this.uri.schemeSpecificPart.drop(2)) + /** Returns true if the file or directory represented by this FsUrl can be read from. */ def readable: Boolean = javaFile.canRead() - + /** Returns true if the file or directory represented by this FsUrl can be written to. */ def writable: Boolean = javaFile.canWrite() - + /** Add a hook to the filesystem to delete this file upon shutdown of the JVM. */ def deleteOnExit(): Unit = javaFile.deleteOnExit() - + /** Returns true if this object exists on the filesystem. */ def exists: Boolean = javaFile.exists() - + /** Returns the filename of this filesystem object. */ def filename: String = javaFile.getName() - + /** Returns true if the filesystem object represented by this FsUrl is a file, and false if * it is a directory. */ def isFile: Boolean = javaFile.isFile() - + /** Returns true if the file or directory is hidden. */ - def hidden: Boolean = if(exists) javaFile.isHidden() else throw new Exception() - + def hidden: Boolean = + if (exists) javaFile.isHidden() else throw new Exception() + /** Returns the date of the last modification to the file or directory. */ - def lastModified[I: TimeSystem.ByInstant](implicit mode: Mode[FsMethods]): - mode.Wrap[I, Exception] = - mode.wrap(javaFile.lastModified() match { - case 0L => throw new Exception() - case d => ?[TimeSystem.ByInstant[I]].instant(d) - }) - + def lastModified[I : TimeSystem.ByInstant]( + implicit mode: Mode[FsMethods]): mode.Wrap[I, Exception] = + mode.wrap( + javaFile.lastModified() match { + case 0L => throw new Exception() + case d => ?[TimeSystem.ByInstant[I]].instant(d) + }) + /** Returns the size of the file in bytes. */ def length(implicit mode: Mode[FsMethods]): mode.Wrap[Long, Exception] = - mode.wrap(javaFile.length() match { + mode.wrap( + javaFile.length() match { case 0L if !exists => throw new Exception() case x => x }) - + /** If the filesystem object represented by this FsUrl does not exist, it is created as a * directory, provided that either the immediate parent directory already exists, or the * makeParents path is set. */ - def mkdir(makeParents: Boolean = false)(implicit mode: Mode[FsMethods]): - mode.Wrap[Boolean, Exception] = mode.wrap(if(makeParents) javaFile.mkdirs() else - javaFile.mkdir()) - + def mkdir(makeParents: Boolean = false)( + implicit mode: Mode[FsMethods]): mode.Wrap[Boolean, Exception] = + mode.wrap(if (makeParents) javaFile.mkdirs() else javaFile.mkdir()) + /** Extract the file extension from the name of this file. */ - def extension(implicit mode: Mode[FsMethods]): mode.Wrap[Option[String], Exception] = - mode.wrap(if(filename contains ".") Some(filename.split("\\.").last) else None) + def extension( + implicit mode: Mode[FsMethods]): mode.Wrap[Option[String], Exception] = + mode.wrap( + if (filename contains ".") Some(filename.split("\\.").last) else None) } /** The file scheme object used as a factory for FsUrls. */ @@ -253,4 +285,3 @@ object File extends FsUrl(Vector()) { def homeDir = File.parse(System.getenv("HOME")) } - diff --git a/google-translate/shared/src/main/scala/rapture/google-translate/package.scala b/google-translate/shared/src/main/scala/rapture/google-translate/package.scala index 32c2c0d..e9d7782 100644 --- a/google-translate/shared/src/main/scala/rapture/google-translate/package.scala +++ b/google-translate/shared/src/main/scala/rapture/google-translate/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.i18n.googleTranslate @@ -36,20 +36,26 @@ class NotString[S <: String] class GoogleApiKey[S <: String](key: S)(implicit notString: NotString[S]) object GoogleApiKey { - def apply[S <: String](key: S)(implicit notString: NotString[key.type]): GoogleApiKey[key.type] = + def apply[S <: String](key: S)( + implicit notString: NotString[key.type]): GoogleApiKey[key.type] = new GoogleApiKey[key.type](key)(notString) } object `package` { - implicit def upcast[ToLang <: Language, FromLang <: Language, S <: String](from: I18n[String, FromLang])(implicit license: GoogleApiKey[S]): I18n[String, ToLang] = - macro Macros.missingTranslationsMacro[ToLang, FromLang, S] + implicit def upcast[ToLang <: Language, FromLang <: Language, S <: String]( + from: I18n[String, FromLang])( + implicit license: GoogleApiKey[S]): I18n[String, ToLang] = macro Macros + .missingTranslationsMacro[ToLang, FromLang, S] } object Macros { - - def missingTranslationsMacro[ToLang <: Language: c.WeakTypeTag, FromLang <: Language: c.WeakTypeTag, S <: String: c.WeakTypeTag](c: - BlackboxContext)(from: c.Expr[I18n[String, FromLang]])(license: c.Expr[GoogleApiKey[S]]): c.Expr[I18n[String, ToLang]] = { - + + def missingTranslationsMacro[ToLang <: Language : c.WeakTypeTag, + FromLang <: Language : c.WeakTypeTag, + S <: String : c.WeakTypeTag]( + c: BlackboxContext)(from: c.Expr[I18n[String, FromLang]])( + license: c.Expr[GoogleApiKey[S]]): c.Expr[I18n[String, ToLang]] = { + import c.universe._ import compatibility._ @@ -69,31 +75,42 @@ object Macros { val missing = toLangs -- fromLangs def langs(tree: Tree): Map[String, String] = tree match { - case Apply(Select(Apply(Select(Select(Select(id1, id2), id3), id4), List(Apply(_, List(Literal(Constant( - str: String)))))), lang), _) if id1.toString == "rapture" && id2.toString == "i18n" && - id3.toString == "package" && id4.toString == "I18nEnrichedStringContext" => - + case Apply( + Select(Apply(Select(Select(Select(id1, id2), id3), id4), + List(Apply(_, List(Literal(Constant(str: String)))))), + lang), + _) + if id1.toString == "rapture" && id2.toString == "i18n" && + id3.toString == "package" && + id4.toString == "I18nEnrichedStringContext" => Map(lang.toString -> str) - + case Apply(app: Apply, _) => langs(app) - - case Apply(TypeApply(Select(q, id6), _), List(app)) if id6.toString == "$bar" => + + case Apply(TypeApply(Select(q, id6), _), List(app)) + if id6.toString == "$bar" => langs(q) ++ langs(app) } val ls = langs(from.tree) - val extras = ls.find(_._1 == "en").orElse(ls.find(_._1 == "fr")).getOrElse(ls.head) match { + val extras = ls + .find(_._1 == "en") + .orElse(ls.find(_._1 == "fr")) + .getOrElse(ls.head) match { case (lang, text) => missing.map { to => - val tran = GoogleTranslate.translate(key, text, lang.toUpperCase, to.toUpperCase).replaceAll("\"", "\\\\\"") - s"""${to.toLowerCase}"${tran}"""" + val tran = GoogleTranslate + .translate(key, text, lang.toUpperCase, to.toUpperCase) + .replaceAll("\"", "\\\\\"") + s"""${to.toLowerCase}"${tran}"""" } } - c.abort(c.enclosingPosition, s"""Not all required language translations have been provided. Consider appending the following translations to the expression:\n\n ${extras.mkString("& ", " & ", "")}\n""") - - + c.abort( + c.enclosingPosition, + s"""Not all required language translations have been provided. Consider appending the following translations to the expression:\n\n ${extras + .mkString("& ", " & ", "")}\n""") } } @@ -105,7 +122,13 @@ object GoogleTranslate { import rapture.json._, jsonBackends.jawn._ def translate(key: String, text: String, from: String, to: String): String = { - val out = uri"https://www.googleapis.com/language/translate/v2".query(Map("q" -> text, "target" -> to, "format" -> "text", "source" -> from, "key" -> key)).slurp[Char] + val out = uri"https://www.googleapis.com/language/translate/v2" + .query(Map("q" -> text, + "target" -> to, + "format" -> "text", + "source" -> from, + "key" -> key)) + .slurp[Char] Json.parse(out).data.translations(0).translatedText.as[String] } } diff --git a/html/shared/src/main/scala/rapture/html/doc.scala b/html/shared/src/main/scala/rapture/html/doc.scala index 1ffcfaa..ce82e29 100644 --- a/html/shared/src/main/scala/rapture/html/doc.scala +++ b/html/shared/src/main/scala/rapture/html/doc.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.html diff --git a/html/shared/src/main/scala/rapture/html/phantom.scala b/html/shared/src/main/scala/rapture/html/phantom.scala index e23ee18..2181cb5 100644 --- a/html/shared/src/main/scala/rapture/html/phantom.scala +++ b/html/shared/src/main/scala/rapture/html/phantom.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.html @@ -66,12 +66,16 @@ object Html5 { trait Bb extends AttributeType trait Menu extends AttributeType - trait Global extends Html with Base with Link with Meta with Style with Script with Body with Blockquote with Ol - with Li with A with Q with Time with Progress with Meter with Bdo with Edit with Img with Iframe with Embed - with Object with Param with Video with Audio with Source with Canvas with Map with Area with Col with Td with - Th with Form with Fieldset with Label with Input with Button with Select with Optgroup with Option with - Textarea with Output with Details with Command with Bb with Menu - + trait Global + extends Html with Base with Link with Meta with Style with Script + with Body with Blockquote with Ol with Li with A with Q with Time + with Progress with Meter with Bdo with Edit with Img with Iframe + with Embed with Object with Param with Video with Audio with Source + with Canvas with Map with Area with Col with Td with Th with Form + with Fieldset with Label with Input with Button with Select with Optgroup + with Option with Textarea with Output with Details with Command with Bb + with Menu + trait Flow extends ElementType trait Metadata extends ElementType trait Top extends ElementType @@ -79,7 +83,7 @@ object Html5 { trait ListItems extends ElementType trait TableItems extends ElementType trait ColItems extends ElementType - trait TrItems extends ElementType + trait TrItems extends ElementType trait TdItems extends ElementType trait OptionItems extends ElementType trait Sectioning extends Flow @@ -89,4 +93,3 @@ object Html5 { trait Embedded extends Phrasing trait Text extends Phrasing } - diff --git a/html/shared/src/main/scala/rapture/html/syntax.scala b/html/shared/src/main/scala/rapture/html/syntax.scala index cc2aab8..c13ee55 100644 --- a/html/shared/src/main/scala/rapture/html/syntax.scala +++ b/html/shared/src/main/scala/rapture/html/syntax.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.html @@ -31,23 +31,26 @@ object htmlSyntax { import Html5._ - implicit def stringToTextNode(str: String): - TextNode[Nothing, Nothing, Html5.Text] = + implicit def stringToTextNode( + str: String): TextNode[Nothing, Nothing, Html5.Text] = TextNode[Nothing, Nothing, Html5.Text](str) type HtmlRoot = Element[Top, ElementType, Html] - - type HtmlElement[T <: ElementType] = Element[_ <: ElementType, _ <: T, _ <: AttributeType] + + type HtmlElement[T <: ElementType] = Element[ + _ <: ElementType, _ <: T, _ <: AttributeType] // FIXME: These tag types are not currently working def A[T <: ElementType] = Tag[T, T, A](block = false)(new AssignedName("A")) def Ins[T <: ElementType] = Tag[T, T, Edit]()(new AssignedName("Ins")) def Del[T <: ElementType] = Tag[T, T, Edit]()(new AssignedName("Del")) def Object[T <: Embedded] = Tag[T, T, Object]()(new AssignedName("Object")) - def Video[T <: Embedded with Interactive] = Tag[T, T, Video]()(new AssignedName("Video")) - def Audio[T <: Embedded with Interactive] = Tag[T, T, Audio]()(new AssignedName("Audio")) + def Video[T <: Embedded with Interactive] = + Tag[T, T, Video]()(new AssignedName("Video")) + def Audio[T <: Embedded with Interactive] = + Tag[T, T, Audio]()(new AssignedName("Audio")) def Canvas[T <: Embedded] = Tag[T, T, Canvas]()(new AssignedName("Canvas")) - + val Html = Tag[Top, ElementType, Html]() val Head = Tag[Metadata, Top, Nothing]() val Title = Tag[Text, Metadata, Global]() @@ -55,7 +58,8 @@ object htmlSyntax { val Link = Tag[Nothing, Metadata, Link]() val Meta = Tag[Metadata, Metadata, Meta]() val Style = Tag[Text, Metadata with Flow, AttributeType](block = true) - val Script = Tag[Text, Metadata with Phrasing, Script](forceClosingTag = true, block = true) + val Script = Tag[Text, Metadata with Phrasing, Script]( + forceClosingTag = true, block = true) val Noscript = Tag[Text, Metadata with Phrasing, AttributeType]() val Body = Tag[Flow, Top, Body]() val Section = Tag[Flow, Sectioning, AttributeType]() @@ -133,7 +137,8 @@ object htmlSyntax { val Datalist = Tag[OptionItems, Phrasing with Interactive, AttributeType]() val Optgroup = Tag[OptionItems, Phrasing, Optgroup]() val Option = Tag[Text, OptionItems, Option]() - val Textarea = Tag[Text, Phrasing with Interactive, Textarea](forceClosingTag = true) + val Textarea = + Tag[Text, Phrasing with Interactive, Textarea](forceClosingTag = true) val Output = Tag[Phrasing, Phrasing, Output]() val Details = Tag[Flow, Interactive, Details]() val Command = Tag[Nothing, Metadata with Phrasing, Command]() @@ -144,97 +149,115 @@ object htmlSyntax { object Data extends Dynamic { def selectDynamic(att: String) = Attribute[Global, String](att)(identity) - def updateDynamic[E <: ElementType](att: String)(v: String) = selectDynamic(att).set[E](v) + def updateDynamic[E <: ElementType](att: String)(v: String) = + selectDynamic(att).set[E](v) } implicit def id = Attribute[Global, Symbol]("id")(_.name) def id_=[E <: ElementType](v: Symbol) = id.set[E](v) - + implicit def lang = Attribute[Global, Symbol]("lang")(_.name) def lang_=[E <: ElementType](v: Symbol) = lang.set[E](v) - - implicit def translate = Attribute[Global, Boolean]("translate")(v => if(v) "yes" else "no") + + implicit def translate = + Attribute[Global, Boolean]("translate")(v => if (v) "yes" else "no") def translate_=[E <: ElementType](v: Boolean) = translate.set[E](v) - - implicit def classes = Attribute[Global, Seq[String]]("classes", "class")(_.mkString(" ")) + + implicit def classes = + Attribute[Global, Seq[String]]("classes", "class")(_.mkString(" ")) def classes_=[E <: ElementType](v: Seq[String]) = classes.set[E](v) - + implicit def onload = Attribute[Body, Js]("onload")(_.content) def onload_=[E <: ElementType](v: Js) = onload.set[E](v) - + implicit def onclick = Attribute[Global, Js]("onclick")(_.content) def onclick_=[E <: ElementType](v: Js) = onclick.set[E](v) - + implicit def title = Attribute[Global, String]("title")(identity) def title_=[E <: ElementType](v: String) = title.set[E](v) - - implicit def alt = Attribute[Img with Area with Input, String]("alt")(identity) + + implicit def alt = + Attribute[Img with Area with Input, String]("alt")(identity) def alt_=[E <: ElementType](v: String) = alt.set[E](v) - - implicit def href = Attribute[Base with Link with A with Area, PathLink]("href")(_.link) - def href_=[E <: ElementType, L: Linkable](v: L) = href.set[E](implicitly[Linkable[L]].link(v)) - - implicit def name = Attribute[Meta with Iframe with Object with Param with Map with Form with Fieldset - with Input with Button with Select with Textarea with Output, Symbol]("name")(_.name) + + implicit def href = + Attribute[Base with Link with A with Area, PathLink]("href")(_.link) + def href_=[E <: ElementType, L : Linkable](v: L) = + href.set[E](implicitly[Linkable[L]].link(v)) + + implicit def name = + Attribute[ + Meta with Iframe with Object with Param with Map with Form with Fieldset with Input with Button with Select with Textarea with Output, + Symbol]("name")(_.name) def name_=[E <: ElementType](v: Symbol) = name.set[E](v) - implicit def selected = Attribute[Option, Boolean]("selected") { v => if(v) "selected" else null } + implicit def selected = Attribute[Option, Boolean]("selected") { v => + if (v) "selected" else null + } def selected_=[E <: ElementType](v: Boolean) = selected.set[E](v) - + implicit def cols = Attribute[Textarea, Int]("cols")(_.toString) def cols_=[E <: ElementType](v: Int) = cols.set[E](v) - + implicit def rows = Attribute[Textarea, Int]("rows")(_.toString) def rows_=[E <: ElementType](v: Int) = rows.set[E](v) - + implicit def colspan = Attribute[Td with Th, Int]("colspan")(_.toString) def colspan_=[E <: ElementType](v: Int) = colspan.set[E](v) - + implicit def rowspan = Attribute[Td with Th, Int]("rowspan")(_.toString) def rowspan_=[E <: ElementType](v: Int) = rowspan.set[E](v) - - implicit def wrap = Attribute[Textarea, Boolean]("wrap") { v => if(v) "wrap" else null } + + implicit def wrap = Attribute[Textarea, Boolean]("wrap") { v => + if (v) "wrap" else null + } def wrap_=[E <: ElementType](v: Boolean) = wrap.set[E](v) - - implicit def open = Attribute[Details, Boolean]("open") { v => if(v) "open" else null } + + implicit def open = Attribute[Details, Boolean]("open") { v => + if (v) "open" else null + } def open_=[E <: ElementType](v: Boolean) = open.set[E](v) - - implicit def max = Attribute[Progress with Meter with Input, Double]("max")(_.toString) + + implicit def max = + Attribute[Progress with Meter with Input, Double]("max")(_.toString) def max_=[E <: ElementType](v: Double) = max.set[E](v) - + implicit def min = Attribute[Meter with Input, Double]("min")(_.toString) def min_=[E <: ElementType](v: Double) = min.set[E](v) - + implicit def low = Attribute[Meter, Double]("low")(_.toString) def low_=[E <: ElementType](v: Double) = low.set[E](v) - + implicit def high = Attribute[Meter, Double]("high")(_.toString) def high_=[E <: ElementType](v: Double) = high.set[E](v) - + implicit def optimum = Attribute[Meter, Double]("optimum")(_.toString) def optimum_=[E <: ElementType](v: Double) = optimum.set[E](v) - + implicit def span = Attribute[Col, Int]("span")(_.toString) def span_=[E <: ElementType](v: Int) = span.set[E](v) - + class HttpEquiv(val name: String) case object contentType extends HttpEquiv("content-type") case object defaultStyle extends HttpEquiv("default-style") case object refresh extends HttpEquiv("refresh") - implicit def httpEquiv = Attribute[Meta, HttpEquiv]("httpEquiv", "http-equiv")(_.name) + implicit def httpEquiv = + Attribute[Meta, HttpEquiv]("httpEquiv", "http-equiv")(_.name) def httpEquiv_=[E <: ElementType](v: HttpEquiv) = httpEquiv.set[E](v) - - implicit def charset = Attribute[Meta with Script, Encoding]("charset")(_.name) + + implicit def charset = + Attribute[Meta with Script, Encoding]("charset")(_.name) def charset_=[E <: ElementType](v: Encoding) = charset.set[E](v) - + implicit def content = Attribute[Meta, String]("content")(identity) def content_=[E <: ElementType](v: String) = content.set[E](v) - + implicit def manifest = Attribute[Html, HttpUrl]("manifest")(_.toString) def manifest_=[E <: ElementType](v: HttpUrl) = manifest.set[E](v) implicit def target = - Attribute[Base with Link with A with Area with Form with Input with Button, Symbol]("target")(_.name) + Attribute[Base with Link with A with Area with Form with Input with Button, + Symbol]("target")(_.name) def target_=[E <: ElementType](v: Symbol) = target.set[E](v) sealed class Rel(val name: String) @@ -253,11 +276,15 @@ object htmlSyntax { case object tag extends Rel("tag") implicit def rel = Attribute[Link with A with Area, Rel]("rel")(_.name) def rel_=[E <: ElementType](v: Rel) = rel.set[E](v) - + // FIXME: Provide &, | and ! operators to write media expressions, and implement all values trait MediaExpr - sealed class Media(val name: String) extends MediaExpr { override def toString = name } - sealed class Device(val name: String) extends MediaExpr { override def toString = name } + sealed class Media(val name: String) extends MediaExpr { + override def toString = name + } + sealed class Device(val name: String) extends MediaExpr { + override def toString = name + } case object all extends Device("all") case object aural extends Device("aural") case object braille extends Device("braille") @@ -267,57 +294,73 @@ object htmlSyntax { case object screen extends Device("screen") case object tty extends Device("tty") case object tv extends Device("tv") - implicit def media = Attribute[Link with Style with A with Source with Area, MediaExpr]("media")(_.toString) + implicit def media = + Attribute[Link with Style with A with Source with Area, MediaExpr]( + "media")(_.toString) def media_=[E <: ElementType](v: MediaExpr) = media.set[E](v) implicit def style = Attribute[Global, Css]("style")(_.content) def style_=[E <: ElementType](v: Css) = style.set[E](v) + implicit def src = + Attribute[Script with Img with Iframe with Embed with Video with Audio with Source with Input, + PathLink]("src")(_.toString) + def src_=[E <: ElementType, L : Linkable](v: L) = + src.set[E](implicitly[Linkable[L]].link(v)) - implicit def src = Attribute[Script with Img with Iframe with Embed with Video with Audio with Source with Input, - PathLink]("src")(_.toString) - def src_=[E <: ElementType, L: Linkable](v: L) = src.set[E](implicitly[Linkable[L]].link(v)) - - implicit def value = Attribute[Li with Progress with Meter with Param with Input with Button with Option, String]( - "value")(identity) + implicit def value = + Attribute[ + Li with Progress with Meter with Param with Input with Button with Option, + String]("value")(identity) def value_=[E <: ElementType](v: String) = value.set[E](v) - - - implicit def typ = Attribute[Link with Style with Script with A with Embed with Object with Source with Area with - Input with Button with Command with Bb with Menu, String]("typ", "type")(identity) + + implicit def typ = + Attribute[ + Link with Style with Script with A with Embed with Object with Source with Area with Input with Button with Command with Bb with Menu, + String]("typ", "type")(identity) def typ_=[E <: ElementType](v: String) = typ.set[E](v) - implicit def action = Attribute[Form with Input with Button, PathLink]("action")(_.link) - def action_=[E <: ElementType, L: Linkable](v: L) = action.set(implicitly[Linkable[L]].link(v)) - - implicit def method = Attribute[Form with Input with Button, String]("method")(identity) + implicit def action = + Attribute[Form with Input with Button, PathLink]("action")(_.link) + def action_=[E <: ElementType, L : Linkable](v: L) = + action.set(implicitly[Linkable[L]].link(v)) + + implicit def method = + Attribute[Form with Input with Button, String]("method")(identity) def method_=[E <: ElementType](v: String) = method.set(v) - - implicit def enctype = Attribute[Form with Input with Button, String]("enctype")(identity) + + implicit def enctype = + Attribute[Form with Input with Button, String]("enctype")(identity) def enctype_=[E <: ElementType](v: String) = enctype.set(v) - - implicit def checked = Attribute[Input, Boolean]("checked")(v => if(v) "checked" else null) + + implicit def checked = + Attribute[Input, Boolean]("checked")(v => if (v) "checked" else null) def checked_=[E <: ElementType](v: Boolean) = checked.set(v) - - implicit def maxlength = Attribute[Input with Textarea, Int]("maxlength")(_.toString) + + implicit def maxlength = + Attribute[Input with Textarea, Int]("maxlength")(_.toString) def maxlength_=[E <: ElementType](v: Int) = maxlength.set(v) - + implicit def hreflang = Attribute[Link, Symbol]("hreflang")(_.name) def hreflang_=[E <: ElementType](v: Symbol) = hreflang.set(v) implicit def sizes = Attribute[Link, String]("sizes")(identity) def sizes_=[E <: ElementType](v: String) = sizes.set(v) - implicit def scoped = Attribute[Style, Boolean]("scoped")(v => if(v) "scoped" else null) + implicit def scoped = + Attribute[Style, Boolean]("scoped")(v => if (v) "scoped" else null) def scoped_=[E <: ElementType](v: Boolean) = scoped.set(v) - implicit def async = Attribute[Script, Boolean]("async")(v => if(v) "async" else null) + implicit def async = + Attribute[Script, Boolean]("async")(v => if (v) "async" else null) def async_=[E <: ElementType](v: Boolean) = async.set(v) - implicit def defer = Attribute[Script, Boolean]("defer")(v => if(v) "defer" else null) + implicit def defer = + Attribute[Script, Boolean]("defer")(v => if (v) "defer" else null) def defer_=[E <: ElementType](v: Boolean) = defer.set(v) - implicit def onbeforeunload = Attribute[Body, Js]("onbeforeunload")(_.content) + implicit def onbeforeunload = + Attribute[Body, Js]("onbeforeunload")(_.content) def onbeforeunload_=[E <: ElementType](v: Js) = onbeforeunload.set(v) implicit def onerror = Attribute[Body, Js]("onerror")(_.content) @@ -344,19 +387,24 @@ object htmlSyntax { implicit def onunload = Attribute[Body, Js]("onunload")(_.content) def onunload_=[E <: ElementType](v: Js) = onunload.set(v) - implicit def reversed = Attribute[Ol, Boolean]("reversed")(v => if(v) "reversed" else null) + implicit def reversed = + Attribute[Ol, Boolean]("reversed")(v => if (v) "reversed" else null) def reversed_=[E <: ElementType](v: Boolean) = reversed.set(v) implicit def start = Attribute[Ol, Int]("start")(_.toString) def start_=[E <: ElementType](v: Int) = start.set(v) implicit def ping = Attribute[Link with Area, PathLink]("ping")(_.link) - def ping_=[E <: ElementType, L: Linkable](v: L) = ping.set(implicitly[Linkable[L]].link(v)) + def ping_=[E <: ElementType, L : Linkable](v: L) = + ping.set(implicitly[Linkable[L]].link(v)) - implicit def cite = Attribute[Blockquote with Q with Edit, PathLink]("cite")(_.link) - def cite_=[E <: ElementType, L: Linkable](v: L) = cite.set(implicitly[Linkable[L]].link(v)) + implicit def cite = + Attribute[Blockquote with Q with Edit, PathLink]("cite")(_.link) + def cite_=[E <: ElementType, L : Linkable](v: L) = + cite.set(implicitly[Linkable[L]].link(v)) - implicit def datetime = Attribute[Time with Edit, String]("datetime")(identity) + implicit def datetime = + Attribute[Time with Edit, String]("datetime")(identity) def datetime_=[E <: ElementType](v: String) = datetime.set(v) implicit def dir = Attribute[Global, Symbol]("dir")(_.name) @@ -365,37 +413,54 @@ object htmlSyntax { implicit def usemap = Attribute[Img with Object, String]("usemap")(identity) def usemap_=[E <: ElementType](v: String) = usemap.set(v) - implicit def ismap = Attribute[Img, Boolean]("ismap")(v => if(v) "ismap" else null) + implicit def ismap = + Attribute[Img, Boolean]("ismap")(v => if (v) "ismap" else null) def ismap_=[E <: ElementType](v: Boolean) = ismap.set(v) - implicit def width = Attribute[Img with Iframe with Embed with Object with Video with Canvas with Input, Int]("width")(_.toString) + implicit def width = + Attribute[ + Img with Iframe with Embed with Object with Video with Canvas with Input, + Int]("width")(_.toString) def width_=[E <: ElementType](v: Int) = width.set(v) - implicit def height = Attribute[Img with Iframe with Embed with Object with Video with Canvas with Input, Int]("height")(_.toString) + implicit def height = + Attribute[ + Img with Iframe with Embed with Object with Video with Canvas with Input, + Int]("height")(_.toString) def height_=[E <: ElementType](v: Int) = height.set(v) - implicit def sandbox = Attribute[Iframe, Boolean]("sandbox")(v => if(v) "sandbox" else null) + implicit def sandbox = + Attribute[Iframe, Boolean]("sandbox")(v => if (v) "sandbox" else null) def sandbox_=[E <: ElementType](v: Boolean) = sandbox.set(v) - implicit def seamless = Attribute[Iframe, Boolean]("seamless")(v => if(v) "seamless" else null) + implicit def seamless = + Attribute[Iframe, Boolean]("seamless")(v => if (v) "seamless" else null) def seamless_=[E <: ElementType](v: Boolean) = seamless.set(v) implicit def poster = Attribute[Video, PathLink]("poster")(_.link) - def poster_=[E <: ElementType, L: Linkable](v: L) = poster.set(implicitly[Linkable[L]].link(v)) + def poster_=[E <: ElementType, L : Linkable](v: L) = + poster.set(implicitly[Linkable[L]].link(v)) implicit def data = Attribute[Object, String]("data")(identity) def data_=[E <: ElementType](v: String) = data.set(v) - implicit def autobuffer = Attribute[Video with Audio, Boolean]("autobuffer")(v => if(v) "autobuffer" else null) + implicit def autobuffer = + Attribute[Video with Audio, Boolean]("autobuffer")( + v => if (v) "autobuffer" else null) def autobuffer_=[E <: ElementType](v: Boolean) = autobuffer.set(v) - implicit def autoplay = Attribute[Video with Audio, Boolean]("autoplay")(v => if(v) "autoplay" else null) + implicit def autoplay = + Attribute[Video with Audio, Boolean]("autoplay")( + v => if (v) "autoplay" else null) def autoplay_=[E <: ElementType](v: Boolean) = autoplay.set(v) - implicit def loop = Attribute[Video with Audio, Boolean]("loop")(v => if(v) "loop" else null) + implicit def loop = + Attribute[Video with Audio, Boolean]("loop")(v => if (v) "loop" else null) def loop_=[E <: ElementType](v: Boolean) = loop.set(v) - implicit def controls = Attribute[Video with Audio, Boolean]("controls")(v => if(v) "controls" else null) + implicit def controls = + Attribute[Video with Audio, Boolean]("controls")( + v => if (v) "controls" else null) def controls_=[E <: ElementType](v: Boolean) = controls.set(v) implicit def coords = Attribute[Area, String]("coords")(identity) @@ -410,19 +475,26 @@ object htmlSyntax { implicit def scope = Attribute[Th, Symbol]("scope")(_.name) def scope_=[E <: ElementType](v: Symbol) = scope.set(v) - implicit def acceptCharset = Attribute[Form, String]("accept-charset")(identity) + implicit def acceptCharset = + Attribute[Form, String]("accept-charset")(identity) def acceptCharset_=[E <: ElementType](v: String) = acceptCharset.set(v) - implicit def autocomplete = Attribute[Form with Input, Boolean]("autocomplete")(v => if(v) "on" else "off") + implicit def autocomplete = + Attribute[Form with Input, Boolean]("autocomplete")( + v => if (v) "on" else "off") def autocomplete_=[E <: ElementType](v: Boolean) = autocomplete.set(v) - implicit def novalidate = Attribute[Form with Input with Button, Boolean]("novalidate")(v => if(v) "novalidate" else null) + implicit def novalidate = + Attribute[Form with Input with Button, Boolean]("novalidate")( + v => if (v) "novalidate" else null) def novalidate_=[E <: ElementType](v: Boolean) = novalidate.set(v) - implicit def label = Attribute[Option with Command with Menu, String]("label")(identity) + implicit def label = + Attribute[Option with Command with Menu, String]("label")(identity) def label_=[E <: ElementType](v: String) = label.set(v) - implicit def forName = Attribute[Option with Command with Menu, Symbol]("forName")(_.name) + implicit def forName = + Attribute[Option with Command with Menu, Symbol]("forName")(_.name) def forName_=[E <: ElementType](v: Symbol) = forName.set(v) implicit def `for` = Attribute[Label, Symbol]("for")(_.name) @@ -431,13 +503,17 @@ object htmlSyntax { implicit def accept = Attribute[Input with Menu, String]("accept")(identity) def accept_=[E <: ElementType](v: String) = accept.set(v) - implicit def autofocus = Attribute[Input with Button with Select with Textarea, Boolean]("autofocus")(v => if(v) "autofocus" else null) + implicit def autofocus = + Attribute[Input with Button with Select with Textarea, Boolean]( + "autofocus")(v => if (v) "autofocus" else null) def autofocus_=[E <: ElementType](v: Boolean) = autofocus.set(v) implicit def list = Attribute[Input, Symbol]("list")(_.name) def list_=[E <: ElementType](v: Symbol) = list.set(v) - implicit def multiple = Attribute[Input with Select, Boolean]("multiple")(v => if(v) "multiple" else null) + implicit def multiple = + Attribute[Input with Select, Boolean]("multiple")( + v => if (v) "multiple" else null) def multiple_=[E <: ElementType](v: Boolean) = multiple.set(v) implicit def pattern = Attribute[Input, String]("pattern")(identity) @@ -446,10 +522,14 @@ object htmlSyntax { implicit def placeholder = Attribute[Input, String]("placeholder")(identity) def placeholder_=[E <: ElementType](v: String) = placeholder.set(v) - implicit def readonly = Attribute[Input with Textarea, Boolean]("readonly")(v => if(v) "readonly" else null) + implicit def readonly = + Attribute[Input with Textarea, Boolean]("readonly")( + v => if (v) "readonly" else null) def readonly_=[E <: ElementType](v: Boolean) = readonly.set(v) - implicit def required = Attribute[Input with Textarea, Boolean]("required")(v => if(v) "required" else null) + implicit def required = + Attribute[Input with Textarea, Boolean]("required")( + v => if (v) "required" else null) def required_=[E <: ElementType](v: Boolean) = required.set(v) implicit def size = Attribute[Input with Select, Int]("size")(_.toString) @@ -459,7 +539,8 @@ object htmlSyntax { def step_=[E <: ElementType](v: Int) = step.set(v) implicit def icon = Attribute[Command, PathLink]("icon")(_.link) - def icon_=[E <: ElementType, L: Linkable](v: L) = icon.set(implicitly[Linkable[L]].link(v)) + def icon_=[E <: ElementType, L : Linkable](v: L) = + icon.set(implicitly[Linkable[L]].link(v)) implicit def radiogroup = Attribute[Command, Symbol]("radiogroup")(_.name) def radiogroup_=[E <: ElementType](v: Symbol) = radiogroup.set(v) @@ -492,5 +573,4 @@ object htmlSyntax { val submit = TypeOption("submit") val image = TypeOption("image") val reset = TypeOption("reset") - } diff --git a/html/shared/src/main/scala/rapture/html/tests.scala b/html/shared/src/main/scala/rapture/html/tests.scala index 2ba6939..10f8536 100644 --- a/html/shared/src/main/scala/rapture/html/tests.scala +++ b/html/shared/src/main/scala/rapture/html/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.html @@ -48,7 +48,7 @@ object Tests { def `Tbody with id can contain Tr` = Tbody(id = 'foo)(Tr, Tr, Tr) def `Tr with id can contain Th/Tr` = Tr(id = 'foo)(Th, Td, Td, Td) - + def `Img has src attribute` = Img(src = ^ / "foo.jpg") def `Link has hreflang attribute` = Link(hreflang = 'en) @@ -168,5 +168,4 @@ object Tests { //def `Should fail` = Html(src = "foo") def `Get Tds` = Table(Tbody(Tr(Td, Td, Td), Tr(Td, Td, Td))) - } diff --git a/html/shared/src/test/scala/rapture/html/tests.scala b/html/shared/src/test/scala/rapture/html/tests.scala index e658c15..35a5c57 100644 --- a/html/shared/src/test/scala/rapture/html/tests.scala +++ b/html/shared/src/test/scala/rapture/html/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.html @@ -47,7 +47,7 @@ object Tests { def `Tbody with id can contain Tr` = Tbody(id = 'foo)(Tr, Tr, Tr) def `Tr with id can contain Th/Tr` = Tr(id = 'foo)(Th, Td, Td, Td) - + def `Img has src attribute` = Img(src = ^ / "foo.jpg") def `Link has hreflang attribute` = Link(hreflang = 'en) @@ -165,5 +165,4 @@ object Tests { //def `Should fail` = Html(src = "foo") def `Get Tds` = Table(Tbody(Tr(Td, Td, Td), Tr(Td, Td, Td))) - } diff --git a/i18n/shared/src/main/scala/rapture/i18n/i18n.scala b/i18n/shared/src/main/scala/rapture/i18n/i18n.scala index 269fc7e..0a6e396 100644 --- a/i18n/shared/src/main/scala/rapture/i18n/i18n.scala +++ b/i18n/shared/src/main/scala/rapture/i18n/i18n.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.i18n @@ -25,10 +25,11 @@ import language.experimental.macros import language.implicitConversions object Locale { - implicit def upcastLocale[From <: Language, ToLang <: From](loc: Locale[From]): Locale[ToLang] = + implicit def upcastLocale[From <: Language, ToLang <: From]( + loc: Locale[From]): Locale[ToLang] = loc.asInstanceOf[Locale[ToLang]] } -case class Locale[L <: Language: ClassTag]() { +case class Locale[L <: Language : ClassTag]() { val classTag: ClassTag[L] = implicitly[ClassTag[L]] val name = classTag.runtimeClass.getName.split("\\.").last.toLowerCase def from[T, L2 <: L](i18n: I18n[T, L2]) = i18n(classTag) @@ -38,34 +39,44 @@ case class Locale[L <: Language: ClassTag]() { override def toString = name - implicit val defaultLanguage: DefaultLanguage[L] = DefaultLanguage[L](classTag) + implicit val defaultLanguage: DefaultLanguage[L] = + DefaultLanguage[L](classTag) } -case class LocaleException(locale: String) extends Exception(s"Locale '$locale' not recognised.") - -class LocaleParser[L <: Language](val locales: Map[String, Locale[_ >: L <: Language]]) { - def |[L2 <: Language](locale: Locale[L2]) = new LocaleParser[L with L2](locales + (locale.name -> locale)) - - def parse(s: String)(implicit mode: Mode[_]): mode.Wrap[Locale[L], LocaleException] = mode.wrap { - locales.get(s.toLowerCase) match { - case Some(loc) => loc.asInstanceOf[Locale[L]] - case None => mode.exception(LocaleException(s)) +case class LocaleException(locale: String) + extends Exception(s"Locale '$locale' not recognised.") + +class LocaleParser[L <: Language]( + val locales: Map[String, Locale[_ >: L <: Language]]) { + def |[L2 <: Language](locale: Locale[L2]) = + new LocaleParser[L with L2](locales + (locale.name -> locale)) + + def parse(s: String)( + implicit mode: Mode[_]): mode.Wrap[Locale[L], LocaleException] = + mode.wrap { + locales.get(s.toLowerCase) match { + case Some(loc) => loc.asInstanceOf[Locale[L]] + case None => mode.exception(LocaleException(s)) + } } - } override def toString = locales.keys.mkString("|") } object I18n { - implicit def upcast[ToLang <: Language, FromLang <: Language](from: I18n[String, FromLang]): I18n[String, ToLang] = - macro Macros.missingTranslationsMacro[ToLang, FromLang] + implicit def upcast[ToLang <: Language, FromLang <: Language]( + from: I18n[String, FromLang]): I18n[String, ToLang] = macro Macros + .missingTranslationsMacro[ToLang, FromLang] - implicit def convertToType[T, L <: Language, L2 >: L <: Language: DefaultLanguage](i18n: I18n[T, L]): T = + implicit def convertToType[ + T, L <: Language, L2 >: L <: Language : DefaultLanguage]( + i18n: I18n[T, L]): T = i18n.map(implicitly[DefaultLanguage[L2]].tag) class `I18n.apply`[L <: Language]() { - def apply[T](value: T)(implicit ct: ClassTag[L]) = new I18n[T, L](Map(ct -> value)) + def apply[T](value: T)(implicit ct: ClassTag[L]) = + new I18n[T, L](Map(ct -> value)) } def apply[L <: Language] = new `I18n.apply`[L]() @@ -73,18 +84,25 @@ object I18n { @implicitNotFound("This I18nString already includes the language ${Lang}.") private[i18n] trait RequireLanguage[Lang] -private[i18n] object RequireLanguage { implicit def requireLanguage: RequireLanguage[Language] = null } +private[i18n] object RequireLanguage { + implicit def requireLanguage: RequireLanguage[Language] = null +} class I18n[T, Languages <: Language](private val map: Map[ClassTag[_], T]) { def apply[Lang >: Languages](implicit ct: ClassTag[Lang]): T = map(ct) - final def &[L >: Languages <: Language, Lang2 <: L](s2: I18n[T, Lang2])(implicit ev: RequireLanguage[L]): - I18n[T, Languages with Lang2] = new I18n[T, Languages with Lang2](map ++ s2.map) + final def &[L >: Languages <: Language, Lang2 <: L](s2: I18n[T, Lang2])( + implicit ev: RequireLanguage[L]): I18n[T, Languages with Lang2] = + new I18n[T, Languages with Lang2](map ++ s2.map) override def toString = { - val langs = map.keys.map(_.runtimeClass.getName.takeRight(2).toLowerCase).mkString("&") + val langs = map.keys + .map(_.runtimeClass.getName.takeRight(2).toLowerCase) + .mkString("&") val content: Option[T] = map.get(implicitly[ClassTag[En]]) - lazy val first: Option[T] = map.headOption.flatMap { case (k, v) => map.get(k) } + lazy val first: Option[T] = map.headOption.flatMap { + case (k, v) => map.get(k) + } val value = content.orElse(first).map(_.toString).getOrElse("") match { case string: String => string case other => s""""$other"""" @@ -95,21 +113,24 @@ class I18n[T, Languages <: Language](private val map: Map[ClassTag[_], T]) { override def hashCode = map.hashCode ^ 248327829 override def equals(that: Any) = that match { - case that: I18n[_, _] => map == that.map + case that: I18n [_, _] => map == that.map case _ => false } } object I18nStringParam { - implicit def stringToStringParam[L <: Language](s: String): I18nStringParam[L] = + implicit def stringToStringParam[L <: Language]( + s: String): I18nStringParam[L] = new I18nStringParam[L](new I18n[String, L](Map()) { override def apply[Lang >: L](implicit ct: ClassTag[Lang]) = s }) - implicit def toI18nStringParam[L <: Language](s: I18n[String, L]): I18nStringParam[L] = + implicit def toI18nStringParam[L <: Language]( + s: I18n[String, L]): I18nStringParam[L] = I18nStringParam(s) } -case class I18nStringParam[+L <: Language](i18n: I18n[String, L @annotation.unchecked.uncheckedVariance]) +case class I18nStringParam[+L <: Language]( + i18n: I18n[String, L @annotation.unchecked.uncheckedVariance]) extends AnyVal trait LanguageBundle[Langs <: Language] { diff --git a/i18n/shared/src/main/scala/rapture/i18n/languages.scala b/i18n/shared/src/main/scala/rapture/i18n/languages.scala index 38d5333..c8b40b4 100644 --- a/i18n/shared/src/main/scala/rapture/i18n/languages.scala +++ b/i18n/shared/src/main/scala/rapture/i18n/languages.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.i18n diff --git a/i18n/shared/src/main/scala/rapture/i18n/package.scala b/i18n/shared/src/main/scala/rapture/i18n/package.scala index afd1f04..891ec91 100644 --- a/i18n/shared/src/main/scala/rapture/i18n/package.scala +++ b/i18n/shared/src/main/scala/rapture/i18n/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.i18n @@ -25,210 +25,399 @@ import language.implicitConversions object `package` { - implicit def i18nStringToString[L <: Language](msg: I18n[String, L]) - (implicit locale: Locale[_ >: L]): String = locale.from(msg) - + implicit def i18nStringToString[L <: Language](msg: I18n[String, L])( + implicit locale: Locale[_ >: L]): String = locale.from(msg) + implicit class I18nEnrichedStringContext(sc: StringContext) { - - private def context[L <: Language: ClassTag](sc: StringContext, params: List[I18nStringParam[L]]): - I18n[String, L] = - new I18n[String, L](Map(implicitly[ClassTag[L]] -> sc.parts.zip(params.map(_.i18n.apply[L]) :+ "").map { - case (a, b) => a+b - }.mkString)) - def aa(params: I18nStringParam[Aa]*): I18n[String, Aa] = context[Aa](sc, params.toList) - def ab(params: I18nStringParam[Ab]*): I18n[String, Ab] = context[Ab](sc, params.toList) - def ae(params: I18nStringParam[Ae]*): I18n[String, Ae] = context[Ae](sc, params.toList) - def af(params: I18nStringParam[Af]*): I18n[String, Af] = context[Af](sc, params.toList) - def ak(params: I18nStringParam[Ak]*): I18n[String, Ak] = context[Ak](sc, params.toList) - def am(params: I18nStringParam[Am]*): I18n[String, Am] = context[Am](sc, params.toList) - def an(params: I18nStringParam[An]*): I18n[String, An] = context[An](sc, params.toList) - def ar(params: I18nStringParam[Ar]*): I18n[String, Ar] = context[Ar](sc, params.toList) - def as(params: I18nStringParam[As]*): I18n[String, As] = context[As](sc, params.toList) - def av(params: I18nStringParam[Av]*): I18n[String, Av] = context[Av](sc, params.toList) - def ay(params: I18nStringParam[Ay]*): I18n[String, Ay] = context[Ay](sc, params.toList) - def az(params: I18nStringParam[Az]*): I18n[String, Az] = context[Az](sc, params.toList) - def ba(params: I18nStringParam[Ba]*): I18n[String, Ba] = context[Ba](sc, params.toList) - def be(params: I18nStringParam[Be]*): I18n[String, Be] = context[Be](sc, params.toList) - def bg(params: I18nStringParam[Bg]*): I18n[String, Bg] = context[Bg](sc, params.toList) - def bh(params: I18nStringParam[Bh]*): I18n[String, Bh] = context[Bh](sc, params.toList) - def bi(params: I18nStringParam[Bi]*): I18n[String, Bi] = context[Bi](sc, params.toList) - def bm(params: I18nStringParam[Bm]*): I18n[String, Bm] = context[Bm](sc, params.toList) - def bn(params: I18nStringParam[Bn]*): I18n[String, Bn] = context[Bn](sc, params.toList) - def bo(params: I18nStringParam[Bo]*): I18n[String, Bo] = context[Bo](sc, params.toList) - def br(params: I18nStringParam[Br]*): I18n[String, Br] = context[Br](sc, params.toList) - def bs(params: I18nStringParam[Bs]*): I18n[String, Bs] = context[Bs](sc, params.toList) - def ca(params: I18nStringParam[Ca]*): I18n[String, Ca] = context[Ca](sc, params.toList) - def ce(params: I18nStringParam[Ce]*): I18n[String, Ce] = context[Ce](sc, params.toList) - def ch(params: I18nStringParam[Ch]*): I18n[String, Ch] = context[Ch](sc, params.toList) - def co(params: I18nStringParam[Co]*): I18n[String, Co] = context[Co](sc, params.toList) - def cr(params: I18nStringParam[Cr]*): I18n[String, Cr] = context[Cr](sc, params.toList) - def cs(params: I18nStringParam[Cs]*): I18n[String, Cs] = context[Cs](sc, params.toList) - def cu(params: I18nStringParam[Cu]*): I18n[String, Cu] = context[Cu](sc, params.toList) - def cv(params: I18nStringParam[Cv]*): I18n[String, Cv] = context[Cv](sc, params.toList) - def cy(params: I18nStringParam[Cy]*): I18n[String, Cy] = context[Cy](sc, params.toList) - def da(params: I18nStringParam[Da]*): I18n[String, Da] = context[Da](sc, params.toList) - def de(params: I18nStringParam[De]*): I18n[String, De] = context[De](sc, params.toList) - def dv(params: I18nStringParam[Dv]*): I18n[String, Dv] = context[Dv](sc, params.toList) - def dz(params: I18nStringParam[Dz]*): I18n[String, Dz] = context[Dz](sc, params.toList) - def ee(params: I18nStringParam[Ee]*): I18n[String, Ee] = context[Ee](sc, params.toList) - def el(params: I18nStringParam[El]*): I18n[String, El] = context[El](sc, params.toList) - def en(params: I18nStringParam[En]*): I18n[String, En] = context[En](sc, params.toList) - def eo(params: I18nStringParam[Eo]*): I18n[String, Eo] = context[Eo](sc, params.toList) - def es(params: I18nStringParam[Es]*): I18n[String, Es] = context[Es](sc, params.toList) - def et(params: I18nStringParam[Et]*): I18n[String, Et] = context[Et](sc, params.toList) - def eu(params: I18nStringParam[Eu]*): I18n[String, Eu] = context[Eu](sc, params.toList) - def fa(params: I18nStringParam[Fa]*): I18n[String, Fa] = context[Fa](sc, params.toList) - def ff(params: I18nStringParam[Ff]*): I18n[String, Ff] = context[Ff](sc, params.toList) - def fi(params: I18nStringParam[Fi]*): I18n[String, Fi] = context[Fi](sc, params.toList) - def fj(params: I18nStringParam[Fj]*): I18n[String, Fj] = context[Fj](sc, params.toList) - def fo(params: I18nStringParam[Fo]*): I18n[String, Fo] = context[Fo](sc, params.toList) - def fr(params: I18nStringParam[Fr]*): I18n[String, Fr] = context[Fr](sc, params.toList) - def fy(params: I18nStringParam[Fy]*): I18n[String, Fy] = context[Fy](sc, params.toList) - def ga(params: I18nStringParam[Ga]*): I18n[String, Ga] = context[Ga](sc, params.toList) - def gd(params: I18nStringParam[Gd]*): I18n[String, Gd] = context[Gd](sc, params.toList) - def gl(params: I18nStringParam[Gl]*): I18n[String, Gl] = context[Gl](sc, params.toList) - def gn(params: I18nStringParam[Gn]*): I18n[String, Gn] = context[Gn](sc, params.toList) - def gu(params: I18nStringParam[Gu]*): I18n[String, Gu] = context[Gu](sc, params.toList) - def gv(params: I18nStringParam[Gv]*): I18n[String, Gv] = context[Gv](sc, params.toList) - def ha(params: I18nStringParam[Ha]*): I18n[String, Ha] = context[Ha](sc, params.toList) - def he(params: I18nStringParam[He]*): I18n[String, He] = context[He](sc, params.toList) - def hi(params: I18nStringParam[Hi]*): I18n[String, Hi] = context[Hi](sc, params.toList) - def ho(params: I18nStringParam[Ho]*): I18n[String, Ho] = context[Ho](sc, params.toList) - def hr(params: I18nStringParam[Hr]*): I18n[String, Hr] = context[Hr](sc, params.toList) - def ht(params: I18nStringParam[Ht]*): I18n[String, Ht] = context[Ht](sc, params.toList) - def hu(params: I18nStringParam[Hu]*): I18n[String, Hu] = context[Hu](sc, params.toList) - def hy(params: I18nStringParam[Hy]*): I18n[String, Hy] = context[Hy](sc, params.toList) - def hz(params: I18nStringParam[Hz]*): I18n[String, Hz] = context[Hz](sc, params.toList) - def ia(params: I18nStringParam[Ia]*): I18n[String, Ia] = context[Ia](sc, params.toList) - def id(params: I18nStringParam[Id]*): I18n[String, Id] = context[Id](sc, params.toList) - def ie(params: I18nStringParam[Ie]*): I18n[String, Ie] = context[Ie](sc, params.toList) - def ig(params: I18nStringParam[Ig]*): I18n[String, Ig] = context[Ig](sc, params.toList) - def ii(params: I18nStringParam[Ii]*): I18n[String, Ii] = context[Ii](sc, params.toList) - def ik(params: I18nStringParam[Ik]*): I18n[String, Ik] = context[Ik](sc, params.toList) - def io(params: I18nStringParam[Io]*): I18n[String, Io] = context[Io](sc, params.toList) - def is(params: I18nStringParam[Is]*): I18n[String, Is] = context[Is](sc, params.toList) - def it(params: I18nStringParam[It]*): I18n[String, It] = context[It](sc, params.toList) - def iu(params: I18nStringParam[Iu]*): I18n[String, Iu] = context[Iu](sc, params.toList) - def ja(params: I18nStringParam[Ja]*): I18n[String, Ja] = context[Ja](sc, params.toList) - def jv(params: I18nStringParam[Jv]*): I18n[String, Jv] = context[Jv](sc, params.toList) - def ka(params: I18nStringParam[Ka]*): I18n[String, Ka] = context[Ka](sc, params.toList) - def kg(params: I18nStringParam[Kg]*): I18n[String, Kg] = context[Kg](sc, params.toList) - def ki(params: I18nStringParam[Ki]*): I18n[String, Ki] = context[Ki](sc, params.toList) - def kj(params: I18nStringParam[Kj]*): I18n[String, Kj] = context[Kj](sc, params.toList) - def kk(params: I18nStringParam[Kk]*): I18n[String, Kk] = context[Kk](sc, params.toList) - def kl(params: I18nStringParam[Kl]*): I18n[String, Kl] = context[Kl](sc, params.toList) - def km(params: I18nStringParam[Km]*): I18n[String, Km] = context[Km](sc, params.toList) - def kn(params: I18nStringParam[Kn]*): I18n[String, Kn] = context[Kn](sc, params.toList) - def ko(params: I18nStringParam[Ko]*): I18n[String, Ko] = context[Ko](sc, params.toList) - def kr(params: I18nStringParam[Kr]*): I18n[String, Kr] = context[Kr](sc, params.toList) - def ks(params: I18nStringParam[Ks]*): I18n[String, Ks] = context[Ks](sc, params.toList) - def ku(params: I18nStringParam[Ku]*): I18n[String, Ku] = context[Ku](sc, params.toList) - def kv(params: I18nStringParam[Kv]*): I18n[String, Kv] = context[Kv](sc, params.toList) - def kw(params: I18nStringParam[Kw]*): I18n[String, Kw] = context[Kw](sc, params.toList) - def ky(params: I18nStringParam[Ky]*): I18n[String, Ky] = context[Ky](sc, params.toList) - def la(params: I18nStringParam[La]*): I18n[String, La] = context[La](sc, params.toList) - def lb(params: I18nStringParam[Lb]*): I18n[String, Lb] = context[Lb](sc, params.toList) - def lg(params: I18nStringParam[Lg]*): I18n[String, Lg] = context[Lg](sc, params.toList) - def li(params: I18nStringParam[Li]*): I18n[String, Li] = context[Li](sc, params.toList) - def ln(params: I18nStringParam[Ln]*): I18n[String, Ln] = context[Ln](sc, params.toList) - def lo(params: I18nStringParam[Lo]*): I18n[String, Lo] = context[Lo](sc, params.toList) - def lt(params: I18nStringParam[Lt]*): I18n[String, Lt] = context[Lt](sc, params.toList) - def lu(params: I18nStringParam[Lu]*): I18n[String, Lu] = context[Lu](sc, params.toList) - def lv(params: I18nStringParam[Lv]*): I18n[String, Lv] = context[Lv](sc, params.toList) - def mg(params: I18nStringParam[Mg]*): I18n[String, Mg] = context[Mg](sc, params.toList) - def mh(params: I18nStringParam[Mh]*): I18n[String, Mh] = context[Mh](sc, params.toList) - def mi(params: I18nStringParam[Mi]*): I18n[String, Mi] = context[Mi](sc, params.toList) - def mk(params: I18nStringParam[Mk]*): I18n[String, Mk] = context[Mk](sc, params.toList) - def ml(params: I18nStringParam[Ml]*): I18n[String, Ml] = context[Ml](sc, params.toList) - def mn(params: I18nStringParam[Mn]*): I18n[String, Mn] = context[Mn](sc, params.toList) - def mr(params: I18nStringParam[Mr]*): I18n[String, Mr] = context[Mr](sc, params.toList) - def ms(params: I18nStringParam[Ms]*): I18n[String, Ms] = context[Ms](sc, params.toList) - def mt(params: I18nStringParam[Mt]*): I18n[String, Mt] = context[Mt](sc, params.toList) - def my(params: I18nStringParam[My]*): I18n[String, My] = context[My](sc, params.toList) - def na(params: I18nStringParam[Na]*): I18n[String, Na] = context[Na](sc, params.toList) - def nb(params: I18nStringParam[Nb]*): I18n[String, Nb] = context[Nb](sc, params.toList) - def nd(params: I18nStringParam[Nd]*): I18n[String, Nd] = context[Nd](sc, params.toList) - def ne(params: I18nStringParam[Ne]*): I18n[String, Ne] = context[Ne](sc, params.toList) - def ng(params: I18nStringParam[Ng]*): I18n[String, Ng] = context[Ng](sc, params.toList) - def nl(params: I18nStringParam[Nl]*): I18n[String, Nl] = context[Nl](sc, params.toList) - def nn(params: I18nStringParam[Nn]*): I18n[String, Nn] = context[Nn](sc, params.toList) - def no(params: I18nStringParam[No]*): I18n[String, No] = context[No](sc, params.toList) - def nr(params: I18nStringParam[Nr]*): I18n[String, Nr] = context[Nr](sc, params.toList) - def nv(params: I18nStringParam[Nv]*): I18n[String, Nv] = context[Nv](sc, params.toList) - def ny(params: I18nStringParam[Ny]*): I18n[String, Ny] = context[Ny](sc, params.toList) - def oc(params: I18nStringParam[Oc]*): I18n[String, Oc] = context[Oc](sc, params.toList) - def oj(params: I18nStringParam[Oj]*): I18n[String, Oj] = context[Oj](sc, params.toList) - def om(params: I18nStringParam[Om]*): I18n[String, Om] = context[Om](sc, params.toList) - def or(params: I18nStringParam[Or]*): I18n[String, Or] = context[Or](sc, params.toList) - def os(params: I18nStringParam[Os]*): I18n[String, Os] = context[Os](sc, params.toList) - def pa(params: I18nStringParam[Pa]*): I18n[String, Pa] = context[Pa](sc, params.toList) - def pi(params: I18nStringParam[Pi]*): I18n[String, Pi] = context[Pi](sc, params.toList) - def pl(params: I18nStringParam[Pl]*): I18n[String, Pl] = context[Pl](sc, params.toList) - def ps(params: I18nStringParam[Ps]*): I18n[String, Ps] = context[Ps](sc, params.toList) - def pt(params: I18nStringParam[Pt]*): I18n[String, Pt] = context[Pt](sc, params.toList) - def qu(params: I18nStringParam[Qu]*): I18n[String, Qu] = context[Qu](sc, params.toList) - def rm(params: I18nStringParam[Rm]*): I18n[String, Rm] = context[Rm](sc, params.toList) - def rn(params: I18nStringParam[Rn]*): I18n[String, Rn] = context[Rn](sc, params.toList) - def ro(params: I18nStringParam[Ro]*): I18n[String, Ro] = context[Ro](sc, params.toList) - def ru(params: I18nStringParam[Ru]*): I18n[String, Ru] = context[Ru](sc, params.toList) - def rw(params: I18nStringParam[Rw]*): I18n[String, Rw] = context[Rw](sc, params.toList) - def sa(params: I18nStringParam[Sa]*): I18n[String, Sa] = context[Sa](sc, params.toList) - def sc(params: I18nStringParam[Sc]*): I18n[String, Sc] = context[Sc](sc, params.toList) - def sd(params: I18nStringParam[Sd]*): I18n[String, Sd] = context[Sd](sc, params.toList) - def se(params: I18nStringParam[Se]*): I18n[String, Se] = context[Se](sc, params.toList) - def sg(params: I18nStringParam[Sg]*): I18n[String, Sg] = context[Sg](sc, params.toList) - def si(params: I18nStringParam[Si]*): I18n[String, Si] = context[Si](sc, params.toList) - def sk(params: I18nStringParam[Sk]*): I18n[String, Sk] = context[Sk](sc, params.toList) - def sl(params: I18nStringParam[Sl]*): I18n[String, Sl] = context[Sl](sc, params.toList) - def sm(params: I18nStringParam[Sm]*): I18n[String, Sm] = context[Sm](sc, params.toList) - def sn(params: I18nStringParam[Sn]*): I18n[String, Sn] = context[Sn](sc, params.toList) - def so(params: I18nStringParam[So]*): I18n[String, So] = context[So](sc, params.toList) - def sq(params: I18nStringParam[Sq]*): I18n[String, Sq] = context[Sq](sc, params.toList) - def sr(params: I18nStringParam[Sr]*): I18n[String, Sr] = context[Sr](sc, params.toList) - def ss(params: I18nStringParam[Ss]*): I18n[String, Ss] = context[Ss](sc, params.toList) - def st(params: I18nStringParam[St]*): I18n[String, St] = context[St](sc, params.toList) - def su(params: I18nStringParam[Su]*): I18n[String, Su] = context[Su](sc, params.toList) - def sv(params: I18nStringParam[Sv]*): I18n[String, Sv] = context[Sv](sc, params.toList) - def sw(params: I18nStringParam[Sw]*): I18n[String, Sw] = context[Sw](sc, params.toList) - def ta(params: I18nStringParam[Ta]*): I18n[String, Ta] = context[Ta](sc, params.toList) - def te(params: I18nStringParam[Te]*): I18n[String, Te] = context[Te](sc, params.toList) - def tg(params: I18nStringParam[Tg]*): I18n[String, Tg] = context[Tg](sc, params.toList) - def th(params: I18nStringParam[Th]*): I18n[String, Th] = context[Th](sc, params.toList) - def ti(params: I18nStringParam[Ti]*): I18n[String, Ti] = context[Ti](sc, params.toList) - def tk(params: I18nStringParam[Tk]*): I18n[String, Tk] = context[Tk](sc, params.toList) - def tl(params: I18nStringParam[Tl]*): I18n[String, Tl] = context[Tl](sc, params.toList) - def tn(params: I18nStringParam[Tn]*): I18n[String, Tn] = context[Tn](sc, params.toList) - def to(params: I18nStringParam[To]*): I18n[String, To] = context[To](sc, params.toList) - def tr(params: I18nStringParam[Tr]*): I18n[String, Tr] = context[Tr](sc, params.toList) - def ts(params: I18nStringParam[Ts]*): I18n[String, Ts] = context[Ts](sc, params.toList) - def tt(params: I18nStringParam[Tt]*): I18n[String, Tt] = context[Tt](sc, params.toList) - def tw(params: I18nStringParam[Tw]*): I18n[String, Tw] = context[Tw](sc, params.toList) - def ty(params: I18nStringParam[Ty]*): I18n[String, Ty] = context[Ty](sc, params.toList) - def ug(params: I18nStringParam[Ug]*): I18n[String, Ug] = context[Ug](sc, params.toList) - def uk(params: I18nStringParam[Uk]*): I18n[String, Uk] = context[Uk](sc, params.toList) - def ur(params: I18nStringParam[Ur]*): I18n[String, Ur] = context[Ur](sc, params.toList) - def uz(params: I18nStringParam[Uz]*): I18n[String, Uz] = context[Uz](sc, params.toList) - def ve(params: I18nStringParam[Ve]*): I18n[String, Ve] = context[Ve](sc, params.toList) - def vi(params: I18nStringParam[Vi]*): I18n[String, Vi] = context[Vi](sc, params.toList) - def vo(params: I18nStringParam[Vo]*): I18n[String, Vo] = context[Vo](sc, params.toList) - def wa(params: I18nStringParam[Wa]*): I18n[String, Wa] = context[Wa](sc, params.toList) - def wo(params: I18nStringParam[Wo]*): I18n[String, Wo] = context[Wo](sc, params.toList) - def xh(params: I18nStringParam[Xh]*): I18n[String, Xh] = context[Xh](sc, params.toList) - def yi(params: I18nStringParam[Yi]*): I18n[String, Yi] = context[Yi](sc, params.toList) - def yo(params: I18nStringParam[Yo]*): I18n[String, Yo] = context[Yo](sc, params.toList) - def za(params: I18nStringParam[Za]*): I18n[String, Za] = context[Za](sc, params.toList) - def zh(params: I18nStringParam[Zh]*): I18n[String, Zh] = context[Zh](sc, params.toList) - def zu(params: I18nStringParam[Zu]*): I18n[String, Zu] = context[Zu](sc, params.toList) - } + private def context[L <: Language : ClassTag]( + sc: StringContext, params: List[I18nStringParam[L]]): I18n[String, L] = + new I18n[String, L]( + Map(implicitly[ClassTag[L]] -> sc.parts + .zip(params.map(_.i18n.apply[L]) :+ "") + .map { + case (a, b) => a + b + } + .mkString)) + def aa(params: I18nStringParam[Aa]*): I18n[String, Aa] = + context[Aa](sc, params.toList) + def ab(params: I18nStringParam[Ab]*): I18n[String, Ab] = + context[Ab](sc, params.toList) + def ae(params: I18nStringParam[Ae]*): I18n[String, Ae] = + context[Ae](sc, params.toList) + def af(params: I18nStringParam[Af]*): I18n[String, Af] = + context[Af](sc, params.toList) + def ak(params: I18nStringParam[Ak]*): I18n[String, Ak] = + context[Ak](sc, params.toList) + def am(params: I18nStringParam[Am]*): I18n[String, Am] = + context[Am](sc, params.toList) + def an(params: I18nStringParam[An]*): I18n[String, An] = + context[An](sc, params.toList) + def ar(params: I18nStringParam[Ar]*): I18n[String, Ar] = + context[Ar](sc, params.toList) + def as(params: I18nStringParam[As]*): I18n[String, As] = + context[As](sc, params.toList) + def av(params: I18nStringParam[Av]*): I18n[String, Av] = + context[Av](sc, params.toList) + def ay(params: I18nStringParam[Ay]*): I18n[String, Ay] = + context[Ay](sc, params.toList) + def az(params: I18nStringParam[Az]*): I18n[String, Az] = + context[Az](sc, params.toList) + def ba(params: I18nStringParam[Ba]*): I18n[String, Ba] = + context[Ba](sc, params.toList) + def be(params: I18nStringParam[Be]*): I18n[String, Be] = + context[Be](sc, params.toList) + def bg(params: I18nStringParam[Bg]*): I18n[String, Bg] = + context[Bg](sc, params.toList) + def bh(params: I18nStringParam[Bh]*): I18n[String, Bh] = + context[Bh](sc, params.toList) + def bi(params: I18nStringParam[Bi]*): I18n[String, Bi] = + context[Bi](sc, params.toList) + def bm(params: I18nStringParam[Bm]*): I18n[String, Bm] = + context[Bm](sc, params.toList) + def bn(params: I18nStringParam[Bn]*): I18n[String, Bn] = + context[Bn](sc, params.toList) + def bo(params: I18nStringParam[Bo]*): I18n[String, Bo] = + context[Bo](sc, params.toList) + def br(params: I18nStringParam[Br]*): I18n[String, Br] = + context[Br](sc, params.toList) + def bs(params: I18nStringParam[Bs]*): I18n[String, Bs] = + context[Bs](sc, params.toList) + def ca(params: I18nStringParam[Ca]*): I18n[String, Ca] = + context[Ca](sc, params.toList) + def ce(params: I18nStringParam[Ce]*): I18n[String, Ce] = + context[Ce](sc, params.toList) + def ch(params: I18nStringParam[Ch]*): I18n[String, Ch] = + context[Ch](sc, params.toList) + def co(params: I18nStringParam[Co]*): I18n[String, Co] = + context[Co](sc, params.toList) + def cr(params: I18nStringParam[Cr]*): I18n[String, Cr] = + context[Cr](sc, params.toList) + def cs(params: I18nStringParam[Cs]*): I18n[String, Cs] = + context[Cs](sc, params.toList) + def cu(params: I18nStringParam[Cu]*): I18n[String, Cu] = + context[Cu](sc, params.toList) + def cv(params: I18nStringParam[Cv]*): I18n[String, Cv] = + context[Cv](sc, params.toList) + def cy(params: I18nStringParam[Cy]*): I18n[String, Cy] = + context[Cy](sc, params.toList) + def da(params: I18nStringParam[Da]*): I18n[String, Da] = + context[Da](sc, params.toList) + def de(params: I18nStringParam[De]*): I18n[String, De] = + context[De](sc, params.toList) + def dv(params: I18nStringParam[Dv]*): I18n[String, Dv] = + context[Dv](sc, params.toList) + def dz(params: I18nStringParam[Dz]*): I18n[String, Dz] = + context[Dz](sc, params.toList) + def ee(params: I18nStringParam[Ee]*): I18n[String, Ee] = + context[Ee](sc, params.toList) + def el(params: I18nStringParam[El]*): I18n[String, El] = + context[El](sc, params.toList) + def en(params: I18nStringParam[En]*): I18n[String, En] = + context[En](sc, params.toList) + def eo(params: I18nStringParam[Eo]*): I18n[String, Eo] = + context[Eo](sc, params.toList) + def es(params: I18nStringParam[Es]*): I18n[String, Es] = + context[Es](sc, params.toList) + def et(params: I18nStringParam[Et]*): I18n[String, Et] = + context[Et](sc, params.toList) + def eu(params: I18nStringParam[Eu]*): I18n[String, Eu] = + context[Eu](sc, params.toList) + def fa(params: I18nStringParam[Fa]*): I18n[String, Fa] = + context[Fa](sc, params.toList) + def ff(params: I18nStringParam[Ff]*): I18n[String, Ff] = + context[Ff](sc, params.toList) + def fi(params: I18nStringParam[Fi]*): I18n[String, Fi] = + context[Fi](sc, params.toList) + def fj(params: I18nStringParam[Fj]*): I18n[String, Fj] = + context[Fj](sc, params.toList) + def fo(params: I18nStringParam[Fo]*): I18n[String, Fo] = + context[Fo](sc, params.toList) + def fr(params: I18nStringParam[Fr]*): I18n[String, Fr] = + context[Fr](sc, params.toList) + def fy(params: I18nStringParam[Fy]*): I18n[String, Fy] = + context[Fy](sc, params.toList) + def ga(params: I18nStringParam[Ga]*): I18n[String, Ga] = + context[Ga](sc, params.toList) + def gd(params: I18nStringParam[Gd]*): I18n[String, Gd] = + context[Gd](sc, params.toList) + def gl(params: I18nStringParam[Gl]*): I18n[String, Gl] = + context[Gl](sc, params.toList) + def gn(params: I18nStringParam[Gn]*): I18n[String, Gn] = + context[Gn](sc, params.toList) + def gu(params: I18nStringParam[Gu]*): I18n[String, Gu] = + context[Gu](sc, params.toList) + def gv(params: I18nStringParam[Gv]*): I18n[String, Gv] = + context[Gv](sc, params.toList) + def ha(params: I18nStringParam[Ha]*): I18n[String, Ha] = + context[Ha](sc, params.toList) + def he(params: I18nStringParam[He]*): I18n[String, He] = + context[He](sc, params.toList) + def hi(params: I18nStringParam[Hi]*): I18n[String, Hi] = + context[Hi](sc, params.toList) + def ho(params: I18nStringParam[Ho]*): I18n[String, Ho] = + context[Ho](sc, params.toList) + def hr(params: I18nStringParam[Hr]*): I18n[String, Hr] = + context[Hr](sc, params.toList) + def ht(params: I18nStringParam[Ht]*): I18n[String, Ht] = + context[Ht](sc, params.toList) + def hu(params: I18nStringParam[Hu]*): I18n[String, Hu] = + context[Hu](sc, params.toList) + def hy(params: I18nStringParam[Hy]*): I18n[String, Hy] = + context[Hy](sc, params.toList) + def hz(params: I18nStringParam[Hz]*): I18n[String, Hz] = + context[Hz](sc, params.toList) + def ia(params: I18nStringParam[Ia]*): I18n[String, Ia] = + context[Ia](sc, params.toList) + def id(params: I18nStringParam[Id]*): I18n[String, Id] = + context[Id](sc, params.toList) + def ie(params: I18nStringParam[Ie]*): I18n[String, Ie] = + context[Ie](sc, params.toList) + def ig(params: I18nStringParam[Ig]*): I18n[String, Ig] = + context[Ig](sc, params.toList) + def ii(params: I18nStringParam[Ii]*): I18n[String, Ii] = + context[Ii](sc, params.toList) + def ik(params: I18nStringParam[Ik]*): I18n[String, Ik] = + context[Ik](sc, params.toList) + def io(params: I18nStringParam[Io]*): I18n[String, Io] = + context[Io](sc, params.toList) + def is(params: I18nStringParam[Is]*): I18n[String, Is] = + context[Is](sc, params.toList) + def it(params: I18nStringParam[It]*): I18n[String, It] = + context[It](sc, params.toList) + def iu(params: I18nStringParam[Iu]*): I18n[String, Iu] = + context[Iu](sc, params.toList) + def ja(params: I18nStringParam[Ja]*): I18n[String, Ja] = + context[Ja](sc, params.toList) + def jv(params: I18nStringParam[Jv]*): I18n[String, Jv] = + context[Jv](sc, params.toList) + def ka(params: I18nStringParam[Ka]*): I18n[String, Ka] = + context[Ka](sc, params.toList) + def kg(params: I18nStringParam[Kg]*): I18n[String, Kg] = + context[Kg](sc, params.toList) + def ki(params: I18nStringParam[Ki]*): I18n[String, Ki] = + context[Ki](sc, params.toList) + def kj(params: I18nStringParam[Kj]*): I18n[String, Kj] = + context[Kj](sc, params.toList) + def kk(params: I18nStringParam[Kk]*): I18n[String, Kk] = + context[Kk](sc, params.toList) + def kl(params: I18nStringParam[Kl]*): I18n[String, Kl] = + context[Kl](sc, params.toList) + def km(params: I18nStringParam[Km]*): I18n[String, Km] = + context[Km](sc, params.toList) + def kn(params: I18nStringParam[Kn]*): I18n[String, Kn] = + context[Kn](sc, params.toList) + def ko(params: I18nStringParam[Ko]*): I18n[String, Ko] = + context[Ko](sc, params.toList) + def kr(params: I18nStringParam[Kr]*): I18n[String, Kr] = + context[Kr](sc, params.toList) + def ks(params: I18nStringParam[Ks]*): I18n[String, Ks] = + context[Ks](sc, params.toList) + def ku(params: I18nStringParam[Ku]*): I18n[String, Ku] = + context[Ku](sc, params.toList) + def kv(params: I18nStringParam[Kv]*): I18n[String, Kv] = + context[Kv](sc, params.toList) + def kw(params: I18nStringParam[Kw]*): I18n[String, Kw] = + context[Kw](sc, params.toList) + def ky(params: I18nStringParam[Ky]*): I18n[String, Ky] = + context[Ky](sc, params.toList) + def la(params: I18nStringParam[La]*): I18n[String, La] = + context[La](sc, params.toList) + def lb(params: I18nStringParam[Lb]*): I18n[String, Lb] = + context[Lb](sc, params.toList) + def lg(params: I18nStringParam[Lg]*): I18n[String, Lg] = + context[Lg](sc, params.toList) + def li(params: I18nStringParam[Li]*): I18n[String, Li] = + context[Li](sc, params.toList) + def ln(params: I18nStringParam[Ln]*): I18n[String, Ln] = + context[Ln](sc, params.toList) + def lo(params: I18nStringParam[Lo]*): I18n[String, Lo] = + context[Lo](sc, params.toList) + def lt(params: I18nStringParam[Lt]*): I18n[String, Lt] = + context[Lt](sc, params.toList) + def lu(params: I18nStringParam[Lu]*): I18n[String, Lu] = + context[Lu](sc, params.toList) + def lv(params: I18nStringParam[Lv]*): I18n[String, Lv] = + context[Lv](sc, params.toList) + def mg(params: I18nStringParam[Mg]*): I18n[String, Mg] = + context[Mg](sc, params.toList) + def mh(params: I18nStringParam[Mh]*): I18n[String, Mh] = + context[Mh](sc, params.toList) + def mi(params: I18nStringParam[Mi]*): I18n[String, Mi] = + context[Mi](sc, params.toList) + def mk(params: I18nStringParam[Mk]*): I18n[String, Mk] = + context[Mk](sc, params.toList) + def ml(params: I18nStringParam[Ml]*): I18n[String, Ml] = + context[Ml](sc, params.toList) + def mn(params: I18nStringParam[Mn]*): I18n[String, Mn] = + context[Mn](sc, params.toList) + def mr(params: I18nStringParam[Mr]*): I18n[String, Mr] = + context[Mr](sc, params.toList) + def ms(params: I18nStringParam[Ms]*): I18n[String, Ms] = + context[Ms](sc, params.toList) + def mt(params: I18nStringParam[Mt]*): I18n[String, Mt] = + context[Mt](sc, params.toList) + def my(params: I18nStringParam[My]*): I18n[String, My] = + context[My](sc, params.toList) + def na(params: I18nStringParam[Na]*): I18n[String, Na] = + context[Na](sc, params.toList) + def nb(params: I18nStringParam[Nb]*): I18n[String, Nb] = + context[Nb](sc, params.toList) + def nd(params: I18nStringParam[Nd]*): I18n[String, Nd] = + context[Nd](sc, params.toList) + def ne(params: I18nStringParam[Ne]*): I18n[String, Ne] = + context[Ne](sc, params.toList) + def ng(params: I18nStringParam[Ng]*): I18n[String, Ng] = + context[Ng](sc, params.toList) + def nl(params: I18nStringParam[Nl]*): I18n[String, Nl] = + context[Nl](sc, params.toList) + def nn(params: I18nStringParam[Nn]*): I18n[String, Nn] = + context[Nn](sc, params.toList) + def no(params: I18nStringParam[No]*): I18n[String, No] = + context[No](sc, params.toList) + def nr(params: I18nStringParam[Nr]*): I18n[String, Nr] = + context[Nr](sc, params.toList) + def nv(params: I18nStringParam[Nv]*): I18n[String, Nv] = + context[Nv](sc, params.toList) + def ny(params: I18nStringParam[Ny]*): I18n[String, Ny] = + context[Ny](sc, params.toList) + def oc(params: I18nStringParam[Oc]*): I18n[String, Oc] = + context[Oc](sc, params.toList) + def oj(params: I18nStringParam[Oj]*): I18n[String, Oj] = + context[Oj](sc, params.toList) + def om(params: I18nStringParam[Om]*): I18n[String, Om] = + context[Om](sc, params.toList) + def or(params: I18nStringParam[Or]*): I18n[String, Or] = + context[Or](sc, params.toList) + def os(params: I18nStringParam[Os]*): I18n[String, Os] = + context[Os](sc, params.toList) + def pa(params: I18nStringParam[Pa]*): I18n[String, Pa] = + context[Pa](sc, params.toList) + def pi(params: I18nStringParam[Pi]*): I18n[String, Pi] = + context[Pi](sc, params.toList) + def pl(params: I18nStringParam[Pl]*): I18n[String, Pl] = + context[Pl](sc, params.toList) + def ps(params: I18nStringParam[Ps]*): I18n[String, Ps] = + context[Ps](sc, params.toList) + def pt(params: I18nStringParam[Pt]*): I18n[String, Pt] = + context[Pt](sc, params.toList) + def qu(params: I18nStringParam[Qu]*): I18n[String, Qu] = + context[Qu](sc, params.toList) + def rm(params: I18nStringParam[Rm]*): I18n[String, Rm] = + context[Rm](sc, params.toList) + def rn(params: I18nStringParam[Rn]*): I18n[String, Rn] = + context[Rn](sc, params.toList) + def ro(params: I18nStringParam[Ro]*): I18n[String, Ro] = + context[Ro](sc, params.toList) + def ru(params: I18nStringParam[Ru]*): I18n[String, Ru] = + context[Ru](sc, params.toList) + def rw(params: I18nStringParam[Rw]*): I18n[String, Rw] = + context[Rw](sc, params.toList) + def sa(params: I18nStringParam[Sa]*): I18n[String, Sa] = + context[Sa](sc, params.toList) + def sc(params: I18nStringParam[Sc]*): I18n[String, Sc] = + context[Sc](sc, params.toList) + def sd(params: I18nStringParam[Sd]*): I18n[String, Sd] = + context[Sd](sc, params.toList) + def se(params: I18nStringParam[Se]*): I18n[String, Se] = + context[Se](sc, params.toList) + def sg(params: I18nStringParam[Sg]*): I18n[String, Sg] = + context[Sg](sc, params.toList) + def si(params: I18nStringParam[Si]*): I18n[String, Si] = + context[Si](sc, params.toList) + def sk(params: I18nStringParam[Sk]*): I18n[String, Sk] = + context[Sk](sc, params.toList) + def sl(params: I18nStringParam[Sl]*): I18n[String, Sl] = + context[Sl](sc, params.toList) + def sm(params: I18nStringParam[Sm]*): I18n[String, Sm] = + context[Sm](sc, params.toList) + def sn(params: I18nStringParam[Sn]*): I18n[String, Sn] = + context[Sn](sc, params.toList) + def so(params: I18nStringParam[So]*): I18n[String, So] = + context[So](sc, params.toList) + def sq(params: I18nStringParam[Sq]*): I18n[String, Sq] = + context[Sq](sc, params.toList) + def sr(params: I18nStringParam[Sr]*): I18n[String, Sr] = + context[Sr](sc, params.toList) + def ss(params: I18nStringParam[Ss]*): I18n[String, Ss] = + context[Ss](sc, params.toList) + def st(params: I18nStringParam[St]*): I18n[String, St] = + context[St](sc, params.toList) + def su(params: I18nStringParam[Su]*): I18n[String, Su] = + context[Su](sc, params.toList) + def sv(params: I18nStringParam[Sv]*): I18n[String, Sv] = + context[Sv](sc, params.toList) + def sw(params: I18nStringParam[Sw]*): I18n[String, Sw] = + context[Sw](sc, params.toList) + def ta(params: I18nStringParam[Ta]*): I18n[String, Ta] = + context[Ta](sc, params.toList) + def te(params: I18nStringParam[Te]*): I18n[String, Te] = + context[Te](sc, params.toList) + def tg(params: I18nStringParam[Tg]*): I18n[String, Tg] = + context[Tg](sc, params.toList) + def th(params: I18nStringParam[Th]*): I18n[String, Th] = + context[Th](sc, params.toList) + def ti(params: I18nStringParam[Ti]*): I18n[String, Ti] = + context[Ti](sc, params.toList) + def tk(params: I18nStringParam[Tk]*): I18n[String, Tk] = + context[Tk](sc, params.toList) + def tl(params: I18nStringParam[Tl]*): I18n[String, Tl] = + context[Tl](sc, params.toList) + def tn(params: I18nStringParam[Tn]*): I18n[String, Tn] = + context[Tn](sc, params.toList) + def to(params: I18nStringParam[To]*): I18n[String, To] = + context[To](sc, params.toList) + def tr(params: I18nStringParam[Tr]*): I18n[String, Tr] = + context[Tr](sc, params.toList) + def ts(params: I18nStringParam[Ts]*): I18n[String, Ts] = + context[Ts](sc, params.toList) + def tt(params: I18nStringParam[Tt]*): I18n[String, Tt] = + context[Tt](sc, params.toList) + def tw(params: I18nStringParam[Tw]*): I18n[String, Tw] = + context[Tw](sc, params.toList) + def ty(params: I18nStringParam[Ty]*): I18n[String, Ty] = + context[Ty](sc, params.toList) + def ug(params: I18nStringParam[Ug]*): I18n[String, Ug] = + context[Ug](sc, params.toList) + def uk(params: I18nStringParam[Uk]*): I18n[String, Uk] = + context[Uk](sc, params.toList) + def ur(params: I18nStringParam[Ur]*): I18n[String, Ur] = + context[Ur](sc, params.toList) + def uz(params: I18nStringParam[Uz]*): I18n[String, Uz] = + context[Uz](sc, params.toList) + def ve(params: I18nStringParam[Ve]*): I18n[String, Ve] = + context[Ve](sc, params.toList) + def vi(params: I18nStringParam[Vi]*): I18n[String, Vi] = + context[Vi](sc, params.toList) + def vo(params: I18nStringParam[Vo]*): I18n[String, Vo] = + context[Vo](sc, params.toList) + def wa(params: I18nStringParam[Wa]*): I18n[String, Wa] = + context[Wa](sc, params.toList) + def wo(params: I18nStringParam[Wo]*): I18n[String, Wo] = + context[Wo](sc, params.toList) + def xh(params: I18nStringParam[Xh]*): I18n[String, Xh] = + context[Xh](sc, params.toList) + def yi(params: I18nStringParam[Yi]*): I18n[String, Yi] = + context[Yi](sc, params.toList) + def yo(params: I18nStringParam[Yo]*): I18n[String, Yo] = + context[Yo](sc, params.toList) + def za(params: I18nStringParam[Za]*): I18n[String, Za] = + context[Za](sc, params.toList) + def zh(params: I18nStringParam[Zh]*): I18n[String, Zh] = + context[Zh](sc, params.toList) + def zu(params: I18nStringParam[Zu]*): I18n[String, Zu] = + context[Zu](sc, params.toList) + } } object Macros { - - def missingTranslationsMacro[ToLang <: Language: c.WeakTypeTag, FromLang <: Language: c.WeakTypeTag](c: - BlackboxContext)(from: c.Expr[I18n[String, FromLang]]): c.Expr[I18n[String, ToLang]] = { - + + def missingTranslationsMacro[ToLang <: Language : c.WeakTypeTag, + FromLang <: Language : c.WeakTypeTag]( + c: BlackboxContext)( + from: c.Expr[I18n[String, FromLang]]): c.Expr[I18n[String, ToLang]] = { + import c.universe._ import compatibility._ @@ -245,22 +434,29 @@ object Macros { val missing = toLangs -- fromLangs def langs(tree: Tree): Map[String, String] = tree match { - case Apply(Select(Apply(Select(Select(Select(id1, id2), id3), id4), List(Apply(_, List(Literal(Constant( - str: String)))))), lang), _) if id1.toString == "rapture" && id2.toString == "i18n" && - id3.toString == "package" && id4.toString == "I18nEnrichedStringContext" => - + case Apply( + Select(Apply(Select(Select(Select(id1, id2), id3), id4), + List(Apply(_, List(Literal(Constant(str: String)))))), + lang), + _) + if id1.toString == "rapture" && id2.toString == "i18n" && + id3.toString == "package" && + id4.toString == "I18nEnrichedStringContext" => Map(lang.toString -> str) - + case Apply(app: Apply, _) => langs(app) - - case Apply(TypeApply(Select(q, id6), _), List(app)) if id6.toString == "$bar" => + + case Apply(TypeApply(Select(q, id6), _), List(app)) + if id6.toString == "$bar" => langs(q) ++ langs(app) } - if(!missing.isEmpty) - c.abort(c.enclosingPosition, s"""Some language translations were not provided: ${missing.mkString(", ")}""") - else - reify(from.splice.asInstanceOf[I18n[String, ToLang]]) + if (!missing.isEmpty) + c.abort( + c.enclosingPosition, + s"""Some language translations were not provided: ${missing.mkString( + ", ")}""") + else reify(from.splice.asInstanceOf[I18n[String, ToLang]]) } } diff --git a/i18n/shared/src/test/scala/rapture/i18n/tests.scala b/i18n/shared/src/test/scala/rapture/i18n/tests.scala index 3af3770..d53b45a 100644 --- a/i18n/shared/src/test/scala/rapture/i18n/tests.scala +++ b/i18n/shared/src/test/scala/rapture/i18n/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.i18n.test @@ -29,106 +29,121 @@ object I18nTests extends TestSuite { import languages._ - val `Create basic English string` = test { - val greetingEn: I18n[String, En] = en"Hello world" - greetingEn[En] - } returns "Hello world" - - val `Create basic French string` = test { - val greetingFr: I18n[String, Fr] = fr"Bonjour le monde" - greetingFr[Fr] - } returns "Bonjour le monde" - - val `Create combined internationalized strings, getting English` = test { - val greeting = en"Hello world" & fr"Bonjour le monde" - greeting[En] - } returns "Hello world" - - val `Create combined internationalized strings, getting French` = test { - val greeting = en"Hello world" & fr"Bonjour le monde" - greeting[Fr] - } returns "Bonjour le monde" - - val `Check providing surplus language definitions allowed` = test { - val greeting = en"Hello world" & fr"Bonjour le monde" - val en: I18n[String, En] = greeting - val fr: I18n[String, Fr] = greeting - val both: I18n[String, En with Fr] = greeting - } returns () - - val `Check internationalized substitution` = test { - val greeting = en"Hello world" & fr"Bonjour le monde" - val msg = en"In English, we say '$greeting'" - msg[En] - } returns "In English, we say 'Hello world'" - - val `Check internationalized substitution (French)` = test { - val greeting = en"Hello world" & fr"Bonjour le monde" - val msg = fr"En français, on dit '$greeting'" - msg[Fr] - } returns "En français, on dit 'Bonjour le monde'" - - val `Substitute ordinary string` = test { - val lang = "Scala" - val msg = en"I speak $lang." & fr"Je parle $lang." & de"Ich spreche $lang." - msg[De] - } returns "Ich spreche Scala." - + val `Create basic English string` = + test { + val greetingEn: I18n[String, En] = en"Hello world" + greetingEn[En] + } returns "Hello world" + + val `Create basic French string` = + test { + val greetingFr: I18n[String, Fr] = fr"Bonjour le monde" + greetingFr[Fr] + } returns "Bonjour le monde" + + val `Create combined internationalized strings, getting English` = + test { + val greeting = en"Hello world" & fr"Bonjour le monde" + greeting[En] + } returns "Hello world" + + val `Create combined internationalized strings, getting French` = + test { + val greeting = en"Hello world" & fr"Bonjour le monde" + greeting[Fr] + } returns "Bonjour le monde" + + val `Check providing surplus language definitions allowed` = + test { + val greeting = en"Hello world" & fr"Bonjour le monde" + val en: I18n[String, En] = greeting + val fr: I18n[String, Fr] = greeting + val both: I18n[String, En with Fr] = greeting + } returns () + + val `Check internationalized substitution` = + test { + val greeting = en"Hello world" & fr"Bonjour le monde" + val msg = en"In English, we say '$greeting'" + msg[En] + } returns "In English, we say 'Hello world'" + + val `Check internationalized substitution (French)` = + test { + val greeting = en"Hello world" & fr"Bonjour le monde" + val msg = fr"En français, on dit '$greeting'" + msg[Fr] + } returns "En français, on dit 'Bonjour le monde'" + + val `Substitute ordinary string` = + test { + val lang = "Scala" + val msg = + en"I speak $lang." & fr"Je parle $lang." & de"Ich spreche $lang." + msg[De] + } returns "Ich spreche Scala." object MyMessages extends LanguageBundle[En with Fr] { val greeting: IString = en"Hello world" & fr"Bonjour le monde" } - val `Test message bundle` = test { - MyMessages.greeting[En] - } returns "Hello world" - - val `Test message bundle (French)` = test { - MyMessages.greeting[Fr] - } returns "Bonjour le monde" - - val `Use default language` = test { - import languages.fr._ - val str: String = MyMessages.greeting - str - } returns "Bonjour le monde" - - val `Adding existing language does not compile` = test { - typeMismatch { - import deferTypeErrors._ - en"a" & fr"b" & en"c" - } - } returns true - - val `Adding existing language does not compile (2)` = test { - typeMismatch { - import deferTypeErrors._ - (en"a" & fr"b") & (de"c" & en"d") - } - } returns true - - val `Get language string using runtime value` = test { - val msg = en"Hello" & fr"Bonjour" - val langs = en | fr - implicit val loc = langs.parse("FR") - msg: String - } returns "Bonjour" - - val `Get language string from subset using runtime value` = test { - typeMismatch { - import deferTypeErrors._ + val `Test message bundle` = + test { + MyMessages.greeting[En] + } returns "Hello world" + + val `Test message bundle (French)` = + test { + MyMessages.greeting[Fr] + } returns "Bonjour le monde" + + val `Use default language` = + test { + import languages.fr._ + val str: String = MyMessages.greeting + str + } returns "Bonjour le monde" + + val `Adding existing language does not compile` = + test { + typeMismatch { + import deferTypeErrors._ + en"a" & fr"b" & en"c" + } + } returns true + + val `Adding existing language does not compile (2)` = + test { + typeMismatch { + import deferTypeErrors._ + (en"a" & fr"b") & (de"c" & en"d") + } + } returns true + + val `Get language string using runtime value` = + test { val msg = en"Hello" & fr"Bonjour" - val langs = en | fr | de + val langs = en | fr implicit val loc = langs.parse("FR") msg: String - } - } returns true - - val `Get language string from superset using runtime value` = test { - val msg = en"Hello" & fr"Bonjour" & de"Hallo" - val langs = en | fr - implicit val loc = langs.parse("FR") - msg: String - } returns "Bonjour" - + } returns "Bonjour" + + val `Get language string from subset using runtime value` = + test { + typeMismatch { + import deferTypeErrors._ + val msg = en"Hello" & fr"Bonjour" + val langs = en | fr | de + implicit val loc = langs.parse("FR") + msg: String + } + } returns true + + val `Get language string from superset using runtime value` = + test { + val msg = en"Hello" & fr"Bonjour" & de"Hallo" + val langs = en | fr + implicit val loc = langs.parse("FR") + msg: String + } returns "Bonjour" } diff --git a/io/shared/src/main/scala/rapture/io/copy.scala b/io/shared/src/main/scala/rapture/io/copy.scala index 02ba86a..3a7d671 100644 --- a/io/shared/src/main/scala/rapture/io/copy.scala +++ b/io/shared/src/main/scala/rapture/io/copy.scala @@ -13,13 +13,14 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ trait Copyable_1 { - implicit def streamableCopyable[SrcType, DestType](implicit reader: Reader[SrcType, Byte], + implicit def streamableCopyable[SrcType, DestType]( + implicit reader: Reader[SrcType, Byte], writer: Writer[DestType, Byte]): Copyable[SrcType, DestType] = new Copyable[SrcType, DestType] { def copy(src: SrcType, dest: DestType): Copyable.Summary = { @@ -38,7 +39,8 @@ object Copyable extends Copyable_1 { } class Capability[SrcType](from: SrcType) { - def copyTo[DestType](to: DestType)(implicit mode: Mode[`Copyable#copyTo`], + def copyTo[DestType](to: DestType)( + implicit mode: Mode[`Copyable#copyTo`], copyable: Copyable[SrcType, DestType]): mode.Wrap[Summary, Exception] = mode.wrap(?[Copyable[SrcType, DestType]].copy(from, to)) } diff --git a/io/shared/src/main/scala/rapture/io/delete.scala b/io/shared/src/main/scala/rapture/io/delete.scala index d9e2455..ab29cc5 100644 --- a/io/shared/src/main/scala/rapture/io/delete.scala +++ b/io/shared/src/main/scala/rapture/io/delete.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -30,9 +30,10 @@ object Deletable { class Capability[Res](res: Res) { def delete()(implicit mode: Mode[`Deletable#delete`], - deleter: Deleter[Res]): mode.Wrap[Summary, Exception] = mode wrap { - deleter.delete(res) - Summary(1) - } + deleter: Deleter[Res]): mode.Wrap[Summary, Exception] = + mode wrap { + deleter.delete(res) + Summary(1) + } } } diff --git a/io/shared/src/main/scala/rapture/io/guid.scala b/io/shared/src/main/scala/rapture/io/guid.scala index 89c6e98..153b109 100644 --- a/io/shared/src/main/scala/rapture/io/guid.scala +++ b/io/shared/src/main/scala/rapture/io/guid.scala @@ -13,13 +13,14 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ object Guid { - private val GuidPattern = """^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$""".r + private val GuidPattern = + """^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$""".r def generate() = Guid(java.util.UUID.randomUUID().toString) } diff --git a/io/shared/src/main/scala/rapture/io/io.scala b/io/shared/src/main/scala/rapture/io/io.scala index f9e8ed2..4900af2 100644 --- a/io/shared/src/main/scala/rapture/io/io.scala +++ b/io/shared/src/main/scala/rapture/io/io.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io @@ -24,25 +24,26 @@ import java.io._ import language.reflectiveCalls object javaResources { - + type StructuralReadable = { def getInputStream(): InputStream } type StructuralWritable = { def getOutputStream(): OutputStream } - + implicit val structuralReader = new JavaInputStreamReader[StructuralReadable](_.getInputStream()) - + implicit val structuralWriter = new JavaOutputStreamWriter[StructuralWritable](_.getOutputStream()) - implicit val javaFileReader = new JavaInputStreamReader[java.io.File]( - new java.io.FileInputStream(_)) - - implicit val javaNioPathReader = new JavaInputStreamReader[java.nio.file.Path]( - java.nio.file.Files.newInputStream(_)) - - implicit val javaFileWriter = new JavaOutputStreamWriter[java.io.File]( - new java.io.FileOutputStream(_)) - - implicit val javaFileAppender = new JavaOutputAppender[java.io.File](f => - alloc[java.io.FileOutputStream](f, true)) + implicit val javaFileReader = + new JavaInputStreamReader[java.io.File](new java.io.FileInputStream(_)) + + implicit val javaNioPathReader = + new JavaInputStreamReader[java.nio.file.Path]( + java.nio.file.Files.newInputStream(_)) + + implicit val javaFileWriter = + new JavaOutputStreamWriter[java.io.File](new java.io.FileOutputStream(_)) + + implicit val javaFileAppender = new JavaOutputAppender[java.io.File]( + f => alloc[java.io.FileOutputStream](f, true)) } diff --git a/io/shared/src/main/scala/rapture/io/money.scala b/io/shared/src/main/scala/rapture/io/money.scala index f4edcb3..28dfd05 100644 --- a/io/shared/src/main/scala/rapture/io/money.scala +++ b/io/shared/src/main/scala/rapture/io/money.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -33,21 +33,34 @@ object Finance { trait Nzd trait Rub - class Currency[T](val code: String, val name: String, val dp: Int, val prefix: String) - implicit val GbpCurrency: Currency[Gbp] = alloc("GBP", "Pounds Sterling", 2, "£") + class Currency[T]( + val code: String, val name: String, val dp: Int, val prefix: String) + implicit val GbpCurrency: Currency[Gbp] = alloc( + "GBP", "Pounds Sterling", 2, "£") implicit val UsdCurrency: Currency[Usd] = alloc("USD", "US Dollars", 2, "$") - implicit val ChfCurrency: Currency[Chf] = alloc("CHF", "Swiss Francs", 2, "Fr") + implicit val ChfCurrency: Currency[Chf] = alloc( + "CHF", "Swiss Francs", 2, "Fr") implicit val EurCurrency: Currency[Eur] = alloc("EUR", "Euros", 2, "€") - implicit val CadCurrency: Currency[Cad] = alloc("CAD", "Canadian Dollars", 2, "$") - implicit val CnyCurrency: Currency[Cny] = alloc("CNY", "Chinese Yuan", 2, "¥") - implicit val DkkCurrency: Currency[Dkk] = alloc("DKK", "Danish Krone", 2, "kr") - implicit val InrCurrency: Currency[Inr] = alloc("INR", "Indian Rupees", 2, "Rs") - implicit val JpyCurrency: Currency[Jpy] = alloc("JPY", "Japanese Yen", 2, "¥") - implicit val NokCurrency: Currency[Nok] = alloc("NOK", "Norwegian Krone", 2, "kr") - implicit val NzdCurrency: Currency[Nzd] = alloc("NZD", "New Zealand Dollars", 2, "$") - implicit val RubCurrency: Currency[Rub] = alloc("RUB", "Russian Rubles", 2, "р") - - trait MoneyFactory[T] { def apply(d: Double)(implicit currency: Currency[T]): Money[T] = alloc(d) } + implicit val CadCurrency: Currency[Cad] = alloc( + "CAD", "Canadian Dollars", 2, "$") + implicit val CnyCurrency: Currency[Cny] = alloc( + "CNY", "Chinese Yuan", 2, "¥") + implicit val DkkCurrency: Currency[Dkk] = alloc( + "DKK", "Danish Krone", 2, "kr") + implicit val InrCurrency: Currency[Inr] = alloc( + "INR", "Indian Rupees", 2, "Rs") + implicit val JpyCurrency: Currency[Jpy] = alloc( + "JPY", "Japanese Yen", 2, "¥") + implicit val NokCurrency: Currency[Nok] = alloc( + "NOK", "Norwegian Krone", 2, "kr") + implicit val NzdCurrency: Currency[Nzd] = alloc( + "NZD", "New Zealand Dollars", 2, "$") + implicit val RubCurrency: Currency[Rub] = alloc( + "RUB", "Russian Rubles", 2, "р") + + trait MoneyFactory[T] { + def apply(d: Double)(implicit currency: Currency[T]): Money[T] = alloc(d) + } object Usd extends MoneyFactory[Usd] object Gbp extends MoneyFactory[Gbp] @@ -62,36 +75,38 @@ object Finance { object Nzd extends MoneyFactory[Nzd] object Rub extends MoneyFactory[Rub] - case class Money[T: Currency](major: Int, minor: Int) { + case class Money[T : Currency](major: Int, minor: Int) { val div = math.pow(10, ?[Currency[T]].dp).toInt - val half = 0.5/div + val half = 0.5 / div def this(amount: Double) = - this((amount*math.pow(10, ?[Currency[T]].dp).toInt + 0.5).toInt/math.pow(10, - ?[Currency[T]].dp).toInt, (amount*math.pow(10, - ?[Currency[T]].dp).toInt + 0.5).toInt%math.pow(10, - ?[Currency[T]].dp).toInt) + this((amount * math.pow(10, ?[Currency[T]].dp).toInt + + 0.5).toInt / math.pow(10, ?[Currency[T]].dp).toInt, + (amount * math.pow(10, ?[Currency[T]].dp).toInt + + 0.5).toInt % math.pow(10, ?[Currency[T]].dp).toInt) - def pad(x: Int) = ("0"*(?[Currency[T]].dp - x.toString.length))+x + def pad(x: Int) = ("0" * (?[Currency[T]].dp - x.toString.length)) + x - override def toString = ?[Currency[T]].prefix+amountString + override def toString = ?[Currency[T]].prefix + amountString def amountString = - if(major < 0) "-"+(-major - 1)+"."+pad(div - minor) else major+"."+pad(minor) + if (major < 0) "-" + (-major - 1) + "." + pad(div - minor) + else major + "." + pad(minor) def +(m: Money[T]): Money[T] = - Money[T](major + m.major + (minor + m.minor)/div, (minor + m.minor)%div) - + Money[T]( + major + m.major + (minor + m.minor) / div, (minor + m.minor) % div) + def unary_- : Money[T] = Money[T](-major - 1, div - minor) def -(m: Money[T]): Money[T] = this + -m def *(n: Int): Money[T] = this * n.toDouble def *(n: Double): Money[T] = { - val x = ((major*div + minor)*n + 0.5).toInt - Money[T](x/div, x%div) + val x = ((major * div + minor) * n + 0.5).toInt + Money[T](x / div, x % div) } - - def /(n: Int): Money[T] = this * (1.0/n) - def /(n: Double): Money[T] = this * (1.0/n) + + def /(n: Int): Money[T] = this * (1.0 / n) + def /(n: Double): Money[T] = this * (1.0 / n) } } diff --git a/io/shared/src/main/scala/rapture/io/move.scala b/io/shared/src/main/scala/rapture/io/move.scala index bb23795..fa4388b 100644 --- a/io/shared/src/main/scala/rapture/io/move.scala +++ b/io/shared/src/main/scala/rapture/io/move.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -27,7 +27,8 @@ object Movable { } class Capability[FromType](from: FromType) { - def moveTo[ToType](to: ToType)(implicit mode: Mode[`Movable#moveTo`], + def moveTo[ToType](to: ToType)( + implicit mode: Mode[`Movable#moveTo`], movable: Movable[FromType, ToType]): mode.Wrap[Summary, Exception] = mode.wrap(?[Movable[FromType, ToType]].move(from, to)) } diff --git a/io/shared/src/main/scala/rapture/io/multipart.scala b/io/shared/src/main/scala/rapture/io/multipart.scala index f570fe1..dc5132c 100644 --- a/io/shared/src/main/scala/rapture/io/multipart.scala +++ b/io/shared/src/main/scala/rapture/io/multipart.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -32,28 +32,32 @@ case class Multipart(data: Array[Byte], headers: Map[String, String]) { headers.get("Content-Disposition") flatMap { v => v.split("; *").to[List] match { case h :: t => - val m = t.map({ a => - val b = a.split("=") - b(0) -> b(1) - }).toMap + val m = t + .map({ a => + val b = a.split("=") + b(0) -> b(1) + }) + .toMap Some(h -> m) case _ => None } } - def filename: Option[String] = contentDisposition flatMap { case (_, m) => m.get("filename") } + def filename: Option[String] = + contentDisposition flatMap { case (_, m) => m.get("filename") } - def name: Option[String] = contentDisposition flatMap { case (_, m) => m.get("name") } + def name: Option[String] = + contentDisposition flatMap { case (_, m) => m.get("name") } def disposition: Option[String] = contentDisposition.map(_._1) - } -class MultipartReader(boundary: String, in: java.io.InputStream, val sizeLimit: Int = 160) +class MultipartReader( + boundary: String, in: java.io.InputStream, val sizeLimit: Int = 160) extends Input[Multipart] { - - private val bnd = ("--"+boundary).getBytes("ASCII") - + + private val bnd = ("--" + boundary).getBytes("ASCII") + private var finished = false private var cued = next() @@ -66,7 +70,7 @@ class MultipartReader(boundary: String, in: java.io.InputStream, val sizeLimit: } private def next(): Option[Multipart] = { - + var buf: Array[Byte] = null var count = -1 val bufs = alloc[ListBuffer[Array[Byte]]]() @@ -75,59 +79,65 @@ class MultipartReader(boundary: String, in: java.io.InputStream, val sizeLimit: var dataStart = 0 var boundmatch: Int = 0 - while(!finished) { + while (!finished) { var cur = in.read() - - if(buf != null && dataStart == 0 && (buf(count%65536) == 10 && cur == 13 || - buf(count%65536) == 13 && cur == 10)) { + + if (buf != null && dataStart == 0 && + (buf(count % 65536) == 10 && cur == 13 || buf(count % 65536) == 13 && + cur == 10)) { // do nothing - } else if(buf != null && dataStart == 0 && (cur == 10 || cur == 13 && - buf(count%65536) == cur)) { + } else if (buf != null && dataStart == 0 && + (cur == 10 || cur == 13 && buf(count % 65536) == cur)) { dataStart = count + 1 val next = in.read().toByte - if(next != 10 && next != 13) { + if (next != 10 && next != 13) { count += 1 - buf(count%65536) = next + buf(count % 65536) = next } - headers = alloc[String](buf.slice(1, dataStart), "ISO-8859-1").split("\r").map({ h => - val i = h.indexOf(':') - h.substring(0, i) -> h.substring(i + 2, h.length) - }).toMap + headers = alloc[String](buf.slice(1, dataStart), "ISO-8859-1") + .split("\r") + .map({ h => + val i = h.indexOf(':') + h.substring(0, i) -> h.substring(i + 2, h.length) + }) + .toMap } else { count += 1 - - if(cur == -1) { + + if (cur == -1) { finished = true return None } - - if(count%65536 == 0) { - if(count > sizeLimit) throw alloc[RuntimeException]("Upload size limit exceeded.") + + if (count % 65536 == 0) { + if (count > sizeLimit) + throw alloc[RuntimeException]("Upload size limit exceeded.") buf = alloc(65536) bufs += buf } - - buf(count%65536) = cur.toByte - - boundmatch = if(buf(count%65536) == bnd(boundmatch)) boundmatch + 1 else 0 - - if(boundmatch == bnd.length) { + + buf(count % 65536) = cur.toByte + + boundmatch = if (buf(count % 65536) == bnd(boundmatch)) boundmatch + 1 + else 0 + + if (boundmatch == bnd.length) { val dataEnd = count - boundmatch - 1 val size = dataEnd - dataStart - - if(size >= 0) { + + if (size >= 0) { val res: Array[Byte] = alloc(size) var done = 0 var i = 0 var offset = dataStart - while(done < size) { + while (done < size) { val chunk = List(65536 - offset, size - done).min System.arraycopy(bufs(i), offset, res, done, chunk) done += chunk offset = 0 i += 1 } - + return Some(Multipart(res, headers)) } else { count = -1 @@ -142,4 +152,3 @@ class MultipartReader(boundary: String, in: java.io.InputStream, val sizeLimit: None } } - diff --git a/io/shared/src/main/scala/rapture/io/package.scala b/io/shared/src/main/scala/rapture/io/package.scala index 3522a3d..04f7557 100644 --- a/io/shared/src/main/scala/rapture/io/package.scala +++ b/io/shared/src/main/scala/rapture/io/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io @@ -33,25 +33,26 @@ trait `Movable#moveTo` extends MethodConstraint trait `Deletable#delete` extends MethodConstraint object `package` { - + /** Views an `Input[Byte]` as a `java.io.InputStream` */ implicit def inputStreamUnwrapper(is: Input[Byte]): InputStream = new InputStream { def read() = is.read().map(_.toInt).getOrElse(-1) } - implicit def classpathStreamByteReader(implicit cl: ClassLoader): JavaInputStreamReader[ClasspathUrl] = + implicit def classpathStreamByteReader( + implicit cl: ClassLoader): JavaInputStreamReader[ClasspathUrl] = ClasspathStream.classpathStreamByteReader - def ensuring[Res, Strm: Closable](create: Strm)(body: Strm => Res): - Res = Utils.ensuring[Res, Strm](create)(body) + def ensuring[Res, Strm : Closable](create: Strm)(body: Strm => Res): Res = + Utils.ensuring[Res, Strm](create)(body) implicit def stringMethods(s: String): StringMethods = alloc(s) implicit def copyable[Res](res: Res): Copyable.Capability[Res] = alloc(res) - implicit def appendable[Res](res: Res): Appendable.Capability[Res] = alloc(res) + implicit def appendable[Res](res: Res): Appendable.Capability[Res] = + alloc(res) implicit def readable[Res](res: Res): Readable.Capability[Res] = alloc(res) implicit def deletable[Res](res: Res): Deletable.Capability[Res] = alloc(res) implicit def slurpable[Res](res: Res): Slurpable.Capability[Res] = alloc(res) implicit def writable[Res](res: Res): Writable.Capability[Res] = alloc(res) implicit def movable[Res](res: Res): Movable.Capability[Res] = alloc(res) implicit def sizable[Res](res: Res): Sizable.Capability[Res] = alloc(res) - } diff --git a/io/shared/src/main/scala/rapture/io/size.scala b/io/shared/src/main/scala/rapture/io/size.scala index e8672b6..37514f2 100644 --- a/io/shared/src/main/scala/rapture/io/size.scala +++ b/io/shared/src/main/scala/rapture/io/size.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -22,32 +22,36 @@ import scala.reflect._ object Sizable { class Capability[Res](res: Res) { + /** Returns the size in bytes of this resource */ - def size[Data](implicit mode: Mode[`Sizable#size`], sizable: Sizable[Res, Data]): mode.Wrap[Long, Exception] = + def size[Data](implicit mode: Mode[`Sizable#size`], + sizable: Sizable[Res, Data]): mode.Wrap[Long, Exception] = mode wrap sizable.size(res) } - implicit def charSizable[Res, Data: ClassTag](implicit reader: Reader[Res, Data]): Sizable[Res, Data] = new Sizable[Res, Data] { - private def accumulator() = new Accumulator[Data, Long] with Output[Data] { - private var count = 0 - def buffer: Long = count - def write(b: Data) = count += 1 - def flush(): Unit = () - def close(): Unit = () - } - - def size(res: Res): Long = { - val acc = accumulator() - res.handleInput[Data, Int](_ pumpTo acc) - acc.buffer + implicit def charSizable[Res, Data : ClassTag]( + implicit reader: Reader[Res, Data]): Sizable[Res, Data] = + new Sizable[Res, Data] { + private def accumulator() = + new Accumulator[Data, Long] with Output[Data] { + private var count = 0 + def buffer: Long = count + def write(b: Data) = count += 1 + def flush(): Unit = () + def close(): Unit = () + } + + def size(res: Res): Long = { + val acc = accumulator() + res.handleInput[Data, Int](_ pumpTo acc) + acc.buffer + } } - } } trait Sizable[Res, Data] { type ExceptionType <: Exception + /** Returns the number of units of the specified resource */ def size(res: Res): Long } - - diff --git a/io/shared/src/main/scala/rapture/io/slurp.scala b/io/shared/src/main/scala/rapture/io/slurp.scala index a3ecfa3..a415e34 100644 --- a/io/shared/src/main/scala/rapture/io/slurp.scala +++ b/io/shared/src/main/scala/rapture/io/slurp.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io @@ -25,13 +25,18 @@ import scala.reflect._ import java.io._ trait AccumulatorBuilder_1 { - implicit val byteAccumulator: AccumulatorBuilder[Byte] { type Out = Bytes } = ByteAccumulator - implicit val stringAccumulator: AccumulatorBuilder[String] { type Out = String } = StringAccumulator + implicit val byteAccumulator: AccumulatorBuilder[Byte] { type Out = Bytes } = + ByteAccumulator + implicit val stringAccumulator: AccumulatorBuilder[String] { + type Out = String + } = StringAccumulator } object AccumulatorBuilder extends AccumulatorBuilder_1 { - implicit val charAccumulator: AccumulatorBuilder[Char] { type Out = String } = CharAccumulator + implicit val charAccumulator: AccumulatorBuilder[Char] { type Out = String } = + CharAccumulator } + /** Interface for an accumulator which is a special kind of output which collects and stores all * input in a buffer which can be retrieved afterwards. No guarantees are made about input * supplied after the buffer has been retrieved. @@ -87,6 +92,7 @@ class StringOutput extends { object Slurpable { class Capability[Res](res: Res) { + /** Reads in the entirety of the stream and accumulates it into an appropriate object * depending on the availability of implicit Accumulator type class objects in scope. * @@ -94,8 +100,11 @@ object Slurpable { * @usecase def slurp[Byte](): Array[Byte] * @tparam Data The units of data being slurped * @return The accumulated data */ - def slurp[Data]()(implicit accumulatorBuilder: AccumulatorBuilder[Data], mode: Mode[`Slurpable#slurp`], - sr: Reader[Res, Data], mf: ClassTag[Data]): mode.Wrap[accumulatorBuilder.Out, Exception] = + def slurp[Data]( + )(implicit accumulatorBuilder: AccumulatorBuilder[Data], + mode: Mode[`Slurpable#slurp`], + sr: Reader[Res, Data], + mf: ClassTag[Data]): mode.Wrap[accumulatorBuilder.Out, Exception] = mode.wrap { val c = accumulatorBuilder.make() res.handleInput[Data, Int](_ pumpTo c) @@ -104,4 +113,3 @@ object Slurpable { } } } - diff --git a/io/shared/src/main/scala/rapture/io/streams.scala b/io/shared/src/main/scala/rapture/io/streams.scala index dcdf1f3..cb5d399 100644 --- a/io/shared/src/main/scala/rapture/io/streams.scala +++ b/io/shared/src/main/scala/rapture/io/streams.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -30,11 +30,14 @@ trait Closable[-R] { def close(resource: R): Unit } object Utils { /** Safely closes a stream after processing */ - def ensuring[Res, Strm: Closable](create: Strm)(blk: Strm => Res) = { + def ensuring[Res, Strm : Closable](create: Strm)(blk: Strm => Res) = { val stream = create val result = try { blk(stream) } catch { - case e: Throwable => try { implicitly[Closable[Strm]].close(stream) } catch { case e2: Exception => () } - throw e + case e: Throwable => + try { implicitly[Closable[Strm]].close(stream) } catch { + case e2: Exception => () + } + throw e } implicitly[Closable[Strm]].close(stream) @@ -44,29 +47,34 @@ object Utils { } /** Makes a `String` viewable as an `rapture.io.Input[Char]` */ -case class StringIsInput(string: String) extends CharInput(alloc[StringReader](string)) +case class StringIsInput(string: String) + extends CharInput(alloc[StringReader](string)) /** Makes an `Array[Byte]` viewable as an `Input[Byte]` */ -case class ByteArrayInput(array: Array[Byte]) extends ByteInput(alloc[ByteArrayInputStream](array)) +case class ByteArrayInput(array: Array[Byte]) + extends ByteInput(alloc[ByteArrayInputStream](array)) object InputBuilder { - implicit def stringInputBuilder(implicit encoding: Encoding): InputBuilder[InputStream, - String] = + implicit def stringInputBuilder( + implicit encoding: Encoding): InputBuilder[InputStream, String] = new InputBuilder[InputStream, String] { def input(s: InputStream): Input[String] = alloc[LineInput](alloc[InputStreamReader](s, encoding.name)) } + /** Type class definition for creating an Input[Char] from a Java InputStream, taking an * [[Encoding]] implicitly for converting between `Byte`s and `Char`s */ - implicit def inputStreamCharBuilder(implicit encoding: Encoding): - InputBuilder[InputStream, Char] = + implicit def inputStreamCharBuilder( + implicit encoding: Encoding): InputBuilder[InputStream, Char] = new InputBuilder[InputStream, Char] { def input(s: InputStream): Input[Char] = alloc[CharInput](alloc[InputStreamReader](s, encoding.name)) } - implicit val buildInputStream: InputBuilder[InputStream, Byte] = InputStreamBuilder + implicit val buildInputStream: InputBuilder[InputStream, Byte] = + InputStreamBuilder implicit val buildReader: InputBuilder[java.io.Reader, Char] = ReaderBuilder - implicit val buildLineReader: InputBuilder[java.io.Reader, String] = LineReaderBuilder + implicit val buildLineReader: InputBuilder[java.io.Reader, String] = + LineReaderBuilder } object Input { @@ -85,25 +93,25 @@ trait InputBuilder[InputType, Data] { } object OutputBuilder { - implicit val buildOutputStream: OutputBuilder[OutputStream, Byte] = OutputStreamBuilder + implicit val buildOutputStream: OutputBuilder[OutputStream, Byte] = + OutputStreamBuilder implicit val buildWriter: OutputBuilder[java.io.Writer, Char] = WriterBuilder - implicit def stringOutputBuilder(implicit encoding: Encoding): - OutputBuilder[OutputStream, String] = + implicit def stringOutputBuilder( + implicit encoding: Encoding): OutputBuilder[OutputStream, String] = new OutputBuilder[OutputStream, String] { def output(s: OutputStream): Output[String] = new LineOutput(new OutputStreamWriter(s, encoding.name)) } + /** Type class definition for creating an Output[Char] from a Java OutputStream, taking an * [[Encoding]] implicitly for converting between `Byte`s and `Char`s */ - implicit def outputStreamCharBuilder(implicit encoding: Encoding): - OutputBuilder[OutputStream, Char] = + implicit def outputStreamCharBuilder( + implicit encoding: Encoding): OutputBuilder[OutputStream, Char] = new OutputBuilder[OutputStream, Char] { def output(s: OutputStream): Output[Char] = alloc[CharOutput](alloc[OutputStreamWriter](s, encoding.name)) } - - } /** Type trait for building a new `Output[Data]` from particular kind of output stream @@ -122,53 +130,69 @@ object AppenderBuilder { } } -trait AppenderBuilder[OutputType, Data] { def appendOutput(s: OutputType): Output[Data] } +trait AppenderBuilder[OutputType, Data] { + def appendOutput(s: OutputType): Output[Data] +} object Appendable { class Capability[Res](res: Res) { - def appendOutput[Data](implicit sa: Appender[Res, Data], mode: Mode[`Appendable#appendOutput`]) = + def appendOutput[Data](implicit sa: Appender[Res, Data], + mode: Mode[`Appendable#appendOutput`]) = sa.appendOutput(res) - - def handleAppend[Data, Res2](body: Output[Data] => Res2)(implicit sw: - Appender[Res, Data]): Res2 = { + + def handleAppend[Data, Res2](body: Output[Data] => Res2)( + implicit sw: Appender[Res, Data]): Res2 = { ensuring(appendOutput[Data])(body) } } - } object Readable { class Capability[Res](res: Res) { /** Gets the input for the resource specified in this resource */ - def input[Data](implicit sr: Reader[Res, Data], mode: Mode[`Readable#input`]): - mode.Wrap[Input[Data], Exception] = mode.wrap(sr.input(res)) - + def input[Data]( + implicit sr: Reader[Res, Data], + mode: Mode[`Readable#input`]): mode.Wrap[Input[Data], Exception] = + mode.wrap(sr.input(res)) + /** Pumps the input for the specified resource to the destination resource provided */ - def redirectTo[Data, DestRes](dest: DestRes)(implicit sr: Reader[Res, Data], sw: Writer[DestRes, Data], - mode: Mode[`Readable#redirectTo`], mf: ClassTag[Data]): mode.Wrap[Int, Exception] = - mode.wrap(handleInput[Data, Int] { in => + def redirectTo[Data, DestRes](dest: DestRes)( + implicit sr: Reader[Res, Data], + sw: Writer[DestRes, Data], + mode: Mode[`Readable#redirectTo`], + mf: ClassTag[Data]): mode.Wrap[Int, Exception] = + mode.wrap( + handleInput[Data, Int] { in => writable(dest).handleOutput[Data, Int](in pumpTo _) }) - - def >[Data, DestRes](dest: DestRes)(implicit sr: Reader[Res, Data], sw: Writer[DestRes, Data], - mode: Mode[`Readable#redirectTo`], mf: ClassTag[Data]): mode.Wrap[Int, Exception] = + + def >[Data, DestRes](dest: DestRes)( + implicit sr: Reader[Res, Data], + sw: Writer[DestRes, Data], + mode: Mode[`Readable#redirectTo`], + mf: ClassTag[Data]): mode.Wrap[Int, Exception] = redirectTo[Data, DestRes](dest)(sr, sw, mode, mf) - - def pipeTo[Data, DestRes](dest: DestRes)(implicit sr: - Reader[Res, Data], sw: Writer[DestRes, Data], mf: ClassTag[Data]): - DestRes = { - redirectTo(dest) - dest - } - def |[Data, DestRes](dest: DestRes)(implicit sr: Reader[Res, Data], sw: Writer[DestRes, Data], - mf: ClassTag[Data]): DestRes = pipeTo(dest)(sr, sw, mf) + def pipeTo[Data, DestRes](dest: DestRes)(implicit sr: Reader[Res, Data], + sw: Writer[DestRes, Data], + mf: ClassTag[Data]): DestRes = { + redirectTo(dest) + dest + } - def >>[Data, DestRes](dest: DestRes)(implicit sr: - Reader[Res, Data], sw: Appender[DestRes, Data], mode: Mode[`Readable#appendTo`], - mf: ClassTag[Data]): mode.Wrap[Int, Exception] = - mode.wrap(handleInput[Data, Int] { in => + def |[Data, DestRes](dest: DestRes)(implicit sr: Reader[Res, Data], + sw: Writer[DestRes, Data], + mf: ClassTag[Data]): DestRes = + pipeTo(dest)(sr, sw, mf) + + def >>[Data, DestRes]( + dest: DestRes)(implicit sr: Reader[Res, Data], + sw: Appender[DestRes, Data], + mode: Mode[`Readable#appendTo`], + mf: ClassTag[Data]): mode.Wrap[Int, Exception] = + mode.wrap( + handleInput[Data, Int] { in => dest.handleAppend[Data, Int](in pumpTo _) }) @@ -176,8 +200,10 @@ object Readable { * * @tparam Data The type that the data should be pumped as * @param out The destination for data to be pumped to */ - def >[Data](out: Output[Data])(implicit sr: Reader[Res, Data], - mode: Mode[`Readable#redirectTo`], mf: ClassTag[Data]): mode.Wrap[Int, Exception] = + def >[Data](out: Output[Data])( + implicit sr: Reader[Res, Data], + mode: Mode[`Readable#redirectTo`], + mf: ClassTag[Data]): mode.Wrap[Int, Exception] = mode.wrap(handleInput[Data, Int](_ pumpTo out)) /** Carefully handles writing to the input stream, ensuring that it is closed following @@ -187,59 +213,67 @@ object Readable { * @tparam Data The type of data the stream should carry * @tparam Res2 The type of body's result * @param body The code to be executed upon the this Input before it is closed */ - def handleInput[Data, Res2](body: Input[Data] => Res2)(implicit sr: - Reader[Res, Data]): Res2 = + def handleInput[Data, Res2](body: Input[Data] => Res2)( + implicit sr: Reader[Res, Data]): Res2 = ensuring(input[Data])(body) } } object Writable { class Capability[Res](res: Res) { - + /** Gets the output stream directly * * @tparam Data The type of data to be carried by the `Output` */ - def output[Data](implicit sw: Writer[Res, Data], mode: Mode[`Writable#output`]): - mode.Wrap[Output[Data], Exception] = mode.wrap(sw.output(res)) - + def output[Data]( + implicit sw: Writer[Res, Data], + mode: Mode[`Writable#output`]): mode.Wrap[Output[Data], Exception] = + mode.wrap(sw.output(res)) + /** Carefully handles writing to the output stream, ensuring that it is closed following * data being written. * * @param body The code to be executed upon this `Output` before being closed. * @return The result from executing the body */ - def handleOutput[Data, Res2](body: Output[Data] => Res2)(implicit sw: - Writer[Res, Data]): Res2 = + def handleOutput[Data, Res2](body: Output[Data] => Res2)( + implicit sw: Writer[Res, Data]): Res2 = ensuring(output[Data])(body) } } object Writer { implicit def byteToLineWriters[T](implicit jisw: JavaOutputStreamWriter[T], - encoding: Encoding): Writer[T, String] = new Writer[T, String] { - def output(t: T): Output[String] = alloc[LineOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) - } + encoding: Encoding): Writer[T, String] = + new Writer[T, String] { + def output(t: T): Output[String] = + alloc[LineOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) + } implicit def byteToCharWriters[T](implicit jisw: JavaOutputStreamWriter[T], - encoding: Encoding): Writer[T, Char] = new Writer[T, Char] { - def output(t: T): Output[Char] = alloc[CharOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) - } - + encoding: Encoding): Writer[T, Char] = + new Writer[T, Char] { + def output(t: T): Output[Char] = + alloc[CharOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) + } + implicit val stdoutWriter: JavaOutputStreamWriter[Stdout.type] = new JavaOutputStreamWriter[Stdout.type](x => System.out, _ => ()) - implicit val stderrWriter: Writer[Stderr.type, Byte] = new Writer[Stderr.type, Byte] { - def output(stderr: Stderr.type): Output[Byte] = - ?[OutputBuilder[OutputStream, Byte]].output(System.out) - } + implicit val stderrWriter: Writer[Stderr.type, Byte] = + new Writer[Stderr.type, Byte] { + def output(stderr: Stderr.type): Output[Byte] = + ?[OutputBuilder[OutputStream, Byte]].output(System.out) + } } /** Type trait for defining how a resource of type U should * * @tparam Resource Resource for which this corresponds * @tparam Data Units of data to be streamed, typically `Byte` or `Char` */ -@implicitNotFound(msg = "Cannot write ${Data} data to ${Resource} resources. Note that if you "+ - "are working with Char data, you will require an implicit character encoding, e.g. "+ - "import encodings.system._ or import encodings.`UTF-8`._.") +@implicitNotFound( + msg = "Cannot write ${Data} data to ${Resource} resources. Note that if you " + + "are working with Char data, you will require an implicit character encoding, e.g. " + + "import encodings.system._ or import encodings.`UTF-8`._.") trait Writer[-Resource, @specialized(Byte, Char) Data] { def output(res: Resource): Output[Data] } @@ -247,19 +281,21 @@ trait Writer[-Resource, @specialized(Byte, Char) Data] { object Appender extends Appender_1 { implicit def byteToCharAppenders[T](implicit jisw: JavaOutputAppender[T], - encoding: Encoding): Appender[T, Char] = new Appender[T, Char] { - def appendOutput(t: T): Output[Char] = - alloc[CharOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) - } - - implicit def byteToLineAppender[Res](implicit appender: Appender[Res, Byte], enc: Encoding) = { + encoding: Encoding): Appender[T, Char] = + new Appender[T, Char] { + def appendOutput(t: T): Output[Char] = + alloc[CharOutput](alloc[OutputStreamWriter](jisw.getOutputStream(t))) + } + + implicit def byteToLineAppender[Res]( + implicit appender: Appender[Res, Byte], enc: Encoding) = { new Appender[Res, String] { def appendOutput(res: Res): Output[String] = new Output[String] { private lazy val output = appender.appendOutput(res) def close() = output.close() def flush() = output.flush() def write(s: String) = { - output.writeBlock((s+"\n").getBytes(enc.name)) + output.writeBlock((s + "\n").getBytes(enc.name)) output.flush() } } @@ -274,21 +310,21 @@ object Appender extends Appender_1 { implicit val stdoutCharAppender: Appender[Stdout.type, Char] = byteToCharAppenders(stdoutAppender, encodings.system()) - + implicit val stderrCharAppender: Appender[Stderr.type, Char] = byteToCharAppenders(stderrAppender, encodings.system()) - } trait Appender_1 { - implicit def charToLineAppender[Res](implicit appender: Appender[Res, Char]) = { + implicit def charToLineAppender[Res]( + implicit appender: Appender[Res, Char]) = { new Appender[Res, String] { def appendOutput(res: Res): Output[String] = new Output[String] { private lazy val output = appender.appendOutput(res) def close() = output.close() def flush() = output.flush() def write(s: String) = { - output.writeBlock((s+"\n").to[Array]) + output.writeBlock((s + "\n").to[Array]) output.flush() } } @@ -326,12 +362,13 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => private var beingHandled = false override def toString() = "" - + // FIXME: This just shouldn't be a Seq - def length: Int = throw alloc[Exception]("Cannot calculate length of a stream") + def length: Int = + throw alloc[Exception]("Cannot calculate length of a stream") def apply(n: Int) = { - for(i <- 0 until n) read() + for (i <- 0 until n) read() read().get } @@ -359,7 +396,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => * will result in a new instance of `Some` to be constructed, so for reading larger block, * use the `readBlock` method which may be implemented more efficiently. */ def read(): Option[Data] - + /** Default implementation for reading a block of data from the input stream into the * specified array. * @@ -374,7 +411,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => * @return The number of items of data transferred */ def readBlock(array: Array[Data], offset: Int = 0, length: Int = -1): Int = { - val end = if(length < 0) (array.length - offset) else (offset + length) + val end = if (length < 0) (array.length - offset) else (offset + length) read() match { case None => -1 @@ -382,7 +419,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => array(offset) = c var i = offset + 1 var continue = true - while(i < end && continue) { + while (i < end && continue) { read() match { case None => continue = false @@ -398,7 +435,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => /** Closes the input stream so that no further data will be provided. */ def close(): Unit - + /** Pumps data from this `Input` to the specified `Output` until the end of the stream is * reached. * @@ -407,7 +444,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => val buf: Array[Data] = alloc(65536) var len = readBlock(buf) var count = 0 - while(len >= 0) { + while (len >= 0) { out.writeBlock(buf, length = len) count += len len = readBlock(buf) @@ -427,29 +464,30 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => private var buf: Seq[T] = Nil private var cur = 0 private var avail = 0 - - def read(): Option[T] = if(cur == avail) { - cur = 0 - avail = 0 - thisInput.read().map(fn) match { - case None => None - case Some(xs) => - if(xs.isEmpty) read() - else if(xs.length == 1) xs.headOption - else { - avail = xs.length - cur += 1 - buf = xs - xs.headOption - } + + def read(): Option[T] = + if (cur == avail) { + cur = 0 + avail = 0 + thisInput.read().map(fn) match { + case None => None + case Some(xs) => + if (xs.isEmpty) read() + else if (xs.length == 1) xs.headOption + else { + avail = xs.length + cur += 1 + buf = xs + xs.headOption + } + } + } else { + cur += 1 + Some(buf(cur - 1)) } - } else { - cur += 1 - Some(buf(cur - 1)) - } - + def ready(): Boolean = cur < avail || thisInput.ready() - + def close(): Unit = { cur = 0 avail = 0 @@ -459,7 +497,7 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => override def foreach[U](fn: Data => U): Unit = { var next: Option[Data] = read() - while(next != None) { + while (next != None) { fn(next.get) next = read() } @@ -467,15 +505,16 @@ trait Input[@specialized(Byte, Char) Data] extends Seq[Data] { thisInput => } object Output { - implicit def outputClosable[T]: Closable[Output[T]] = new Closable[Output[T]] { - def close(out: Output[T]): Unit = out.close() - } + implicit def outputClosable[T]: Closable[Output[T]] = + new Closable[Output[T]] { + def close(out: Output[T]): Unit = out.close() + } } /** Defines a generic output stream */ trait Output[@specialized(Byte, Char) Data] { private var beingHandled = false - + /** Writes one item of data to this stream * * @param data The data to be written */ @@ -494,13 +533,13 @@ trait Output[@specialized(Byte, Char) Data] { * remainder of the array. * @return The number of data items written. */ def writeBlock(array: Array[Data], offset: Int = 0, length: Int = -1): Int = { - - val end = if(length < 0) (array.length - offset) else (offset + length) + + val end = if (length < 0) (array.length - offset) else (offset + length) array.slice(offset, end).foreach(write) end - offset } - + /** Flushes the stream */ def flush(): Unit @@ -509,11 +548,13 @@ trait Output[@specialized(Byte, Char) Data] { } trait Reader_1 { - implicit def stringByteReader(implicit encoding: Encoding): Reader[String, Byte] = + implicit def stringByteReader( + implicit encoding: Encoding): Reader[String, Byte] = new Reader[String, Byte] { - def input(s: String): Input[Byte] = ByteArrayInput(s.getBytes(encoding.name)) + def input(s: String): Input[Byte] = + ByteArrayInput(s.getBytes(encoding.name)) } - + implicit val stringLineReader: Reader[String, String] = StringLineReader } @@ -523,16 +564,17 @@ object Reader extends Reader_1 { def input(in: I[T]): Input[T] = in } - implicit def byteInputToCharReader(implicit encoding: Encoding): Reader[Input[Char], Byte] = + implicit def byteInputToCharReader( + implicit encoding: Encoding): Reader[Input[Char], Byte] = new Reader[Input[Char], Byte] { def input(in: Input[Char]): Input[Byte] = new Input[Byte] { private var cued: Array[Byte] = Array() private var index = 0 def read(): Option[Byte] = { - if(index >= cued.length) { + if (index >= cued.length) { // FIXME: Find a less stupid way of doing this val next = in.read() - if(next.isEmpty) return None + if (next.isEmpty) return None cued = next.get.toString.getBytes(encoding.name) index = 0 } @@ -544,64 +586,69 @@ object Reader extends Reader_1 { def close(): Unit = in.close() } } - - implicit def charInputToByteReader(implicit encoding: Encoding): Reader[Input[Byte], Char] = + + implicit def charInputToByteReader( + implicit encoding: Encoding): Reader[Input[Byte], Char] = new Reader[Input[Byte], Char] { def input(in: Input[Byte]): Input[Char] = { val javaInputStream = new InputStream { def read(): Int = { val r = in.read() - if(r.isDefined) r.get.toInt else -1 + if (r.isDefined) r.get.toInt else -1 } } - alloc[CharInput](alloc[InputStreamReader](javaInputStream, encoding.name)) + alloc[CharInput]( + alloc[InputStreamReader](javaInputStream, encoding.name)) } } - implicit def byteToLineReaders[T](implicit jisr: JavaInputStreamReader[T], - encoding: Encoding): Reader[T, String] = new Reader[T, String] { - def input(t: T): Input[String] = - alloc[LineInput](alloc[InputStreamReader](jisr.getInputStream(t))) - } + encoding: Encoding): Reader[T, String] = + new Reader[T, String] { + def input(t: T): Input[String] = + alloc[LineInput](alloc[InputStreamReader](jisr.getInputStream(t))) + } implicit def byteToCharReaders[T](implicit jisr: JavaInputStreamReader[T], - encoding: Encoding): Reader[T, Char] = new Reader[T, Char] { - def input(t: T): Input[Char] = - alloc[CharInput](alloc[InputStreamReader](jisr.getInputStream(t))) - } + encoding: Encoding): Reader[T, Char] = + new Reader[T, Char] { + def input(t: T): Input[Char] = + alloc[CharInput](alloc[InputStreamReader](jisr.getInputStream(t))) + } - implicit def resourceBytes[Res](res: Res)(implicit sr: Reader[Res, Byte]): Bytes = + implicit def resourceBytes[Res](res: Res)( + implicit sr: Reader[Res, Byte]): Bytes = slurpable(res).slurp[Byte] implicit val stringCharReader: Reader[String, Char] = StringCharReader implicit val byteArrayReader: Reader[Array[Byte], Byte] = ByteArrayReader implicit val bytesReader: Reader[Bytes, Byte] = BytesReader - implicit val stdinReader: Reader[Stdin.type, Byte] = new Reader[Stdin.type, Byte] { - def input(stdin: Stdin.type): Input[Byte] = - ?[InputBuilder[InputStream, Byte]].input(System.in) - } - + implicit val stdinReader: Reader[Stdin.type, Byte] = + new Reader[Stdin.type, Byte] { + def input(stdin: Stdin.type): Input[Byte] = + ?[InputBuilder[InputStream, Byte]].input(System.in) + } } /** Generic type class for reading a particular kind of data from */ -@implicitNotFound(msg = "Cannot find implicit Reader for ${Resource} resources. "+ - "${Resource} resources can only be read if a Reader implicit exists within scope. "+ - "Note that if you are working with Char data, you will require an implicit character "+ - "encoding, e.g. import encodings.system._ or import encodings.`UTF-8`._.") +@implicitNotFound( + msg = "Cannot find implicit Reader for ${Resource} resources. " + + "${Resource} resources can only be read if a Reader implicit exists within scope. " + + "Note that if you are working with Char data, you will require an implicit character " + + "encoding, e.g. import encodings.system._ or import encodings.`UTF-8`._.") trait Reader[-Resource, @specialized(Byte, Char) Data] { - + /** Creates the `Input` for streaming data of the specified type from the given resource * * @param res The resource to get the input stream from * @return an `Input[Data]` for the specified resource */ def input(res: Resource): Input[Data] - + /** Pumps data from the specified resource to the given destination resource */ - def pump[DestResource](res: Resource, dest: DestResource)(implicit sw: - Writer[DestResource, Data], mf: ClassTag[Data]): Int = + def pump[DestResource](res: Resource, dest: DestResource)( + implicit sw: Writer[DestResource, Data], mf: ClassTag[Data]): Int = input(res) pumpTo sw.output(dest) } @@ -618,7 +665,7 @@ object StringLineReader extends Reader[String, String] { def close() = () def read() = { cur += 1 - if(ready()) Some(lines(cur)) else None + if (ready()) Some(lines(cur)) else None } } } diff --git a/io/shared/src/main/scala/rapture/io/strings.scala b/io/shared/src/main/scala/rapture/io/strings.scala index df31a0b..dcce0a4 100644 --- a/io/shared/src/main/scala/rapture/io/strings.scala +++ b/io/shared/src/main/scala/rapture/io/strings.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io diff --git a/io/shared/src/main/scala/rapture/io/wrappers.scala b/io/shared/src/main/scala/rapture/io/wrappers.scala index 5abe2ab..8d2fa6c 100644 --- a/io/shared/src/main/scala/rapture/io/wrappers.scala +++ b/io/shared/src/main/scala/rapture/io/wrappers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.io import rapture.core._ @@ -33,44 +33,50 @@ object OutputStreamBuilder extends OutputBuilder[OutputStream, Byte] { } object ClasspathStream { - def classpathStreamByteReader(implicit cl: ClassLoader) = new JavaInputStreamReader[ClasspathUrl](url => - cl.javaClassLoader.getResourceAsStream(url.uri.schemeSpecificPart)) + def classpathStreamByteReader(implicit cl: ClassLoader) = + new JavaInputStreamReader[ClasspathUrl](url => + cl.javaClassLoader.getResourceAsStream(url.uri.schemeSpecificPart)) } + /** Wraps a `java.io.Reader` as an `Input[Char]` */ class CharInput(in: java.io.Reader) extends Input[Char] { private val bin = alloc[BufferedReader](in) def ready() = bin.ready() - + def read() = bin.read() match { case -1 => None case x => Some(x.toChar) } - + def close() = bin.close() - - override def readBlock(array: Array[Char], offset: Int = 0, length: Int = -1): Int = - bin.read(array, offset, if(length == -1) (array.length - offset) else length) + + override def readBlock( + array: Array[Char], offset: Int = 0, length: Int = -1): Int = + bin.read( + array, offset, if (length == -1) (array.length - offset) else length) override def toString() = "" } /** Wraps a `java.io.InputStream` as an `Input[Byte]` */ class ByteInput(in: InputStream) extends Input[Byte] { - + private val bin = alloc[BufferedInputStream](in) // FIXME: This might be really slow def ready() = bin.available() > 0 - + def read() = bin.read() match { case -1 => None case x => Some(x.toByte) } - - override def readBlock(array: Array[Byte], offset: Int = 0, length: Int = -1): Int = - bin.read(array, offset, if(length == -1) (array.length - offset) else length) + + override def readBlock( + array: Array[Byte], offset: Int = 0, length: Int = -1): Int = + bin.read( + array, offset, if (length == -1) (array.length - offset) else length) def close() = in.close() @@ -80,45 +86,46 @@ class ByteInput(in: InputStream) extends Input[Byte] { /** Wraps a `java.io.OutputStream` into an `Output[Byte]` * * @param out The `java.io.OutputStream` to be wrapped */ -class ByteOutput(out: OutputStream, closer: OutputStream => Unit = (_.close())) extends Output[Byte] { - +class ByteOutput(out: OutputStream, closer: OutputStream => Unit = (_.close())) + extends Output[Byte] { + private val bout = alloc[BufferedOutputStream](out) - + def write(b: Byte) = bout.write(b) - + def flush(): Unit = bout.flush() def close(): Unit = bout.close() - + override def toString() = "" - - override def writeBlock(array: Array[Byte], offset: Int = 0, length: Int = -1): Int = { - val len = if(length == -1) (array.length - offset) else length + + override def writeBlock( + array: Array[Byte], offset: Int = 0, length: Int = -1): Int = { + val len = if (length == -1) (array.length - offset) else length bout.write(array, offset, len) bout.flush() len } - } /** Wraps a `java.io.Writer` * * @param out The `java.io.Writer` to be wrapped */ class CharOutput(out: java.io.Writer) extends Output[Char] { - + private val bout = alloc[BufferedWriter](out) - + def write(b: Char) = bout.write(b) def flush(): Unit = bout.flush() def close(): Unit = bout.close() override def toString() = "" - - override def writeBlock(array: Array[Char], offset: Int = 0, length: Int = -1): Int = { - val len = if(length == -1) (array.length - offset) else length + + override def writeBlock( + array: Array[Char], offset: Int = 0, length: Int = -1): Int = { + val len = if (length == -1) (array.length - offset) else length bout.write(array, offset, len) bout.flush() len } - } /** Wraps a `java.io.BufferedWriter` for providing line-by-line output of `String`s @@ -174,16 +181,22 @@ object WriterBuilder extends OutputBuilder[java.io.Writer, Char] { def output(s: java.io.Writer): Output[Char] = alloc[CharOutput](s) } -class JavaOutputStreamWriter[T](val getOutputStream: T => OutputStream, val closer: OutputStream => Unit = (_.close())) extends - Writer[T, Byte] { - def output(t: T): Output[Byte] = alloc[ByteOutput](alloc[BufferedOutputStream](getOutputStream(t)), closer) +class JavaOutputStreamWriter[T](val getOutputStream: T => OutputStream, + val closer: OutputStream => Unit = (_.close())) + extends Writer[T, Byte] { + def output(t: T): Output[Byte] = + alloc[ByteOutput](alloc[BufferedOutputStream](getOutputStream(t)), closer) } -class JavaOutputAppender[T](val getOutputStream: T => OutputStream, val closer: OutputStream => Unit = (_.close())) extends Appender[T, Byte] { - def appendOutput(t: T): Output[Byte] = alloc[ByteOutput](alloc[BufferedOutputStream](getOutputStream(t)), closer) +class JavaOutputAppender[T](val getOutputStream: T => OutputStream, + val closer: OutputStream => Unit = (_.close())) + extends Appender[T, Byte] { + def appendOutput(t: T): Output[Byte] = + alloc[ByteOutput](alloc[BufferedOutputStream](getOutputStream(t)), closer) } -class JavaInputStreamReader[T](val getInputStream: T => InputStream) extends - Reader[T, Byte] { - def input(t: T): Input[Byte] = alloc[ByteInput](alloc[BufferedInputStream](getInputStream(t))) +class JavaInputStreamReader[T](val getInputStream: T => InputStream) + extends Reader[T, Byte] { + def input(t: T): Input[Byte] = + alloc[ByteInput](alloc[BufferedInputStream](getInputStream(t))) } diff --git a/js/shared/src/main/scala/rapture/js/context.scala b/js/shared/src/main/scala/rapture/js/context.scala index b86dca2..36bcad2 100644 --- a/js/shared/src/main/scala/rapture/js/context.scala +++ b/js/shared/src/main/scala/rapture/js/context.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.js @@ -24,68 +24,74 @@ import rapture.data._ import language.experimental.macros private[js] object JsMacros { - - def parseSource(s: List[String], stringsUsed: List[Boolean]): Option[(Int, Int, String)] = try { - JsValidator.validate(s) - None - } catch { - case JsValidator.ValidationException(strNo, pos, msg) => - Some((strNo, pos, s"failed to parse Js literal: $msg")) - } - - def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Js]]*): c.Expr[Js] = { + + def parseSource(s: List[String], + stringsUsed: List[Boolean]): Option[(Int, Int, String)] = + try { + JsValidator.validate(s) + None + } catch { + case JsValidator.ValidationException(strNo, pos, msg) => + Some((strNo, pos, s"failed to parse Js literal: $msg")) + } + + def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[Js]]*): c.Expr[Js] = { import c.universe._ import compatibility._ c.prefix.tree match { case Select(Apply(_, List(Apply(_, rawParts))), _) => val ys = rawParts.to[List] - val text = rawParts map { case lit@Literal(Constant(part: String)) => part } + val text = + rawParts map { case lit @ Literal(Constant(part: String)) => part } - val listExprs = c.Expr[List[ForcedConversion[Js]]](Apply( - Select(reify(List).tree, termName(c, "apply")), - exprs.map(_.tree).to[List] - )) + val listExprs = c.Expr[List[ForcedConversion[Js]]](Apply( + Select(reify(List).tree, termName(c, "apply")), + exprs.map(_.tree).to[List] + )) val stringsUsed: List[Boolean] = listExprs.tree match { - case Apply(_, bs) => bs.map { - case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => nme.toString == "forceStringConversion" - } - } - - parseSource(text, stringsUsed) foreach { case (n, offset, msg) => - val oldPos = ys(n).asInstanceOf[Literal].pos - val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) - c.error(newPos, msg) - } - - val listParts = c.Expr[List[String]](Apply( - Select(reify(List).tree, termName(c, "apply")), - rawParts - )) - - reify { + case Apply(_, bs) => + bs.map { + case Apply(Apply(TypeApply(Select(_, nme), _), _), _) => + nme.toString == "forceStringConversion" + } + } + + parseSource(text, stringsUsed) foreach { + case (n, offset, msg) => + val oldPos = ys(n).asInstanceOf[Literal].pos + val newPos = oldPos.withPoint(oldPos.startOrPoint + offset) + c.error(newPos, msg) + } + + val listParts = c.Expr[List[String]](Apply( + Select(reify(List).tree, termName(c, "apply")), + rawParts + )) + + reify { val sb = new StringBuilder - val textParts = listParts.splice.iterator - val expressions: Iterator[ForcedConversion[_]] = listExprs.splice.iterator - - sb.append(textParts.next()) - - while(textParts.hasNext) { - sb.append(expressions.next.value) - sb.append(textParts.next) - } - Js(sb.toString) - } + val textParts = listParts.splice.iterator + val expressions: Iterator[ForcedConversion[_]] = + listExprs.splice.iterator + + sb.append(textParts.next()) + + while (textParts.hasNext) { + sb.append(expressions.next.value) + sb.append(textParts.next) + } + Js(sb.toString) + } } } - } private[js] class JsStrings(sc: StringContext) { class JsContext() { - def apply(exprs: ForcedConversion[Js]*): Js = - macro JsMacros.contextMacro + def apply(exprs: ForcedConversion[Js]*): Js = macro JsMacros.contextMacro } val js = new JsContext() } diff --git a/js/shared/src/main/scala/rapture/js/js.scala b/js/shared/src/main/scala/rapture/js/js.scala index 4b78c7c..ab4019e 100644 --- a/js/shared/src/main/scala/rapture/js/js.scala +++ b/js/shared/src/main/scala/rapture/js/js.scala @@ -13,10 +13,10 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.js case class Js(content: String) { - override def toString = s"""js${"\""*3}$content${"\""*3}""" + override def toString = s"""js${"\"" * 3}$content${"\"" * 3}""" } diff --git a/js/shared/src/main/scala/rapture/js/package.scala b/js/shared/src/main/scala/rapture/js/package.scala index dbea6ee..864da43 100644 --- a/js/shared/src/main/scala/rapture/js/package.scala +++ b/js/shared/src/main/scala/rapture/js/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.js diff --git a/js/shared/src/main/scala/rapture/js/validator.scala b/js/shared/src/main/scala/rapture/js/validator.scala index a6f22ca..3e1e5e3 100644 --- a/js/shared/src/main/scala/rapture/js/validator.scala +++ b/js/shared/src/main/scala/rapture/js/validator.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.js @@ -25,21 +25,24 @@ private[js] object JsValidator { case class ValidationException(strNo: Int, pos: Int, msg: String) extends Exception - + def validate(parts: List[String]): Unit = { val script = parts.mkString("null"); - val engine: Compilable = alloc[ScriptEngineManager]().getEngineByName("JavaScript") match { - case e: Compilable => e - } - + val engine: Compilable = + alloc[ScriptEngineManager]().getEngineByName("JavaScript") match { + case e: Compilable => e + } + try engine.compile(script) catch { case e: ScriptException => - val pos = script.split("\n").take(e.getLineNumber - 1).map(_.length + 1).sum + e.getColumnNumber - val Regex = ":[0-9]+:[0-9]+ (.*)$".r - println("pos = "+pos) - val msg = e.getMessage.split("\n").head match { case Regex(m) => m } - - throw ValidationException(0, pos, msg) + val pos = + script.split("\n").take(e.getLineNumber - 1).map(_.length + 1).sum + + e.getColumnNumber + val Regex = ":[0-9]+:[0-9]+ (.*)$".r + println("pos = " + pos) + val msg = e.getMessage.split("\n").head match { case Regex(m) => m } + + throw ValidationException(0, pos, msg) } } } diff --git a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/ast.scala b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/ast.scala index 3031618..90d9f7e 100644 --- a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/ast.scala +++ b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.argonaut @@ -30,16 +30,17 @@ private[argonaut] object ArgonautAst extends JsonBufferAst { override def dereferenceObject(obj: Any, element: String): Any = obj match { - case j: AJson if j.isObject => j.field(element).getOrElse(throw MissingValueException()) + case j: AJson if j.isObject => + j.field(element).getOrElse(throw MissingValueException()) case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case j: AJson if j.isObject => j.objectFields.get.iterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { case j: AJson if j.isArray => j.array.get(element) @@ -55,46 +56,56 @@ private[argonaut] object ArgonautAst extends JsonBufferAst { case j: AJson if j.isBool => j.bool.get case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getDouble(double: Any): Double = double match { case j: AJson if j.isNumber => j.number.get.toDouble.get case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case j: AJson if j.isNumber => BigDecimal(j.number.get.toDouble.get) - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getString(string: Any): String = string match { case j: AJson if j.isString => j.string.get case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { - case j: AJson if j.isObject => j.obj.get.toMap.map{ case (k, v) => k.toString -> v } + case j: AJson if j.isObject => + j.obj.get.toMap.map { case (k, v) => k.toString -> v } case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = { - val contents = (name, value) :: obj.asInstanceOf[AJson].obj.get.toList.collect { - case (k, v) if k.toString != name => k.toString -> v } + val contents = + (name, value) :: obj.asInstanceOf[AJson].obj.get.toList.collect { + case (k, v) if k.toString != name => k.toString -> v + } fromObject(contents.toMap) } - + def removeObjectValue(obj: Any, name: String): Any = { val contents = obj.asInstanceOf[AJson].obj.get.toList.collect { - case (k, v) if k.toString != name => k.toString -> v } + case (k, v) if k.toString != name => k.toString -> v + } fromObject(contents.toMap) } - + def addArrayValue(array: Any, value: Any): Any = fromArray(array.asInstanceOf[AJson].array.get :+ value) - + def setArrayValue(array: Any, index: Int, value: Any): Any = - fromArray(array.asInstanceOf[AJson].array.get.padTo(index, nullValue).patch(index, - Seq(value), 1)) - + fromArray( + array + .asInstanceOf[AJson] + .array + .get + .padTo(index, nullValue) + .patch(index, Seq(value), 1)) + def isArray(array: Any): Boolean = array match { case j: AJson if j.isArray => true case _ => false @@ -104,39 +115,38 @@ private[argonaut] object ArgonautAst extends JsonBufferAst { case j: AJson if j.isBool => true case _ => false } - + def isNumber(num: Any): Boolean = num match { case j: AJson if j.isNumber => true case _ => false } - + def isString(string: Any): Boolean = string match { case j: AJson if j.isString => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case j: AJson if j.isObject => true case _ => false } - + def isNull(obj: Any): Boolean = obj match { case j: AJson if j.isNull => true case _ => false } - - - def fromArray(array: Seq[Any]): Any = jArray(array.to[List] map { case v: AJson => v }) + + def fromArray(array: Seq[Any]): Any = + jArray(array.to[List] map { case v: AJson => v }) def fromBoolean(boolean: Boolean): Any = jBool(boolean) def fromDouble(number: Double): Any = jNumber(number).get def fromBigDecimal(number: BigDecimal): Any = jNumber(number.toDouble).get - - def fromObject(obj: Map[String,Any]): Any = - AJson(obj.mapValues{ case v: AJson => v }.to[List]: _*) - + + def fromObject(obj: Map[String, Any]): Any = + AJson(obj.mapValues { case v: AJson => v }.to[List]: _*) + def fromString(string: String): Any = jString(string) // FIXME: Is there a better way of getting a JNull? lazy val nullValue: Any = argonaut.Parse.parseOption("null").get - } diff --git a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/extractors.scala b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/extractors.scala index 0ba3d9c..ae6e867 100644 --- a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/extractors.scala +++ b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.argonaut @@ -25,7 +25,7 @@ import argonaut.{Json => AJson, _} private[argonaut] trait Extractors { implicit val argonautJObjectExtractor: JsonCastExtractor[JsonObject] = JsonCastExtractor(ArgonautAst, DataTypes.Object) - + implicit val argonautJValueExtractor: JsonCastExtractor[AJson] = JsonCastExtractor(ArgonautAst, DataTypes.Object) } diff --git a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/package.scala b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/package.scala index 4ff1d4b..08cff2a 100644 --- a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/package.scala +++ b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.argonaut diff --git a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/parse.scala b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/parse.scala index 90f767a..3c01919 100644 --- a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/parse.scala +++ b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.argonaut import rapture.core._ diff --git a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/serializers.scala b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/serializers.scala index 3c8971f..04957f3 100644 --- a/json-argonaut/shared/src/main/scala/rapture/json-argonaut/serializers.scala +++ b/json-argonaut/shared/src/main/scala/rapture/json-argonaut/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.argonaut diff --git a/json-circe/shared/src/main/scala/rapture/json-circe/ast.scala b/json-circe/shared/src/main/scala/rapture/json-circe/ast.scala index 1433281..754a087 100644 --- a/json-circe/shared/src/main/scala/rapture/json-circe/ast.scala +++ b/json-circe/shared/src/main/scala/rapture/json-circe/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.circe @@ -28,15 +28,17 @@ private[circe] object CirceAst extends JsonBufferAst { override def toString = "" override def dereferenceObject(obj: Any, element: String): Any = { - def fail(): Nothing = throw TypeMismatchException(getType(obj), DataTypes.Object) + def fail(): Nothing = + throw TypeMismatchException(getType(obj), DataTypes.Object) obj match { case j: CirceJson => j.asObject.getOrElse(fail())(element).get case _ => fail() } } - + override def getKeys(obj: Any): Iterator[String] = { - def fail(): Nothing = throw TypeMismatchException(getType(obj), DataTypes.Object) + def fail(): Nothing = + throw TypeMismatchException(getType(obj), DataTypes.Object) obj match { case j: CirceJson => j.asObject.getOrElse(fail()).fields.to[Iterator] case _ => fail() @@ -57,49 +59,63 @@ private[circe] object CirceAst extends JsonBufferAst { case j: CirceJson if j.isBoolean => j.asBoolean.get case _ => throw TypeMismatchException(getType(j), DataTypes.Boolean) } - + def getDouble(double: Any): Double = double match { case j: CirceJson if j.isNumber => j.asNumber.get.toDouble case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case j: CirceJson if j.isNumber => - j.asNumber.get.toBigDecimal.getOrElse(throw - TypeMismatchException(getType(bigDecimal), DataTypes.Number)) + j.asNumber.get.toBigDecimal.getOrElse( + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number)) case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getString(string: Any): String = string match { case j: CirceJson if j.isString => j.asString.get case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { - case j: CirceJson if j.isObject => j.asObject.get.toMap.map{ case (k, v) => k.toString -> v } + case j: CirceJson if j.isObject => + j.asObject.get.toMap.map { case (k, v) => k.toString -> v } case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = { - val contents = (name, value) :: obj.asInstanceOf[CirceJson].asObject.get.toList.collect { - case (k, v) if k.toString != name => k.toString -> v } + val contents = + (name, value) :: obj + .asInstanceOf[CirceJson] + .asObject + .get + .toList + .collect { + case (k, v) if k.toString != name => k.toString -> v + } fromObject(contents.toMap) } - + def removeObjectValue(obj: Any, name: String): Any = { val contents = obj.asInstanceOf[CirceJson].asObject.get.toList.collect { - case (k, v) if k.toString != name => k.toString -> v } + case (k, v) if k.toString != name => k.toString -> v + } fromObject(contents.toMap) } - + def addArrayValue(array: Any, value: Any): Any = fromArray(array.asInstanceOf[CirceJson].asArray.get :+ value) - + def setArrayValue(array: Any, index: Int, value: Any): Any = - fromArray(array.asInstanceOf[CirceJson].asArray.get.padTo(index, nullValue).patch(index, - Seq(value), 1)) - + fromArray( + array + .asInstanceOf[CirceJson] + .asArray + .get + .padTo(index, nullValue) + .patch(index, Seq(value), 1)) + def isArray(array: Any): Boolean = array match { case j: CirceJson if j.isArray => true case _ => false @@ -109,39 +125,39 @@ private[circe] object CirceAst extends JsonBufferAst { case j: CirceJson if j.isBoolean => true case _ => false } - + def isNumber(num: Any): Boolean = num match { case j: CirceJson if j.isNumber => true case _ => false } - + def isString(string: Any): Boolean = string match { case j: CirceJson if j.isString => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case j: CirceJson if j.isObject => true case _ => false } - + def isNull(obj: Any): Boolean = obj match { case j: CirceJson if j.isNull => true case _ => false } - - - def fromArray(array: Seq[Any]): Any = CirceJson.arr(array.to[List].map { case v: CirceJson => v }: _*) + + def fromArray(array: Seq[Any]): Any = + CirceJson.arr(array.to[List].map { case v: CirceJson => v }: _*) def fromBoolean(boolean: Boolean): Any = CirceJson.fromBoolean(boolean) def fromDouble(number: Double): Any = CirceJson.fromDouble(number).get - def fromBigDecimal(number: BigDecimal): Any = CirceJson.fromBigDecimal(number) - - def fromObject(obj: Map[String,Any]): Any = - CirceJson.obj(obj.mapValues{ case v: CirceJson => v }.to[List]: _*) - + def fromBigDecimal(number: BigDecimal): Any = + CirceJson.fromBigDecimal(number) + + def fromObject(obj: Map[String, Any]): Any = + CirceJson.obj(obj.mapValues { case v: CirceJson => v }.to[List]: _*) + def fromString(string: String): Any = CirceJson.fromString(string) // FIXME: Is there a better way of getting a JNull? lazy val nullValue: Any = CirceJson.Null - } diff --git a/json-circe/shared/src/main/scala/rapture/json-circe/extractors.scala b/json-circe/shared/src/main/scala/rapture/json-circe/extractors.scala index 4828ffa..ad0d3c9 100644 --- a/json-circe/shared/src/main/scala/rapture/json-circe/extractors.scala +++ b/json-circe/shared/src/main/scala/rapture/json-circe/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.circe @@ -25,7 +25,7 @@ import io.circe.{Json => CirceJson, _} private[circe] trait Extractors { implicit val circeJObjectExtractor: JsonCastExtractor[JsonObject] = JsonCastExtractor(CirceAst, DataTypes.Object) - + implicit val circeJValueExtractor: JsonCastExtractor[CirceJson] = JsonCastExtractor(CirceAst, DataTypes.Object) } diff --git a/json-circe/shared/src/main/scala/rapture/json-circe/package.scala b/json-circe/shared/src/main/scala/rapture/json-circe/package.scala index 0fc99a2..5b52ec9 100644 --- a/json-circe/shared/src/main/scala/rapture/json-circe/package.scala +++ b/json-circe/shared/src/main/scala/rapture/json-circe/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.circe diff --git a/json-circe/shared/src/main/scala/rapture/json-circe/parse.scala b/json-circe/shared/src/main/scala/rapture/json-circe/parse.scala index 7382c43..85614a5 100644 --- a/json-circe/shared/src/main/scala/rapture/json-circe/parse.scala +++ b/json-circe/shared/src/main/scala/rapture/json-circe/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.circe import rapture.core._ @@ -26,7 +26,8 @@ private[circe] object CirceParser extends Parser[String, JsonBufferAst] { val ast = CirceAst - def parse(s: String): Option[Any] = CirceSupportParser.parseFromString(s).toOption + def parse(s: String): Option[Any] = + CirceSupportParser.parseFromString(s).toOption override def toString = "" } diff --git a/json-circe/shared/src/main/scala/rapture/json-circe/serializers.scala b/json-circe/shared/src/main/scala/rapture/json-circe/serializers.scala index 3aa54b3..e268b0d 100644 --- a/json-circe/shared/src/main/scala/rapture/json-circe/serializers.scala +++ b/json-circe/shared/src/main/scala/rapture/json-circe/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.circe diff --git a/json-jackson/shared/src/main/scala/rapture/json-jackson/ast.scala b/json-jackson/shared/src/main/scala/rapture/json-jackson/ast.scala index 84f526f..c11fb86 100644 --- a/json-jackson/shared/src/main/scala/rapture/json-jackson/ast.scala +++ b/json-jackson/shared/src/main/scala/rapture/json-jackson/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jackson import rapture.core._ @@ -31,7 +31,7 @@ private[jackson] object JacksonAst extends JsonAst { private val mapper = new ObjectMapper() .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true) .configure(DeserializationFeature.USE_BIG_INTEGER_FOR_INTS, true) - + def getArray(array: Any): List[Any] = array match { case list: JsonNode if list.isArray => list.elements.to[List] case _ => throw TypeMismatchException(getType(array), DataTypes.Array) @@ -41,35 +41,39 @@ private[jackson] object JacksonAst extends JsonAst { case boolean: JsonNode if boolean.isBoolean => boolean.asBoolean case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getDouble(number: Any): Double = number match { - case number: JsonNode if number.isBigDecimal => number.decimalValue.doubleValue - case number: JsonNode if number.isBigInteger => number.bigIntegerValue.doubleValue + case number: JsonNode if number.isBigDecimal => + number.decimalValue.doubleValue + case number: JsonNode if number.isBigInteger => + number.bigIntegerValue.doubleValue case number: JsonNode if number.isNumber => number.asDouble case number: Double => number case _ => throw TypeMismatchException(getType(number), DataTypes.Number) } - + def getBigDecimal(number: Any): BigDecimal = number match { - case number: JsonNode if number.isBigDecimal => BigDecimal(number.decimalValue) - case number: JsonNode if number.isBigInteger => BigDecimal(number.bigIntegerValue) + case number: JsonNode if number.isBigDecimal => + BigDecimal(number.decimalValue) + case number: JsonNode if number.isBigInteger => + BigDecimal(number.bigIntegerValue) case number: JsonNode if number.isNumber => number.asDouble case number: Double => BigDecimal(number) case _ => throw TypeMismatchException(getType(number), DataTypes.Number) } - + def getString(string: Any): String = string match { case string: JsonNode if string.isTextual => string.asText case string: String => string case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { case obj: JsonNode if obj.isObject => (obj.fieldNames map { case k => k -> Option(obj.get(k)).get }).toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceObject(obj: Any, element: String): Any = obj match { case obj: JsonNode if obj.isObject => Option(obj.get(element)).get case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) @@ -85,25 +89,26 @@ private[jackson] object JacksonAst extends JsonAst { case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } - def setObjectValue(obj: JsonNode, name: String, value: JsonNode): Unit = obj match { - case obj: node.ObjectNode => obj.set(name, value) - } - + def setObjectValue(obj: JsonNode, name: String, value: JsonNode): Unit = + obj match { + case obj: node.ObjectNode => obj.set(name, value) + } + def removeObjectValue(obj: JsonNode, name: String): Unit = obj match { case obj: node.ObjectNode => obj.remove(name) } - + def addArrayValue(array: JsonNode, value: JsonNode): Unit = array match { case array: node.ArrayNode => array.add(value) } - + def setArrayValue(array: JsonNode, index: Int, value: JsonNode): Unit = ??? def nullValue = null def fromArray(array: Seq[Any]): Any = { val newArray = mapper.createArrayNode - for(v <- array) v match { + for (v <- array) v match { case v: Boolean => newArray.add(v) case v: String => newArray.add(v) case v: Double => newArray.add(v) @@ -115,10 +120,10 @@ private[jackson] object JacksonAst extends JsonAst { def fromBoolean(boolean: Boolean): Any = boolean def fromDouble(number: Double): Any = number def fromBigDecimal(number: BigDecimal): Any = number.toDouble - - def fromObject(obj: Map[String,Any]): Any = { + + def fromObject(obj: Map[String, Any]): Any = { val newObject = mapper.createObjectNode - for((k, v) <- obj) v match { + for ((k, v) <- obj) v match { case v: Boolean => newObject.put(k, v) case v: String => newObject.put(k, v) case v: Double => newObject.put(k, v) @@ -129,12 +134,11 @@ private[jackson] object JacksonAst extends JsonAst { } def fromString(string: String): Any = string - def isBoolean(any: Any): Boolean = any match { case x: JsonNode if x.isBoolean => true case _ => false } - + def isString(any: Any): Boolean = any match { case x: JsonNode if x.isTextual => true case x: String => true @@ -146,17 +150,17 @@ private[jackson] object JacksonAst extends JsonAst { case x: Double => true case _ => false } - + def isObject(any: Any): Boolean = any match { case x: JsonNode if x.isObject => true case _ => false } - + def isArray(any: Any): Boolean = any match { case x: JsonNode if x.isArray => true case _ => false } - + def isNull(any: Any): Boolean = any match { case x: JsonNode if x.isNull => true case _ => false diff --git a/json-jackson/shared/src/main/scala/rapture/json-jackson/extractors.scala b/json-jackson/shared/src/main/scala/rapture/json-jackson/extractors.scala index 2c69666..90e8d3d 100644 --- a/json-jackson/shared/src/main/scala/rapture/json-jackson/extractors.scala +++ b/json-jackson/shared/src/main/scala/rapture/json-jackson/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jackson diff --git a/json-jackson/shared/src/main/scala/rapture/json-jackson/package.scala b/json-jackson/shared/src/main/scala/rapture/json-jackson/package.scala index 34aa67b..56bd9dc 100644 --- a/json-jackson/shared/src/main/scala/rapture/json-jackson/package.scala +++ b/json-jackson/shared/src/main/scala/rapture/json-jackson/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jackson @@ -22,5 +22,6 @@ import rapture.data._ object `package` extends Extractors with Serializers { implicit val implicitJsonAst: JsonAst = JacksonAst - implicit val implicitJsonStringParser: Parser[String, JsonAst] = JacksonParser + implicit val implicitJsonStringParser: Parser[String, JsonAst] = + JacksonParser } diff --git a/json-jackson/shared/src/main/scala/rapture/json-jackson/parse.scala b/json-jackson/shared/src/main/scala/rapture/json-jackson/parse.scala index 9ced47a..41642ec 100644 --- a/json-jackson/shared/src/main/scala/rapture/json-jackson/parse.scala +++ b/json-jackson/shared/src/main/scala/rapture/json-jackson/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jackson import rapture.core._ @@ -23,14 +23,13 @@ import rapture.data._ import com.fasterxml.jackson.databind.ObjectMapper private[jackson] object JacksonParser extends Parser[String, JsonAst] { - + val ast = JacksonAst - + override def toString = "" - + private val mapper = new ObjectMapper() - + def parse(s: String): Option[Any] = Some(mapper.readTree(s)) } - diff --git a/json-jackson/shared/src/main/scala/rapture/json-jackson/serializers.scala b/json-jackson/shared/src/main/scala/rapture/json-jackson/serializers.scala index 9821476..86cb7b5 100644 --- a/json-jackson/shared/src/main/scala/rapture/json-jackson/serializers.scala +++ b/json-jackson/shared/src/main/scala/rapture/json-jackson/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jackson @@ -21,7 +21,7 @@ import rapture.json._ private[jackson] trait Serializers { import com.fasterxml.jackson.databind._ - + implicit val jacksonJsonNodeSerializer: DirectJsonSerializer[JsonNode] = - DirectJsonSerializer(JacksonAst) + DirectJsonSerializer(JacksonAst) } diff --git a/json-jawn/shared/src/main/scala/rapture/json-jawn/ast.scala b/json-jawn/shared/src/main/scala/rapture/json-jawn/ast.scala index 4dab391..568e469 100644 --- a/json-jawn/shared/src/main/scala/rapture/json-jawn/ast.scala +++ b/json-jawn/shared/src/main/scala/rapture/json-jawn/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jawn @@ -26,21 +26,22 @@ import rapture.data.MissingValueException import jawn.ast._ private[jawn] object JawnAst extends JsonBufferAst { - + override def dereferenceObject(obj: Any, element: String): Any = obj match { - case JObject(obj) => try obj(element) catch { - case e: Exception => throw MissingValueException() - } + case JObject(obj) => + try obj(element) catch { + case e: Exception => throw MissingValueException() + } case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case JObject(obj) => obj.keys.iterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { case JArray(arr) => arr(element) @@ -48,7 +49,7 @@ private[jawn] object JawnAst extends JsonBufferAst { } def getArray(array: Any): List[Any] = array match { - case JArray(xs)=> xs.toList + case JArray(xs) => xs.toList case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } @@ -58,50 +59,55 @@ private[jawn] object JawnAst extends JsonBufferAst { case JFalse => false case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case DoubleNum(d) => BigDecimal(d) case DeferLong(v) => BigDecimal(v) case DeferNum(v) => BigDecimal(v) - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getDouble(double: Any): Double = double match { case DoubleNum(d) => d case DeferLong(v) => v.toDouble case DeferNum(v) => java.lang.Double.valueOf(v) case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getString(string: Any): String = string match { case JString(s) => s case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { case JObject(o) => o.toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = { obj.asInstanceOf[JObject].vs(name) = value.asInstanceOf[JValue] obj } - + def removeObjectValue(obj: Any, name: String): Any = { obj.asInstanceOf[JObject].vs -= name obj } - + def addArrayValue(array: Any, value: Any): Any = JArray(array.asInstanceOf[JArray].vs :+ value.asInstanceOf[JValue]) - + def setArrayValue(array: Any, index: Int, value: Any): Any = - JArray(array.asInstanceOf[JArray].vs.padTo(index, null).patch(index, - Seq(value.asInstanceOf[JValue]), 1)) - + JArray( + array + .asInstanceOf[JArray] + .vs + .padTo(index, null) + .patch(index, Seq(value.asInstanceOf[JValue]), 1)) + def isArray(array: Any): Boolean = array match { - case JArray(xs)=> true + case JArray(xs) => true case _ => false } @@ -109,39 +115,41 @@ private[jawn] object JawnAst extends JsonBufferAst { case JTrue | JFalse => true case _ => false } - + def isNumber(num: Any): Boolean = num match { case DoubleNum(_) | DeferLong(_) | DeferNum(_) => true case _ => false } - + def isString(string: Any): Boolean = string match { case JString(_) => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case JObject(_) => true case _ => false } - + def isNull(obj: Any): Boolean = obj match { case JNull => true case _ => false } - - def fromArray(array: Seq[Any]): Any = JArray(array.to[Array] map { case v: JValue => v }) - def fromBoolean(boolean: Boolean): Any = if(boolean) JTrue else JFalse + + def fromArray(array: Seq[Any]): Any = + JArray(array.to[Array] map { case v: JValue => v }) + def fromBoolean(boolean: Boolean): Any = if (boolean) JTrue else JFalse def fromDouble(number: Double): Any = DoubleNum(number) def fromBigDecimal(number: BigDecimal): Any = DeferNum(number.toString) - - def fromObject(obj: Map[String,Any]): Any = - JObject(collection.mutable.Map(obj.mapValues{ case v: JValue => v }.to[Seq]: _*)) - + + def fromObject(obj: Map[String, Any]): Any = + JObject( + collection.mutable.Map( + obj.mapValues { case v: JValue => v }.to[Seq]: _*)) + def fromString(string: String): Any = JString(string) val nullValue = JNull override def toString = "" - } diff --git a/json-jawn/shared/src/main/scala/rapture/json-jawn/extractors.scala b/json-jawn/shared/src/main/scala/rapture/json-jawn/extractors.scala index a17294c..0a4a7de 100644 --- a/json-jawn/shared/src/main/scala/rapture/json-jawn/extractors.scala +++ b/json-jawn/shared/src/main/scala/rapture/json-jawn/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jawn @@ -25,28 +25,28 @@ import _root_.jawn.ast._ private[jawn] trait Extractors { implicit val jawnJObjectExtractor: JsonCastExtractor[JObject] = JsonCastExtractor(JawnAst, DataTypes.Object) - + implicit val jawnJArrayExtractor: JsonCastExtractor[JArray] = JsonCastExtractor(JawnAst, DataTypes.Array) - + implicit val jawnDeferNumExtractor: JsonCastExtractor[DeferNum] = JsonCastExtractor(JawnAst, DataTypes.Number) - + implicit val jawnDoubleNumExtractor: JsonCastExtractor[DoubleNum] = JsonCastExtractor(JawnAst, DataTypes.Number) - + implicit val jawnLongNumExtractor: JsonCastExtractor[LongNum] = JsonCastExtractor(JawnAst, DataTypes.Number) - - implicit val jawnJNumExtractor: JsonCastExtractor[JNum] = - JsonCastExtractor(JawnAst, DataTypes.Number) - + + implicit val jawnJNumExtractor: JsonCastExtractor[JNum] = JsonCastExtractor( + JawnAst, DataTypes.Number) + implicit val jawnStringExtractor: JsonCastExtractor[JString] = JsonCastExtractor(JawnAst, DataTypes.String) - - implicit val jawnAtomExtractor: JsonCastExtractor[JAtom] = - JsonCastExtractor(JawnAst, DataTypes.Scalar) - + + implicit val jawnAtomExtractor: JsonCastExtractor[JAtom] = JsonCastExtractor( + JawnAst, DataTypes.Scalar) + implicit val jawnValueExtractor: JsonCastExtractor[JValue] = JsonCastExtractor(JawnAst, DataTypes.Any) } diff --git a/json-jawn/shared/src/main/scala/rapture/json-jawn/package.scala b/json-jawn/shared/src/main/scala/rapture/json-jawn/package.scala index c8443ea..cffd5e0 100644 --- a/json-jawn/shared/src/main/scala/rapture/json-jawn/package.scala +++ b/json-jawn/shared/src/main/scala/rapture/json-jawn/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jawn @@ -30,17 +30,22 @@ private[jawn] trait package_1 { object `package` extends package_1 with Extractors with Serializers { implicit val implicitJsonAst: JsonBufferAst = JawnAst - implicit def implicitJsonStringParser(implicit f: Facade[_]): Parser[String, JsonBufferAst] = + implicit def implicitJsonStringParser( + implicit f: Facade[_]): Parser[String, JsonBufferAst] = new JawnStringParser - - implicit def implicitJsonByteBufferParser(implicit f: Facade[_]): Parser[java.nio.ByteBuffer, - JsonBufferAst] = new JawnByteBufferParser - - implicit def implicitJsonFileParser(implicit f: Facade[_]): Parser[java.io.File, - JsonBufferAst] = new JawnFileParser - implicit def jsonFormatterImplicit[Ast <: JsonAst](implicit ast: Ast): Formatter[Ast] { - type Out = String } = new Formatter[Ast] { + implicit def implicitJsonByteBufferParser( + implicit f: Facade[_]): Parser[java.nio.ByteBuffer, JsonBufferAst] = + new JawnByteBufferParser + + implicit def implicitJsonFileParser( + implicit f: Facade[_]): Parser[java.io.File, JsonBufferAst] = + new JawnFileParser + + implicit def jsonFormatterImplicit[Ast <: JsonAst](implicit ast: Ast + ): Formatter[Ast] { + type Out = String + } = new Formatter[Ast] { type Out = String def format(json: Any): String = json match { case jv: JValue => jv.render(FastRenderer) diff --git a/json-jawn/shared/src/main/scala/rapture/json-jawn/parse.scala b/json-jawn/shared/src/main/scala/rapture/json-jawn/parse.scala index 991dda5..dade5a1 100644 --- a/json-jawn/shared/src/main/scala/rapture/json-jawn/parse.scala +++ b/json-jawn/shared/src/main/scala/rapture/json-jawn/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jawn @@ -23,28 +23,31 @@ import rapture.json._ import jawn.{Parser => JawnParser, _} -private[jawn] class JawnStringParser(implicit f: Facade[_]) extends Parser[String, JsonBufferAst] { - +private[jawn] class JawnStringParser(implicit f: Facade[_]) + extends Parser[String, JsonBufferAst] { + override def toString = "" - + val ast = JawnAst def parse(s: String): Option[Any] = JawnParser.parseFromString(s).toOption } -private[jawn] class JawnByteBufferParser(implicit f: Facade[_]) extends Parser[java.nio.ByteBuffer, - JsonBufferAst] { - +private[jawn] class JawnByteBufferParser(implicit f: Facade[_]) + extends Parser[java.nio.ByteBuffer, JsonBufferAst] { + override def toString = "" - + val ast = JawnAst def parse(buf: java.nio.ByteBuffer): Option[Any] = JawnParser.parseFromByteBuffer(buf).toOption } -private[jawn] class JawnFileParser(implicit f: Facade[_]) extends Parser[java.io.File, JsonBufferAst] { - +private[jawn] class JawnFileParser(implicit f: Facade[_]) + extends Parser[java.io.File, JsonBufferAst] { + override def toString = "" - + val ast = JawnAst - def parse(file: java.io.File): Option[Any] = JawnParser.parseFromFile(file).toOption + def parse(file: java.io.File): Option[Any] = + JawnParser.parseFromFile(file).toOption } diff --git a/json-jawn/shared/src/main/scala/rapture/json-jawn/serializers.scala b/json-jawn/shared/src/main/scala/rapture/json-jawn/serializers.scala index 6360159..f41137a 100644 --- a/json-jawn/shared/src/main/scala/rapture/json-jawn/serializers.scala +++ b/json-jawn/shared/src/main/scala/rapture/json-jawn/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.jawn diff --git a/json-json4s/shared/src/main/scala/rapture/json-json4s/ast.scala b/json-json4s/shared/src/main/scala/rapture/json-json4s/ast.scala index 13482a6..f02fa66 100644 --- a/json-json4s/shared/src/main/scala/rapture/json-json4s/ast.scala +++ b/json-json4s/shared/src/main/scala/rapture/json-json4s/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.json4s @@ -29,92 +29,98 @@ private[json4s] object Json4sAst extends JsonBufferAst { override def toString = "" def getArray(array: Any): List[Any] = array match { - case JArray(xs)=> xs.toList + case JArray(xs) => xs.toList case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } - def fromArray(array: Seq[Any]): Any = JArray(array.to[List] map { case v: JValue => v }) - + def fromArray(array: Seq[Any]): Any = + JArray(array.to[List] map { case v: JValue => v }) + def getBoolean(boolean: Any): Boolean = boolean match { case boolean: Boolean => boolean case JBool(v) => v case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def fromBoolean(boolean: Boolean): Any = JBool(boolean) - + def getDouble(double: Any): Double = double match { case JDouble(d) => d case JInt(v) => v.toDouble case JDecimal(v) => v.toDouble case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case JDecimal(v) => v case JDouble(d) => BigDecimal(d) case JInt(v) => BigDecimal(v) - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def fromDouble(number: Double): Any = JDouble(number) def fromBigDecimal(number: BigDecimal): Any = JDecimal(number) - + def getString(string: Any): String = string match { case JString(s) => s case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def fromString(string: String): Any = JString(string) def getObject(obj: Any): Map[String, Any] = obj match { case JObject(o) => o.toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - - def fromObject(obj: Map[String,Any]): Any = - JObject(obj.mapValues{ case v: JValue => v }.to[List]) - + + def fromObject(obj: Map[String, Any]): Any = + JObject(obj.mapValues { case v: JValue => v }.to[List]) + def setObjectValue(obj: Any, name: String, value: Any): Any = { - val contents = (name, value) :: obj.asInstanceOf[JObject].obj.filter(_._1 != name) + val contents = + (name, value) :: obj.asInstanceOf[JObject].obj.filter(_._1 != name) JObject(contents map { case (k: String, v: JValue) => k -> v }) } - + def removeObjectValue(obj: Any, name: String): Any = JObject(obj.asInstanceOf[JObject].obj.filter(_._1 == name)) - + def addArrayValue(array: Any, value: Any): Any = JArray(array.asInstanceOf[JArray].arr :+ value.asInstanceOf[JValue]) - + def setArrayValue(array: Any, index: Int, value: Any): Any = array match { case array: JArray => - JArray(array.arr.padTo(index, JNull).patch(index, Seq(value.asInstanceOf[JValue]), 1)) + JArray( + array.arr + .padTo(index, JNull) + .patch(index, Seq(value.asInstanceOf[JValue]), 1)) case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } - + def isBoolean(boolean: Any): Boolean = boolean match { case JBool(_) => true case _ => false } - + def isString(string: Any): Boolean = string match { case JString(_) => true case _ => false } - + def isNumber(num: Any): Boolean = num match { case JDecimal(_) | JInt(_) | JDouble(_) => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case JObject(_) => true case _ => false } - + def isArray(array: Any): Boolean = array match { - case JArray(xs)=> true + case JArray(xs) => true case _ => false } @@ -122,7 +128,7 @@ private[json4s] object Json4sAst extends JsonBufferAst { case JNull => true case _ => false } - + def nullValue: Any = JNull override def dereferenceObject(obj: Any, element: String): Any = @@ -130,13 +136,13 @@ private[json4s] object Json4sAst extends JsonBufferAst { case JObject(obj) => obj.find(_._1 == element).get._2 case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case JObject(obj) => obj.map(_._1).iterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { case JArray(arr) => arr(element) diff --git a/json-json4s/shared/src/main/scala/rapture/json-json4s/extractors.scala b/json-json4s/shared/src/main/scala/rapture/json-json4s/extractors.scala index 0f01d14..dcf3be5 100644 --- a/json-json4s/shared/src/main/scala/rapture/json-json4s/extractors.scala +++ b/json-json4s/shared/src/main/scala/rapture/json-json4s/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.json4s @@ -25,22 +25,22 @@ import org.json4s._ private[json4s] trait Extractors { implicit val json4sJValueExtractor: JsonCastExtractor[JValue] = JsonCastExtractor(Json4sAst, DataTypes.Any) - + implicit val json4sJDecimalExtractor: JsonCastExtractor[JDecimal] = JsonCastExtractor(Json4sAst, DataTypes.Number) - + implicit val json4sJDoubleExtractor: JsonCastExtractor[JDouble] = JsonCastExtractor(Json4sAst, DataTypes.Number) - + implicit val json4sJStringExtractor: JsonCastExtractor[JString] = JsonCastExtractor(Json4sAst, DataTypes.String) - + implicit val json4sJIntExtractor: JsonCastExtractor[JInt] = JsonCastExtractor(Json4sAst, DataTypes.Number) - + implicit val json4sJArrayExtractor: JsonCastExtractor[JArray] = JsonCastExtractor(Json4sAst, DataTypes.Array) - + implicit val json4sJObjectExtractor: JsonCastExtractor[JObject] = JsonCastExtractor(Json4sAst, DataTypes.Object) } diff --git a/json-json4s/shared/src/main/scala/rapture/json-json4s/package.scala b/json-json4s/shared/src/main/scala/rapture/json-json4s/package.scala index f2fbf82..e3b460d 100644 --- a/json-json4s/shared/src/main/scala/rapture/json-json4s/package.scala +++ b/json-json4s/shared/src/main/scala/rapture/json-json4s/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.json4s diff --git a/json-json4s/shared/src/main/scala/rapture/json-json4s/parse.scala b/json-json4s/shared/src/main/scala/rapture/json-json4s/parse.scala index 7746098..bb56dff 100644 --- a/json-json4s/shared/src/main/scala/rapture/json-json4s/parse.scala +++ b/json-json4s/shared/src/main/scala/rapture/json-json4s/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.json4s @@ -23,13 +23,13 @@ import rapture.json._ import org.json4s._ private[json4s] object Json4sParser extends Parser[String, JsonBufferAst] { - + val ast = Json4sAst def parse(s: String): Option[Any] = try Some(native.JsonParser.parse(s, useBigDecimalForDouble = true)) catch { case e: Exception => None } - + override def toString = "" } diff --git a/json-json4s/shared/src/main/scala/rapture/json-json4s/serializers.scala b/json-json4s/shared/src/main/scala/rapture/json-json4s/serializers.scala index 397733d..4ca9bf4 100644 --- a/json-json4s/shared/src/main/scala/rapture/json-json4s/serializers.scala +++ b/json-json4s/shared/src/main/scala/rapture/json-json4s/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.json4s diff --git a/json-lift/shared/src/main/scala/rapture/json-lift/ast.scala b/json-lift/shared/src/main/scala/rapture/json-lift/ast.scala index e02df42..124e8b7 100644 --- a/json-lift/shared/src/main/scala/rapture/json-lift/ast.scala +++ b/json-lift/shared/src/main/scala/rapture/json-lift/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.lift @@ -34,13 +34,13 @@ private[lift] object LiftAst extends JsonBufferAst { case JObject(obj) => obj.find(_.name == element).get.value case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case JObject(obj) => obj.map(_.name).iterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { case JArray(arr) => arr(element) @@ -48,7 +48,7 @@ private[lift] object LiftAst extends JsonBufferAst { } def getArray(array: Any): List[Any] = array match { - case JArray(xs)=> xs.toList + case JArray(xs) => xs.toList case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } @@ -57,51 +57,60 @@ private[lift] object LiftAst extends JsonBufferAst { case JBool(v) => v case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case JDouble(d) => BigDecimal(d) case JInt(v) => BigDecimal(v.toDouble) - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getDouble(double: Any): Double = double match { case JDouble(d) => d case JInt(v) => v.toDouble case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getString(string: Any): String = string match { case JString(s) => s case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { - case JObject(o) => o.map{ f => f.name -> f.value }.toMap + case JObject(o) => + o.map { f => + f.name -> f.value + }.toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = { - val contents = (name, value) :: obj.asInstanceOf[JObject].obj.filter(_.name != name) - JObject(contents map { + val contents = + (name, value) :: obj.asInstanceOf[JObject].obj.filter(_.name != name) + JObject( + contents map { case JField(k: String, v: JValue) => JField(k, v) case (k: String, v: JValue) => JField(k, v) }) } - + def removeObjectValue(obj: Any, name: String): Any = JObject(obj.asInstanceOf[JObject].obj.filter(_.name == name)) - + def addArrayValue(array: Any, value: Any): Any = JArray(array.asInstanceOf[JArray].arr :+ value.asInstanceOf[JValue]) - + def setArrayValue(array: Any, index: Int, value: Any): Any = array match { case array: JArray => - JArray(array.arr.padTo(index, JNull).patch(index, Seq(value.asInstanceOf[JValue]), 1)) + JArray( + array.arr + .padTo(index, JNull) + .patch(index, Seq(value.asInstanceOf[JValue]), 1)) case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } - + def isArray(array: Any): Boolean = array match { - case JArray(xs)=> true + case JArray(xs) => true case _ => false } @@ -109,37 +118,37 @@ private[lift] object LiftAst extends JsonBufferAst { case JBool(_) => true case _ => false } - + def isNumber(num: Any): Boolean = num match { case JInt(_) | JDouble(_) => true case _ => false } - + def isString(string: Any): Boolean = string match { case JString(_) => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case JObject(_) => true case _ => false } - + def isNull(obj: Any): Boolean = obj match { case JNull => true case _ => false } - + def nullValue: Any = JNull - - def fromArray(array: Seq[Any]): Any = JArray(array.to[List] map { case v: JValue => v }) + + def fromArray(array: Seq[Any]): Any = + JArray(array.to[List] map { case v: JValue => v }) def fromBoolean(boolean: Boolean): Any = JBool(boolean) def fromDouble(number: Double): Any = JDouble(number) def fromBigDecimal(number: BigDecimal): Any = JDouble(number.toDouble) - - def fromObject(obj: Map[String,Any]): Any = - JObject(obj.map{ case (k, v: JValue) => JField(k, v) }.to[List]) - - def fromString(string: String): Any = JString(string) + def fromObject(obj: Map[String, Any]): Any = + JObject(obj.map { case (k, v: JValue) => JField(k, v) }.to[List]) + + def fromString(string: String): Any = JString(string) } diff --git a/json-lift/shared/src/main/scala/rapture/json-lift/extractors.scala b/json-lift/shared/src/main/scala/rapture/json-lift/extractors.scala index 593c2ae..11e607a 100644 --- a/json-lift/shared/src/main/scala/rapture/json-lift/extractors.scala +++ b/json-lift/shared/src/main/scala/rapture/json-lift/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.lift @@ -26,19 +26,19 @@ import JsonAST._ private[lift] trait Extractors { implicit val liftJValueExtractor: JsonCastExtractor[JValue] = JsonCastExtractor(LiftAst, DataTypes.Any) - + implicit val liftJStringExtractor: JsonCastExtractor[JString] = JsonCastExtractor(LiftAst, DataTypes.String) - - implicit val liftJIntExtractor: JsonCastExtractor[JInt] = - JsonCastExtractor(LiftAst, DataTypes.Number) - + + implicit val liftJIntExtractor: JsonCastExtractor[JInt] = JsonCastExtractor( + LiftAst, DataTypes.Number) + implicit val liftJDoubleExtractor: JsonCastExtractor[JDouble] = JsonCastExtractor(LiftAst, DataTypes.Number) - + implicit val liftJArrayExtractor: JsonCastExtractor[JArray] = JsonCastExtractor(LiftAst, DataTypes.Array) - + implicit val liftJObjectExtractor: JsonCastExtractor[JObject] = JsonCastExtractor(LiftAst, DataTypes.Object) } diff --git a/json-lift/shared/src/main/scala/rapture/json-lift/package.scala b/json-lift/shared/src/main/scala/rapture/json-lift/package.scala index 9bd7938..f885313 100644 --- a/json-lift/shared/src/main/scala/rapture/json-lift/package.scala +++ b/json-lift/shared/src/main/scala/rapture/json-lift/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.lift diff --git a/json-lift/shared/src/main/scala/rapture/json-lift/parse.scala b/json-lift/shared/src/main/scala/rapture/json-lift/parse.scala index e6317a3..4475c4d 100644 --- a/json-lift/shared/src/main/scala/rapture/json-lift/parse.scala +++ b/json-lift/shared/src/main/scala/rapture/json-lift/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.lift diff --git a/json-lift/shared/src/main/scala/rapture/json-lift/serializers.scala b/json-lift/shared/src/main/scala/rapture/json-lift/serializers.scala index 6565083..a465352 100644 --- a/json-lift/shared/src/main/scala/rapture/json-lift/serializers.scala +++ b/json-lift/shared/src/main/scala/rapture/json-lift/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.lift diff --git a/json-play/shared/src/main/scala/rapture/json-play/ast.scala b/json-play/shared/src/main/scala/rapture/json-play/ast.scala index 5fb06ff..81a7c83 100644 --- a/json-play/shared/src/main/scala/rapture/json-play/ast.scala +++ b/json-play/shared/src/main/scala/rapture/json-play/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.play @@ -28,25 +28,27 @@ private[play] object PlayAst extends JsonBufferAst { override def toString = "" override def dereferenceObject(obj: Any, element: String): Any = obj match { - case obj@JsObject(_) => obj \ element match { - case JsDefined(v) => v - case _ => throw MissingValueException() - } + case obj @ JsObject(_) => + obj \ element match { + case JsDefined(v) => v + case _ => throw MissingValueException() + } case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case obj: JsObject => obj.keys.iterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { - case arr@JsArray(_) => arr(element) match { - case JsDefined(v) => v - case _ => throw MissingValueException() - } + case arr @ JsArray(_) => + arr(element) match { + case JsDefined(v) => v + case _ => throw MissingValueException() + } case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } @@ -59,97 +61,107 @@ private[play] object PlayAst extends JsonBufferAst { case JsBoolean(v) => v case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { case JsNumber(n) => n - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getDouble(double: Any): Double = double match { case JsNumber(n) => n.toDouble case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getString(string: Any): String = string match { case JsString(s) => s case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { case JsObject(obj) => obj.toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = (value, obj) match { - case (value: JsValue, obj: JsValue) => PJson.toJson(obj.as[Map[String, JsValue]].updated(name, value)) + case (value: JsValue, obj: JsValue) => + PJson.toJson(obj.as[Map[String, JsValue]].updated(name, value)) } - + def removeObjectValue(obj: Any, name: String): Any = obj match { case obj: JsObject => PJson.toJson(obj.as[Map[String, JsValue]] - name) } - + def addArrayValue(array: Any, value: Any): Any = array match { - case v: JsValue => PJson.toJson(v.as[Array[JsValue]] :+ value.asInstanceOf[JsValue]) + case v: JsValue => + PJson.toJson(v.as[Array[JsValue]] :+ value.asInstanceOf[JsValue]) } - + def setArrayValue(array: Any, index: Int, value: Any): Any = array match { case v: JsValue => val array = v.as[Array[JsValue]] - PJson.toJson(array.padTo(index, JsNull: JsValue).patch(index, Seq(value.asInstanceOf[JsValue]), 1)) + PJson.toJson(array + .padTo(index, JsNull: JsValue) + .patch(index, Seq(value.asInstanceOf[JsValue]), 1)) } - - def isArray(array: Any): Boolean = try { - array match { - case JsArray(_) => true - case _ => false - } - } catch { case e: Exception => false } - def isBoolean(boolean: Any): Boolean = try { - boolean match { - case JsBoolean(boolean) => true - case _ => false - } - } catch { case e: Exception => false } + def isArray(array: Any): Boolean = + try { + array match { + case JsArray(_) => true + case _ => false + } + } catch { case e: Exception => false } - def isNumber(num: Any): Boolean = try { - num match { - case JsNumber(_) => true - case _ => false - } - } catch { case e: Exception => false } + def isBoolean(boolean: Any): Boolean = + try { + boolean match { + case JsBoolean(boolean) => true + case _ => false + } + } catch { case e: Exception => false } - def isString(string: Any): Boolean = try { - string match { - case JsString(s) => true - case _ => false - //case JsDefined(string) => string.asOpt[String].isDefined - } - } catch { case e: Exception => false } + def isNumber(num: Any): Boolean = + try { + num match { + case JsNumber(_) => true + case _ => false + } + } catch { case e: Exception => false } + + def isString(string: Any): Boolean = + try { + string match { + case JsString(s) => true + case _ => false + //case JsDefined(string) => string.asOpt[String].isDefined + } + } catch { case e: Exception => false } + + def isObject(obj: Any): Boolean = + try { + obj match { + case JsObject(obj) => true + case _ => false + } + } catch { case e: Exception => false } - def isObject(obj: Any): Boolean = try { - obj match { - case JsObject(obj) => true - case _ => false - } - } catch { case e: Exception => false } - def isNull(obj: Any): Boolean = obj match { case JsDefined(JsNull) => true case _ => false } - + val nullValue: Any = JsNull - - def fromArray(array: Seq[Any]): Any = PJson.toJson(array.map(_.asInstanceOf[JsValue])) + + def fromArray(array: Seq[Any]): Any = + PJson.toJson(array.map(_.asInstanceOf[JsValue])) def fromBoolean(boolean: Boolean): Any = PJson.toJson(boolean) def fromDouble(number: Double): Any = PJson.toJson(number) def fromBigDecimal(number: BigDecimal): Any = PJson.toJson(number) - + def fromObject(obj: Map[String, Any]): Any = PJson.toJson(obj.map { case (k, v: JsValue) => (k, v) }) - - def fromString(string: String): Any = PJson.toJson(string) + def fromString(string: String): Any = PJson.toJson(string) } diff --git a/json-play/shared/src/main/scala/rapture/json-play/extraction.scala b/json-play/shared/src/main/scala/rapture/json-play/extraction.scala index a5f963e..6349754 100644 --- a/json-play/shared/src/main/scala/rapture/json-play/extraction.scala +++ b/json-play/shared/src/main/scala/rapture/json-play/extraction.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.play @@ -25,10 +25,10 @@ import play.api.libs.json._ private[play] trait Extractors { implicit val playJsValueExtractor: JsonCastExtractor[JsValue] = JsonCastExtractor(PlayAst, DataTypes.Any) - + implicit val playJsObjectExtractor: JsonCastExtractor[JsObject] = JsonCastExtractor(PlayAst, DataTypes.Object) - + implicit val playJsArrayExtractor: JsonCastExtractor[JsArray] = JsonCastExtractor(PlayAst, DataTypes.Array) } diff --git a/json-play/shared/src/main/scala/rapture/json-play/package.scala b/json-play/shared/src/main/scala/rapture/json-play/package.scala index 7c15537..cf0082d 100644 --- a/json-play/shared/src/main/scala/rapture/json-play/package.scala +++ b/json-play/shared/src/main/scala/rapture/json-play/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.play diff --git a/json-play/shared/src/main/scala/rapture/json-play/parse.scala b/json-play/shared/src/main/scala/rapture/json-play/parse.scala index 963a2df..f32ce3d 100644 --- a/json-play/shared/src/main/scala/rapture/json-play/parse.scala +++ b/json-play/shared/src/main/scala/rapture/json-play/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.play diff --git a/json-play/shared/src/main/scala/rapture/json-play/serializers.scala b/json-play/shared/src/main/scala/rapture/json-play/serializers.scala index 5ffd738..934eefe 100644 --- a/json-play/shared/src/main/scala/rapture/json-play/serializers.scala +++ b/json-play/shared/src/main/scala/rapture/json-play/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.play @@ -24,7 +24,7 @@ import play.api.libs.json._ private[play] trait Serializers { implicit val playJsValueSerializer: DirectJsonSerializer[JsValue] = DirectJsonSerializer(PlayAst) - + implicit val playJsObjectSerializer: DirectJsonSerializer[JsObject] = DirectJsonSerializer(PlayAst) } diff --git a/json-spray/shared/src/main/scala/rapture/json-spray/ast.scala b/json-spray/shared/src/main/scala/rapture/json-spray/ast.scala index dbbd755..0603896 100644 --- a/json-spray/shared/src/main/scala/rapture/json-spray/ast.scala +++ b/json-spray/shared/src/main/scala/rapture/json-spray/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.spray @@ -31,18 +31,19 @@ private[spray] object SprayAst extends JsonBufferAst { override def dereferenceObject(obj: Any, element: String): Any = obj match { - case obj: JsObject => try obj.getFields(element)(0) catch { - case e: IndexOutOfBoundsException => throw MissingValueException() - } + case obj: JsObject => + try obj.getFields(element)(0) catch { + case e: IndexOutOfBoundsException => throw MissingValueException() + } case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def getKeys(obj: Any): Iterator[String] = obj match { case obj: JsObject => obj.fields.keysIterator case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + override def dereferenceArray(array: Any, element: Int): Any = array match { case v: JsValue => @@ -52,132 +53,152 @@ private[spray] object SprayAst extends JsonBufferAst { } def getArray(array: Any): List[Any] = array match { - case v: JsValue => try v.convertTo[List[JsValue]] catch { - case e: Exception => throw TypeMismatchException(getType(array), DataTypes.Array) - } + case v: JsValue => + try v.convertTo[List[JsValue]] catch { + case e: Exception => + throw TypeMismatchException(getType(array), DataTypes.Array) + } case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } def getBoolean(boolean: Any): Boolean = boolean match { - case v: JsValue => try v.convertTo[Boolean] catch { - case e: Exception => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) - } + case v: JsValue => + try v.convertTo[Boolean] catch { + case e: Exception => + throw TypeMismatchException(getType(boolean), DataTypes.Boolean) + } case _ => throw TypeMismatchException(getType(boolean), DataTypes.Boolean) } - + def getBigDecimal(bigDecimal: Any): BigDecimal = bigDecimal match { - case v: JsValue => try v.convertTo[BigDecimal] catch { - case e: Exception => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) - } - case _ => throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + case v: JsValue => + try v.convertTo[BigDecimal] catch { + case e: Exception => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) + } + case _ => + throw TypeMismatchException(getType(bigDecimal), DataTypes.Number) } - + def getDouble(double: Any): Double = double match { - case v: JsValue => try v.convertTo[Double] catch { - case e: Exception => throw TypeMismatchException(getType(double), DataTypes.Number) - } + case v: JsValue => + try v.convertTo[Double] catch { + case e: Exception => + throw TypeMismatchException(getType(double), DataTypes.Number) + } case _ => throw TypeMismatchException(getType(double), DataTypes.Number) } - + def getString(string: Any): String = string match { - case v: JsValue => try v.convertTo[String] catch { - case e: Exception => throw TypeMismatchException(getType(string), DataTypes.String) - } + case v: JsValue => + try v.convertTo[String] catch { + case e: Exception => + throw TypeMismatchException(getType(string), DataTypes.String) + } case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { case v: JsObject => v.fields case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def setObjectValue(obj: Any, name: String, value: Any): Any = (value, obj) match { - case (value: JsValue, obj: JsValue) => obj.asJsObject.fields.updated(name, value).toJson + case (value: JsValue, obj: JsValue) => + obj.asJsObject.fields.updated(name, value).toJson } - + def removeObjectValue(obj: Any, name: String): Any = obj match { case obj: JsObject => (obj.fields - name).toJson } - + def addArrayValue(array: Any, value: Any): Any = array match { - case v: JsValue => (v.convertTo[Array[JsValue]] :+ value.asInstanceOf[JsValue]).toJson + case v: JsValue => + (v.convertTo[Array[JsValue]] :+ value.asInstanceOf[JsValue]).toJson } - + def setArrayValue(array: Any, index: Int, value: Any): Any = array match { case v: JsValue => val array = v.convertTo[Array[JsValue]] - array.padTo(index, JsNull: JsValue).patch(index, Seq(value.asInstanceOf[JsValue]), 1).toJson + array + .padTo(index, JsNull: JsValue) + .patch(index, Seq(value.asInstanceOf[JsValue]), 1) + .toJson } - - def isArray(array: Any): Boolean = try { - array match { - case array: JsValue => - array.convertTo[Array[JsValue]] - true - case _ => false + + def isArray(array: Any): Boolean = + try { + array match { + case array: JsValue => + array.convertTo[Array[JsValue]] + true + case _ => false + } + } catch { + case e: DeserializationException => false } - } catch { - case e: DeserializationException => false - } - def isBoolean(boolean: Any): Boolean = try { - boolean match { - case boolean: JsValue => - boolean.convertTo[Boolean] - true - case _ => false + def isBoolean(boolean: Any): Boolean = + try { + boolean match { + case boolean: JsValue => + boolean.convertTo[Boolean] + true + case _ => false + } + } catch { + case e: ClassCastException => false + case e: DeserializationException => false } - } catch { - case e: ClassCastException => false - case e: DeserializationException => false - } - def isNumber(num: Any): Boolean = try { - num match { - case JsNull => false - case num: JsValue => - num.convertTo[Double] - true - case _ => false + def isNumber(num: Any): Boolean = + try { + num match { + case JsNull => false + case num: JsValue => + num.convertTo[Double] + true + case _ => false + } + } catch { + case e: ClassCastException => false + case e: DeserializationException => false } - } catch { - case e: ClassCastException => false - case e: DeserializationException => false - } - def isString(string: Any): Boolean = try { - string match { - case string: JsValue => - string.convertTo[String] - true - case _ => false + def isString(string: Any): Boolean = + try { + string match { + case string: JsValue => + string.convertTo[String] + true + case _ => false + } + } catch { + case e: ClassCastException => false + case e: DeserializationException => false } - } catch { - case e: ClassCastException => false - case e: DeserializationException => false - } def isObject(obj: Any): Boolean = obj match { case obj: JsObject => true case _ => false } - + def isNull(obj: Any): Boolean = obj match { case JsNull => true case _ => false } - + def nullValue: Any = JsNull - - def fromArray(array: Seq[Any]): Any = array.map(_.asInstanceOf[JsValue]).toJson + + def fromArray(array: Seq[Any]): Any = + array.map(_.asInstanceOf[JsValue]).toJson def fromBoolean(boolean: Boolean): Any = boolean.toJson def fromDouble(number: Double): Any = number.toJson def fromBigDecimal(number: BigDecimal): Any = number.toJson - + def fromObject(obj: Map[String, Any]): Any = (obj.map { case (k, v: JsValue) => (k, v) }).toJson - - def fromString(string: String): Any = string.toJson + def fromString(string: String): Any = string.toJson } diff --git a/json-spray/shared/src/main/scala/rapture/json-spray/extraction.scala b/json-spray/shared/src/main/scala/rapture/json-spray/extraction.scala index 77d566a..eda6925 100644 --- a/json-spray/shared/src/main/scala/rapture/json-spray/extraction.scala +++ b/json-spray/shared/src/main/scala/rapture/json-spray/extraction.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.spray @@ -25,7 +25,7 @@ import spray.json._ private[spray] trait Extractors { implicit val sprayJsValueExtractor: JsonCastExtractor[JsValue] = JsonCastExtractor(SprayAst, DataTypes.Any) - + implicit val sprayJsObjectExtractor: JsonCastExtractor[JsObject] = JsonCastExtractor(SprayAst, DataTypes.Object) } diff --git a/json-spray/shared/src/main/scala/rapture/json-spray/package.scala b/json-spray/shared/src/main/scala/rapture/json-spray/package.scala index 1e379af..1cd8056 100644 --- a/json-spray/shared/src/main/scala/rapture/json-spray/package.scala +++ b/json-spray/shared/src/main/scala/rapture/json-spray/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.spray diff --git a/json-spray/shared/src/main/scala/rapture/json-spray/parse.scala b/json-spray/shared/src/main/scala/rapture/json-spray/parse.scala index ff32ce5..6467b3c 100644 --- a/json-spray/shared/src/main/scala/rapture/json-spray/parse.scala +++ b/json-spray/shared/src/main/scala/rapture/json-spray/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.spray diff --git a/json-spray/shared/src/main/scala/rapture/json-spray/serializers.scala b/json-spray/shared/src/main/scala/rapture/json-spray/serializers.scala index 1c75ca5..22c3806 100644 --- a/json-spray/shared/src/main/scala/rapture/json-spray/serializers.scala +++ b/json-spray/shared/src/main/scala/rapture/json-spray/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.jsonBackends.spray @@ -24,7 +24,7 @@ import spray.json._ private[spray] trait Serializers { implicit val sprayJsValueSerializer: DirectJsonSerializer[JsValue] = DirectJsonSerializer(SprayAst) - + implicit val sprayJsObjectSerializer: DirectJsonSerializer[JsObject] = DirectJsonSerializer(SprayAst) } diff --git a/json-test/shared/src/test/scala/rapture/json-test/tests.scala b/json-test/shared/src/test/scala/rapture/json-test/tests.scala index c1b0c0f..064bedd 100644 --- a/json-test/shared/src/test/scala/rapture/json-test/tests.scala +++ b/json-test/shared/src/test/scala/rapture/json-test/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json.test @@ -46,23 +46,47 @@ class TestRun extends Programme { import jsonBackends._ -object PlayTests extends JsonTests(play.implicitJsonAst, play.implicitJsonStringParser) -object JawnTests extends JsonTests(jawn.implicitJsonAst, jawn.implicitJsonStringParser(jawn.jawnFacade)) -object Json4sTests extends JsonTests(json4s.implicitJsonAst, json4s.implicitJsonStringParser) -object SprayTests extends JsonTests(spray.implicitJsonAst, spray.implicitJsonStringParser) -object JacksonTests extends JsonTests(jackson.implicitJsonAst, jackson.implicitJsonStringParser) -object ArgonautTests extends JsonTests(argonaut.implicitJsonAst, argonaut.implicitJsonStringParser) -object CirceTests extends JsonTests(circe.implicitJsonAst, circe.implicitJsonStringParser) -object LiftTests extends JsonTests(lift.implicitJsonAst, lift.implicitJsonStringParser) - -object MutablePlayTests extends MutableJsonTests(play.implicitJsonAst, play.implicitJsonStringParser) -object MutableJawnTests extends MutableJsonTests(jawn.implicitJsonAst, jawn.implicitJsonStringParser(jawn.jawnFacade)) -object MutableJson4sTests extends MutableJsonTests(json4s.implicitJsonAst, json4s.implicitJsonStringParser) -object MutableSprayTests extends MutableJsonTests(spray.implicitJsonAst, spray.implicitJsonStringParser) -object MutableArgonautTests extends MutableJsonTests(argonaut.implicitJsonAst, argonaut.implicitJsonStringParser) -object MutableCirceTests extends MutableJsonTests(circe.implicitJsonAst, circe.implicitJsonStringParser) -object MutableLiftTests extends MutableJsonTests(lift.implicitJsonAst, lift.implicitJsonStringParser) - +object PlayTests + extends JsonTests(play.implicitJsonAst, play.implicitJsonStringParser) +object JawnTests + extends JsonTests( + jawn.implicitJsonAst, jawn.implicitJsonStringParser(jawn.jawnFacade)) +object Json4sTests + extends JsonTests(json4s.implicitJsonAst, json4s.implicitJsonStringParser) +object SprayTests + extends JsonTests(spray.implicitJsonAst, spray.implicitJsonStringParser) +object JacksonTests + extends JsonTests( + jackson.implicitJsonAst, jackson.implicitJsonStringParser) +object ArgonautTests + extends JsonTests( + argonaut.implicitJsonAst, argonaut.implicitJsonStringParser) +object CirceTests + extends JsonTests(circe.implicitJsonAst, circe.implicitJsonStringParser) +object LiftTests + extends JsonTests(lift.implicitJsonAst, lift.implicitJsonStringParser) + +object MutablePlayTests + extends MutableJsonTests( + play.implicitJsonAst, play.implicitJsonStringParser) +object MutableJawnTests + extends MutableJsonTests( + jawn.implicitJsonAst, jawn.implicitJsonStringParser(jawn.jawnFacade)) +object MutableJson4sTests + extends MutableJsonTests( + json4s.implicitJsonAst, json4s.implicitJsonStringParser) +object MutableSprayTests + extends MutableJsonTests( + spray.implicitJsonAst, spray.implicitJsonStringParser) +object MutableArgonautTests + extends MutableJsonTests( + argonaut.implicitJsonAst, argonaut.implicitJsonStringParser) +object MutableCirceTests + extends MutableJsonTests( + circe.implicitJsonAst, circe.implicitJsonStringParser) +object MutableLiftTests + extends MutableJsonTests( + lift.implicitJsonAst, lift.implicitJsonStringParser) case class Foo(alpha: String, beta: Int) case class Bar(foo: Foo, gamma: Double) @@ -80,7 +104,8 @@ case class D(d: E) case class E(e: F) case class F(f: Int) -abstract class JsonTests(ast: JsonAst, parser: Parser[String, JsonAst]) extends TestSuite { +abstract class JsonTests(ast: JsonAst, parser: Parser[String, JsonAst]) + extends TestSuite { implicit def implicitAst: JsonAst = ast implicit def implicitParser: Parser[String, JsonAst] = parser @@ -98,76 +123,94 @@ abstract class JsonTests(ast: JsonAst, parser: Parser[String, JsonAst]) extends "self": 0 }""" - val `Extract Int` = test { - source1.int.as[Int] - } returns 42 - val `Extract value called "self"` = test { - source1.self.as[Int] - } returns 0 - - val `Extract Option[Int]` = test { - source1.int.as[Option[Int]] - } returns Some(42) - - val `Extract Option[Int], wrong type` = test { - source1.string.as[Option[Int]] - } returns None - - val `Extract String` = test { - source1.string.as[String] - } returns "Hello" - - val `Extract Double` = test { - source1.double.as[Double] - } returns 3.14159 - - val `Extract Boolean` = test { - source1.boolean.as[Boolean] - } returns true - - val `Extract List[Int]` = test { - source1.list.as[List[Int]] - } returns List(1, 2, 3) - - val `Extract Vector[Int]` = test { - source1.list.as[Vector[Int]] - } returns Vector(1, 2, 3) - - val `Extract case class` = test { - source1.foo.as[Foo] - } returns Foo("test", 1) - - val `Extract case class with missing optional value` = test { - source1.baz.as[Baz] - } returns Baz("test", None) - - val `Extract case class with missing tried value` = test { - source1.baz.as[Baz2] - } returns Baz2("test", util.Failure(MissingValueException())) - - val `Extract case class with present optional value` = test { - source1.baz2.as[Baz] - } returns Baz("test", Some(7)) - - val `Extract case class with present tried value` = test { - source1.baz2.as[Baz2] - } returns Baz2("test", util.Success(7)) - - val `Extract nested case class` = test { - source1.bar.as[Bar] - } returns Bar(Foo("test2", 2), 2.7) - - val `Extract deeply-nested case class` = test { - json"""{ "a": { "b": { "c": { "d": { "e": { "f": 1 } } } } } }""".as[A] - } returns A(B(C(D(E(F(1)))))) - - val `Extract List element` = test { - source1.list(1).as[Int] - } returns 2 - - val `Extract object element` = test { - source1.bar.foo.alpha.as[String] - } returns "test2" + val `Extract Int` = + test { + source1.int.as[Int] + } returns 42 + val `Extract value called "self"` = + test { + source1.self.as[Int] + } returns 0 + + val `Extract Option[Int]` = + test { + source1.int.as[Option[Int]] + } returns Some(42) + + val `Extract Option[Int], wrong type` = + test { + source1.string.as[Option[Int]] + } returns None + + val `Extract String` = + test { + source1.string.as[String] + } returns "Hello" + + val `Extract Double` = + test { + source1.double.as[Double] + } returns 3.14159 + + val `Extract Boolean` = + test { + source1.boolean.as[Boolean] + } returns true + + val `Extract List[Int]` = + test { + source1.list.as[List[Int]] + } returns List(1, 2, 3) + + val `Extract Vector[Int]` = + test { + source1.list.as[Vector[Int]] + } returns Vector(1, 2, 3) + + val `Extract case class` = + test { + source1.foo.as[Foo] + } returns Foo("test", 1) + + val `Extract case class with missing optional value` = + test { + source1.baz.as[Baz] + } returns Baz("test", None) + + val `Extract case class with missing tried value` = + test { + source1.baz.as[Baz2] + } returns Baz2("test", util.Failure(MissingValueException())) + + val `Extract case class with present optional value` = + test { + source1.baz2.as[Baz] + } returns Baz("test", Some(7)) + + val `Extract case class with present tried value` = + test { + source1.baz2.as[Baz2] + } returns Baz2("test", util.Success(7)) + + val `Extract nested case class` = + test { + source1.bar.as[Bar] + } returns Bar(Foo("test2", 2), 2.7) + + val `Extract deeply-nested case class` = + test { + json"""{ "a": { "b": { "c": { "d": { "e": { "f": 1 } } } } } }""".as[A] + } returns A(B(C(D(E(F(1)))))) + + val `Extract List element` = + test { + source1.list(1).as[Int] + } returns 2 + + val `Extract object element` = + test { + source1.bar.foo.alpha.as[String] + } returns "test2" // For some reason these two tests work fine in the REPL, but not here. /* @@ -178,121 +221,142 @@ abstract class JsonTests(ast: JsonAst, parser: Parser[String, JsonAst]) extends val `Extract missing value with case class default 2` = test { json"""{"alpha": "no"}""".as[HasDefault2] } returns HasDefault2("no", 1) - */ - - val `Extract case class ignoring default value` = test { - json"""{"alpha": "no", "beta": 0}""".as[HasDefault2] - } returns HasDefault2("no", 0) - - val `Check type failure` = test { - source1.string.as[Int] - } throws TypeMismatchException(DataTypes.String, DataTypes.Number) - - val `Check missing value failure` = test { - source1.nothing.as[Int] - } throws MissingValueException() - - val `Match string` = test { - source1 match { - case json""" { "string": $h } """ => h.as[String] - } - } returns "Hello" - - val `Match inner JSON` = test { - source1 match { - case json""" { "foo": $foo } """ => foo - } - } returns json"""{ "alpha": "test", "beta": 1 }""" - - val `Match inner string` = test { - source1 match { - case json""" { "foo": { "alpha": $t } } """ => t.as[String] - } - } returns "test" - - val `Filtered match` = test { - source1 match { - case json""" { "int": 42, "foo": { "alpha": $t } } """ => t.as[String] - } - } returns "test" - - val `Inner filtered match` = test { - source1 match { - case json""" { "foo": { "alpha": "test" }, "bar": { "gamma": $g } } """ => g.as[Double] - } - } returns 2.7 - - val `Filtered failed match` = test { - source1 match { - case json""" { "int": 0, "foo": { "alpha": $t } } """ => t.as[String] - } - } throws classOf[MatchError] - - val `Multiple pattern match` = test { - json"""{ "foo": "bar" }""" match { - case json"""{ "bar": "foo" }""" => 0 - case json"""{ "foo": "baz" }""" => 1 - case json"""{ "foo": "bar" }""" => 2 - } - } returns 2 - - val `Empty object doesn't match` = test { - json"""{ "foo": "bar" }""" match { - case json"""{ "foo": {} }""" => 0 - } - } throws classOf[MatchError] - - val `Serialize string` = test { - Json("Hello World!").toString - } returns """"Hello World!"""" - - val `Serialize int` = test { - Json(1648).toString - } returns "1648" - - val `Serialize array` = test { - Json(List(1, 2, 3)).toString - } returns "[1,2,3]" - - val `Serialize object` = test { - import formatters.humanReadable._ - Json.format(json"""{"baz":"quux","foo":"bar"}""") - } returns """{ - | "baz": "quux", - | "foo": "bar" - |}""".stripMargin - - val `Empty object serialization` = test { - import formatters.humanReadable._ - Json.format(json"{}") - } returns "{}" - - val `Empty array serialization` = test { - import formatters.humanReadable._ - Json.format(json"[]") - } returns "[]" + */ + + val `Extract case class ignoring default value` = + test { + json"""{"alpha": "no", "beta": 0}""".as[HasDefault2] + } returns HasDefault2("no", 0) + + val `Check type failure` = + test { + source1.string.as[Int] + } throws TypeMismatchException(DataTypes.String, DataTypes.Number) + + val `Check missing value failure` = + test { + source1.nothing.as[Int] + } throws MissingValueException() + + val `Match string` = + test { + source1 match { + case json""" { "string": $h } """ => h.as[String] + } + } returns "Hello" + + val `Match inner JSON` = + test { + source1 match { + case json""" { "foo": $foo } """ => foo + } + } returns json"""{ "alpha": "test", "beta": 1 }""" + + val `Match inner string` = + test { + source1 match { + case json""" { "foo": { "alpha": $t } } """ => t.as[String] + } + } returns "test" + + val `Filtered match` = + test { + source1 match { + case json""" { "int": 42, "foo": { "alpha": $t } } """ => t.as[String] + } + } returns "test" + + val `Inner filtered match` = + test { + source1 match { + case json""" { "foo": { "alpha": "test" }, "bar": { "gamma": $g } } """ => + g.as[Double] + } + } returns 2.7 + + val `Filtered failed match` = + test { + source1 match { + case json""" { "int": 0, "foo": { "alpha": $t } } """ => t.as[String] + } + } throws classOf[MatchError] + + val `Multiple pattern match` = + test { + json"""{ "foo": "bar" }""" match { + case json"""{ "bar": "foo" }""" => 0 + case json"""{ "foo": "baz" }""" => 1 + case json"""{ "foo": "bar" }""" => 2 + } + } returns 2 + + val `Empty object doesn't match` = + test { + json"""{ "foo": "bar" }""" match { + case json"""{ "foo": {} }""" => 0 + } + } throws classOf[MatchError] + + val `Serialize string` = + test { + Json("Hello World!").toString + } returns """"Hello World!"""" + + val `Serialize int` = + test { + Json(1648).toString + } returns "1648" + + val `Serialize array` = + test { + Json(List(1, 2, 3)).toString + } returns "[1,2,3]" + + val `Serialize object` = + test { + import formatters.humanReadable._ + Json.format(json"""{"baz":"quux","foo":"bar"}""") + } returns """{ + | "baz": "quux", + | "foo": "bar" + |}""".stripMargin + + val `Empty object serialization` = + test { + import formatters.humanReadable._ + Json.format(json"{}") + } returns "{}" + + val `Empty array serialization` = + test { + import formatters.humanReadable._ + Json.format(json"[]") + } returns "[]" // As reported by Jim Newsham - val `Extracting Option should not throw exception` = test { - val j = json"""{"foo":"bar"}""" - j.as[Option[String]] - } returns None + val `Extracting Option should not throw exception` = + test { + val j = json"""{"foo":"bar"}""" + j.as[Option[String]] + } returns None // Reported by @ajrnz - val `Tabs should be escaped when serializing strings` = test { - Json("\t").toString - } returns """"\t"""" - + val `Tabs should be escaped when serializing strings` = + test { + Json("\t").toString + } returns """"\t"""" } -abstract class MutableJsonTests(ast: JsonBufferAst, parser: Parser[String, JsonBufferAst]) extends TestSuite { - +abstract class MutableJsonTests( + ast: JsonBufferAst, parser: Parser[String, JsonBufferAst]) + extends TestSuite { + implicit def implicitAst: JsonBufferAst = ast implicit def implicitParser: Parser[String, JsonBufferAst] = parser case class Foo(alpha: String, beta: Int) case class Bar(foo: Foo, gamma: Double) - + val mutableSource = jsonBuffer"""{ "string": "Hello", "int": 42, @@ -306,70 +370,81 @@ abstract class MutableJsonTests(ast: JsonBufferAst, parser: Parser[String, JsonB "self": 0 }""" - val `Mutable extract Int` = test { - mutableSource.int.as[Int] - } returns 42 - + val `Mutable extract Int` = + test { + mutableSource.int.as[Int] + } returns 42 + val source2 = JsonBuffer.parse("""{ "string": "Hello", "int": 42 }""") - val `Mutable get String` = test { - source2.string.as[String] - } returns "Hello" + val `Mutable get String` = + test { + source2.string.as[String] + } returns "Hello" //val `Mutable get optional String` = test { // source2.string.as[Option[String]] //} returns Some("Hello") - val `Mutable get Int` = test { - source2.int.as[Int] - } returns 42 - - val `Mutable change String` = test { - source2.string = "World" - source2.string.as[String] - } returns "World" - - val `Mutable add String` = test { - source2.inner.newString = "Hello" - source2.inner.newString.as[String] - } returns "Hello" - - val `Mutable add Json` = test { - val jb = JsonBuffer.empty - jb.foo = json"""{ "foo": "bar" }""" - } returns jsonBuffer"""{ "foo": { "foo": "bar" } }""" - - val `Mutable add case class` = test { - source2.foo = Foo("string", -1) - source2.foo.as[Foo] - } returns Foo("string", -1) - - val `Deep insertion of integer` = test { - source2.alpha.beta.gamma.delta = 1 - source2.alpha.beta.gamma.delta.as[Int] - } returns 1 - - val `Array autopadding` = test { - source2.autopad(4) = 1 - source2.autopad(4).as[Int] - } returns 1 - - val `Deep array insertion of integer` = test { - source2.array(1)(2)(3)(4) = 1 - source2.array(1)(2)(3)(4).as[Int] - } returns 1 - - val `Deep mixed insertion of string` = test { - source2.mixed(4).foo.bar(2).baz = "Mixed" - source2.mixed(4).foo.bar(2).baz.as[String] - } returns "Mixed" - - val `Mutable add array String` = test { - source2.inner.newArray += "Hello" - source2.inner.newArray(0).as[String] - } returns "Hello" - + val `Mutable get Int` = + test { + source2.int.as[Int] + } returns 42 + + val `Mutable change String` = + test { + source2.string = "World" + source2.string.as[String] + } returns "World" + + val `Mutable add String` = + test { + source2.inner.newString = "Hello" + source2.inner.newString.as[String] + } returns "Hello" + + val `Mutable add Json` = + test { + val jb = JsonBuffer.empty + jb.foo = json"""{ "foo": "bar" }""" + } returns jsonBuffer"""{ "foo": { "foo": "bar" } }""" + + val `Mutable add case class` = + test { + source2.foo = Foo("string", -1) + source2.foo.as[Foo] + } returns Foo("string", -1) + + val `Deep insertion of integer` = + test { + source2.alpha.beta.gamma.delta = 1 + source2.alpha.beta.gamma.delta.as[Int] + } returns 1 + + val `Array autopadding` = + test { + source2.autopad(4) = 1 + source2.autopad(4).as[Int] + } returns 1 + + val `Deep array insertion of integer` = + test { + source2.array(1)(2)(3)(4) = 1 + source2.array(1)(2)(3)(4).as[Int] + } returns 1 + + val `Deep mixed insertion of string` = + test { + source2.mixed(4).foo.bar(2).baz = "Mixed" + source2.mixed(4).foo.bar(2).baz.as[String] + } returns "Mixed" + + val `Mutable add array String` = + test { + source2.inner.newArray += "Hello" + source2.inner.newArray(0).as[String] + } returns "Hello" } diff --git a/json/shared/src/main/scala/rapture/json/ast.scala b/json/shared/src/main/scala/rapture/json/ast.scala index 0f3e931..828f303 100644 --- a/json/shared/src/main/scala/rapture/json/ast.scala +++ b/json/shared/src/main/scala/rapture/json/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -42,18 +42,18 @@ trait JsonAst extends DataAst { /** Extracts a `BigDecimal` from the parsed JSON. */ def getBigDecimal(number: Any): BigDecimal - + def fromBigDecimal(number: BigDecimal): Any /** Tests if the element represents a `Boolean` */ def isBoolean(any: Any): Boolean - + /** Tests if the element represents a `String` */ def isString(any: Any): Boolean - + /** Tests if the element represents a number */ def isNumber(any: Any): Boolean - + /** Tests if the element represents a `null` */ def isNull(any: Any): Boolean @@ -62,26 +62,28 @@ trait JsonAst extends DataAst { /** Returns the DataType instance for the particular type. */ def getType(any: Any): DataTypes.DataType = - if(isBoolean(any)) DataTypes.Boolean - else if(isString(any)) DataTypes.String - else if(isNumber(any)) DataTypes.Number - else if(isObject(any)) DataTypes.Object - else if(isArray(any)) DataTypes.Array - else if(isNull(any)) DataTypes.Null + if (isBoolean(any)) DataTypes.Boolean + else if (isString(any)) DataTypes.String + else if (isNumber(any)) DataTypes.Number + else if (isObject(any)) DataTypes.Object + else if (isArray(any)) DataTypes.Array + else if (isNull(any)) DataTypes.Null else throw MissingValueException() def convert(v: Any, ast: DataAst): Any = { val oldAst = ast.asInstanceOf[JsonAst] - if(oldAst.isString(v)) fromString(oldAst.getString(v)) - else if(oldAst.isBoolean(v)) fromBoolean(oldAst.getBoolean(v)) - else if(oldAst.isNumber(v)) fromDouble(oldAst.getDouble(v)) - else if(oldAst.isArray(v)) fromArray(oldAst.getArray(v).map(convert(_, oldAst))) - else if(oldAst.isObject(v)) fromObject(oldAst.getObject(v).mapValues(convert(_, oldAst))) + if (oldAst.isString(v)) fromString(oldAst.getString(v)) + else if (oldAst.isBoolean(v)) fromBoolean(oldAst.getBoolean(v)) + else if (oldAst.isNumber(v)) fromDouble(oldAst.getDouble(v)) + else if (oldAst.isArray(v)) + fromArray(oldAst.getArray(v).map(convert(_, oldAst))) + else if (oldAst.isObject(v)) + fromObject(oldAst.getObject(v).mapValues(convert(_, oldAst))) else nullValue } - protected def typeTest(pf: PartialFunction[Any, Unit])(v: Any) = pf.isDefinedAt(v) + protected def typeTest(pf: PartialFunction[Any, Unit])(v: Any) = + pf.isDefinedAt(v) } trait JsonBufferAst extends JsonAst with MutableDataAst - diff --git a/json/shared/src/main/scala/rapture/json/context.scala b/json/shared/src/main/scala/rapture/json/context.scala index 229dde3..8b46339 100644 --- a/json/shared/src/main/scala/rapture/json/context.scala +++ b/json/shared/src/main/scala/rapture/json/context.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -24,45 +24,56 @@ import rapture.data._ import language.experimental.macros private[json] object JsonDataMacros extends DataContextMacros[Json, JsonAst] { - - def companion(c: BlackboxContext): c.Expr[DataCompanion[Json, JsonAst]] = c.universe.reify(Json) - - def parseSource(s: List[String], stringsUsed: List[Boolean]) = try { - JsonValidator.validate(s, stringsUsed) - None - } catch { - case JsonValidator.ValidationException(strNo, pos, expected, found) => - val f = if(found == '\u0000') "end of input" else s"'$found'" - Some((strNo, pos, s"failed to parse Json literal: expected $expected, but found $f")) - case JsonValidator.DuplicateKeyException(strNo, pos, key) => - Some((strNo, pos, s"""duplicate key found in Json literal: "$key"""")) - case JsonValidator.NonStringKeyException(strNo, pos) => - Some((strNo, pos, s"""only Strings may be used as JSON object keys""")) - } - - override def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Json]]*) - (parser: c.Expr[Parser[String, JsonAst]]): c.Expr[Json] = - super.contextMacro(c)(exprs: _*)(parser) + def companion(c: BlackboxContext): c.Expr[DataCompanion[Json, JsonAst]] = + c.universe.reify(Json) + + def parseSource(s: List[String], stringsUsed: List[Boolean]) = + try { + JsonValidator.validate(s, stringsUsed) + None + } catch { + case JsonValidator.ValidationException(strNo, pos, expected, found) => + val f = if (found == '\u0000') "end of input" else s"'$found'" + Some( + (strNo, + pos, + s"failed to parse Json literal: expected $expected, but found $f")) + case JsonValidator.DuplicateKeyException(strNo, pos, key) => + Some((strNo, pos, s"""duplicate key found in Json literal: "$key"""")) + case JsonValidator.NonStringKeyException(strNo, pos) => + Some((strNo, pos, s"""only Strings may be used as JSON object keys""")) + } + + override def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[Json]]*)( + parser: c.Expr[Parser[String, JsonAst]]): c.Expr[Json] = + super.contextMacro(c)(exprs: _*)(parser) } -private[json] object JsonBufferDataMacros extends DataContextMacros[JsonBuffer, JsonBufferAst] { - - def companion(c: BlackboxContext): c.Expr[DataCompanion[JsonBuffer, JsonBufferAst]] = +private[json] object JsonBufferDataMacros + extends DataContextMacros[JsonBuffer, JsonBufferAst] { + + def companion( + c: BlackboxContext): c.Expr[DataCompanion[JsonBuffer, JsonBufferAst]] = c.universe.reify(JsonBuffer) - def parseSource(s: List[String], stringsUsed: List[Boolean]) = try { - JsonValidator.validate(s, stringsUsed) - None - } catch { - case JsonValidator.ValidationException(strNo, pos, expected, found) => - val f = if(found == '\u0000') "end of input" else s"'$found'" - Some((strNo, pos, - s"Failed to parse JsonBuffer literal: Expected $expected, but found $f.")) - } - - override def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[JsonBuffer]]*) - (parser: c.Expr[Parser[String, JsonBufferAst]]): c.Expr[JsonBuffer] = + def parseSource(s: List[String], stringsUsed: List[Boolean]) = + try { + JsonValidator.validate(s, stringsUsed) + None + } catch { + case JsonValidator.ValidationException(strNo, pos, expected, found) => + val f = if (found == '\u0000') "end of input" else s"'$found'" + Some( + (strNo, + pos, + s"Failed to parse JsonBuffer literal: Expected $expected, but found $f.")) + } + + override def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[JsonBuffer]]*)( + parser: c.Expr[Parser[String, JsonBufferAst]]): c.Expr[JsonBuffer] = super.contextMacro(c)(exprs: _*)(parser) } @@ -71,17 +82,16 @@ private[json] object JsonBufferDataMacros extends DataContextMacros[JsonBuffer, * from a JSON string. */ private[json] class JsonStrings(sc: StringContext) { class JsonContext() extends DataContext(Json, sc) { - def apply(exprs: ForcedConversion[Json]*)(implicit parser: Parser[String, JsonAst]): Json = - macro JsonDataMacros.contextMacro + def apply(exprs: ForcedConversion[Json]*)( + implicit parser: Parser[String, JsonAst]): Json = macro JsonDataMacros.contextMacro } val json = new JsonContext() } private[json] class JsonBufferStrings(sc: StringContext) { class JsonBufferContext() extends DataContext(JsonBuffer, sc) { - def apply(exprs: ForcedConversion[JsonBuffer]*)(implicit parser: Parser[String, - JsonBufferAst]): JsonBuffer = - macro JsonBufferDataMacros.contextMacro + def apply(exprs: ForcedConversion[JsonBuffer]*)( + implicit parser: Parser[String, JsonBufferAst]): JsonBuffer = macro JsonBufferDataMacros.contextMacro } val jsonBuffer = new JsonBufferContext() } diff --git a/json/shared/src/main/scala/rapture/json/extractors.scala b/json/shared/src/main/scala/rapture/json/extractors.scala index d4b6948..f82cd83 100644 --- a/json/shared/src/main/scala/rapture/json/extractors.scala +++ b/json/shared/src/main/scala/rapture/json/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -24,85 +24,129 @@ import scala.util._ import language.higherKinds -private[json] case class JsonCastExtractor[T](ast: JsonAst, dataType: DataTypes.DataType) +private[json] case class JsonCastExtractor[T]( + ast: JsonAst, dataType: DataTypes.DataType) private[json] trait Extractors extends Extractors_1 { - implicit def optionExtractor[T](implicit ext: Extractor[T, Json]): Extractor[Option[T], Json] { type Throws = - Nothing } = GeneralExtractors.optionExtractor[Json, T] + implicit def optionExtractor[T](implicit ext: Extractor[T, Json] + ): Extractor[Option[T], Json] { type Throws = Nothing } = + GeneralExtractors.optionExtractor[Json, T] - implicit def tryExtractor[T](implicit ext: Extractor[T, Json]): Extractor[Try[T], Json] { type Throws = - Nothing } = GeneralExtractors.tryExtractor[Json, T] + implicit def tryExtractor[T](implicit ext: Extractor[T, Json] + ): Extractor[Try[T], Json] { type Throws = Nothing } = + GeneralExtractors.tryExtractor[Json, T] + + implicit def genSeqExtractor[T, Coll[_]]( + implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], + ext: Extractor[T, Json] + ): Extractor[Coll[T], Json] { type Throws = ext.Throws } = { - implicit def genSeqExtractor[T, Coll[_]](implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], - ext: Extractor[T, Json]): Extractor[Coll[T], Json] { type Throws = ext.Throws } = { - GeneralExtractors.genSeqExtractor[T, Coll, Json] - } + } - implicit def mapExtractor[K, V](implicit ext: Extractor[V, Json], ext2: StringParser[K]): Extractor[Map[K, V], Json] = + implicit def mapExtractor[K, V]( + implicit ext: Extractor[V, Json], + ext2: StringParser[K]): Extractor[Map[K, V], Json] = GeneralExtractors.mapExtractor[K, V, Json] - } private[json] trait Extractors_1 extends Extractors_2 { - implicit def jsonExtractor(implicit ast: JsonAst): Extractor[Json, Json] { type Throws = DataGetException } = + implicit def jsonExtractor(implicit ast: JsonAst + ): Extractor[Json, Json] { type Throws = DataGetException } = new Extractor[Json, Json] { type Throws = DataGetException - def extract(any: Json, dataAst: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Json, DataGetException] = - mode.wrap(mode.catching[DataGetException, Json](any.$wrap(any.$normalize))) - } - - implicit val stringExtractor: Extractor[String, Json] { type Throws = DataGetException } = - new Extractor[String, Json] { - type Throws = DataGetException - def extract(any: Json, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[String, DataGetException] = - mode.wrap(mode.catching[DataGetException, String](any.$ast.getString(any.$normalize))) + def extract(any: Json, + dataAst: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[Json, DataGetException] = + mode.wrap( + mode.catching[DataGetException, Json](any.$wrap(any.$normalize))) } - implicit val doubleExtractor: Extractor[Double, Json] { type Throws = DataGetException } = - new Extractor[Double, Json] { - type Throws = DataGetException - def extract(any: Json, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Double, Throws] = - mode.wrap(mode.catching[DataGetException, Double](any.$ast.getDouble(any.$normalize))) - } + implicit val stringExtractor: Extractor[String, Json] { + type Throws = DataGetException + } = new Extractor[String, Json] { + type Throws = DataGetException + def extract(any: Json, + ast: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[String, DataGetException] = + mode.wrap(mode.catching[DataGetException, String]( + any.$ast.getString(any.$normalize))) + } - implicit val intExtractor: Extractor[Int, Json] { type Throws = DataGetException } = - doubleExtractor.smap(_.toInt) + implicit val doubleExtractor: Extractor[Double, Json] { + type Throws = DataGetException + } = new Extractor[Double, Json] { + type Throws = DataGetException + def extract( + any: Json, + ast: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[Double, Throws] = + mode.wrap(mode.catching[DataGetException, Double]( + any.$ast.getDouble(any.$normalize))) + } - implicit val booleanExtractor: Extractor[Boolean, Json] { type Throws = DataGetException } = - new Extractor[Boolean, Json] { - type Throws = DataGetException - def extract(any: Json, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Boolean, DataGetException] = - mode.wrap(any.$ast.getBoolean(any.$normalize)) - } - - implicit val bigDecimalExtractor: Extractor[BigDecimal, Json] { type Throws = DataGetException } = - new Extractor[BigDecimal, Json] { - type Throws = DataGetException - def extract(any: Json, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[BigDecimal, DataGetException] = - mode.wrap(any.$ast.getBigDecimal(any.$normalize)) - } - - implicit val bigIntExtractor: Extractor[BigInt, Json] { type Throws = DataGetException } = - bigDecimalExtractor.smap(_.toBigInt) + implicit val intExtractor: Extractor[Int, Json] { + type Throws = DataGetException + } = doubleExtractor.smap(_.toInt) + + implicit val booleanExtractor: Extractor[Boolean, Json] { + type Throws = DataGetException + } = new Extractor[Boolean, Json] { + type Throws = DataGetException + def extract(any: Json, + ast: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[Boolean, DataGetException] = + mode.wrap(any.$ast.getBoolean(any.$normalize)) + } + + implicit val bigDecimalExtractor: Extractor[BigDecimal, Json] { + type Throws = DataGetException + } = new Extractor[BigDecimal, Json] { + type Throws = DataGetException + def extract(any: Json, + ast: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[BigDecimal, DataGetException] = + mode.wrap(any.$ast.getBigDecimal(any.$normalize)) + } + + implicit val bigIntExtractor: Extractor[BigInt, Json] { + type Throws = DataGetException + } = bigDecimalExtractor.smap(_.toBigInt) } private[json] trait Extractors_2 { - implicit def jsonBufferExtractor[T](implicit jsonAst: JsonAst, ext: Extractor[T, Json]): - Extractor[T, JsonBuffer] { type Throws = ext.Throws } = new Extractor[T, JsonBuffer] { - type Throws = ext.Throws - def extract(any: JsonBuffer, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, ext.Throws] = - ext.extract(Json.construct(MutableCell(any.$root.value), Vector()), ast, mode) - } - - implicit def jsonBufferToJsonExtractor(implicit ast: JsonBufferAst): Extractor[JsonBuffer, Json] = + implicit def jsonBufferExtractor[T](implicit jsonAst: JsonAst, + ext: Extractor[T, Json] + ): Extractor[T, JsonBuffer] { type Throws = ext.Throws } = + new Extractor[T, JsonBuffer] { + type Throws = ext.Throws + def extract( + any: JsonBuffer, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, ext.Throws] = + ext.extract( + Json.construct(MutableCell(any.$root.value), Vector()), ast, mode) + } + + implicit def jsonBufferToJsonExtractor( + implicit ast: JsonBufferAst): Extractor[JsonBuffer, Json] = new Extractor[JsonBuffer, Json] { type Throws = DataGetException - def extract(any: Json, dataAst: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[JsonBuffer, Throws] = - mode.wrap(JsonBuffer.construct(MutableCell(JsonDataType.jsonSerializer.serialize(any)), Vector())) + def extract( + any: Json, + dataAst: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[JsonBuffer, Throws] = + mode.wrap( + JsonBuffer.construct( + MutableCell(JsonDataType.jsonSerializer.serialize(any)), + Vector())) } - } diff --git a/json/shared/src/main/scala/rapture/json/formatters.scala b/json/shared/src/main/scala/rapture/json/formatters.scala index 00ab672..e56abb3 100644 --- a/json/shared/src/main/scala/rapture/json/formatters.scala +++ b/json/shared/src/main/scala/rapture/json/formatters.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -22,61 +22,75 @@ import rapture.data._ object formatters extends formatters_1 { object compact { - def apply[Ast <: JsonAst]()(implicit ast: Ast): Formatter[Ast] { type Out = String } = + def apply[Ast <: JsonAst]()( + implicit ast: Ast): Formatter[Ast] { type Out = String } = jsonFormatterImplicit[Ast] - implicit def jsonFormatterImplicit[Ast <: JsonAst](implicit ast: Ast, df: DecimalFormat): - Formatter[Ast] { type Out = String } = + implicit def jsonFormatterImplicit[Ast <: JsonAst]( + implicit ast: Ast, + df: DecimalFormat): Formatter[Ast] { type Out = String } = new Formatter[Ast] { type Out = String - def format(json: Any): String = general(json, 0, ast, "", "") + def format(json: Any): String = general(json, 0, ast, "", "") } } } private[json] class formatters_1 { + /** Formats the JSON object for multi-line readability. */ - protected def general[Ast <: JsonAst](json: Any, ln: Int, ast: Ast, pad: String = " ", - brk: String = "\n")(implicit df: DecimalFormat): String = { - val indent = pad*ln + protected def general[Ast <: JsonAst]( + json: Any, ln: Int, ast: Ast, pad: String = " ", brk: String = "\n")( + implicit df: DecimalFormat): String = { + val indent = pad * ln json match { case j => - if(ast.isString(j)) { - "\""+ast.getString(j).replaceAll("\\\\", "\\\\\\\\").replaceAll("\r", "\\\\r").replaceAll("\t", "\\\\t"). - replaceAll("\n", "\\\\n").replaceAll("\"", "\\\\\"")+"\"" - - } else if(ast.isBoolean(j)) { - if(ast.getBoolean(j)) "true" else "false" - } else if(ast.isNumber(j)) { + if (ast.isString(j)) { + "\"" + ast + .getString(j) + .replaceAll("\\\\", "\\\\\\\\") + .replaceAll("\r", "\\\\r") + .replaceAll("\t", "\\\\t") + .replaceAll("\n", "\\\\n") + .replaceAll("\"", "\\\\\"") + "\"" + } else if (ast.isBoolean(j)) { + if (ast.getBoolean(j)) "true" else "false" + } else if (ast.isNumber(j)) { val bd = ast.getBigDecimal(j) - if(bd.isWhole) String(bd.toBigInt) else String(df.format(bd)) - } else if(ast.isArray(j)) { + if (bd.isWhole) String(bd.toBigInt) else String(df.format(bd)) + } else if (ast.isArray(j)) { val arr = ast.getArray(j) - if(arr.isEmpty) "[]" else List("[", arr map { v => - s"${indent}${pad}${general(v, ln + 1, ast, pad, brk)}" - } mkString s",${brk}", s"${indent}]") mkString brk - } else if(ast.isObject(j)) { + if (arr.isEmpty) "[]" + else + List("[", arr map { v => + s"${indent}${pad}${general(v, ln + 1, ast, pad, brk)}" + } mkString s",${brk}", s"${indent}]") mkString brk + } else if (ast.isObject(j)) { val keys = ast.getKeys(j) - if(keys.isEmpty) "{}" else List("{", keys map { k => - val inner = ast.dereferenceObject(j, k) - s"""${indent}${pad}"${k}":${pad}${general(inner, ln + 1, ast, pad, brk)}""" - } mkString s",${brk}", s"${indent}}") mkString brk - } else if(ast.isNull(j)) "null" - else if(j == DataCompanion.Empty) "empty" + if (keys.isEmpty) "{}" + else + List("{", keys map { k => + val inner = ast.dereferenceObject(j, k) + s"""${indent}${pad}"${k}":${pad}${general( + inner, ln + 1, ast, pad, brk)}""" + } mkString s",${brk}", s"${indent}}") mkString brk + } else if (ast.isNull(j)) "null" + else if (j == DataCompanion.Empty) "empty" else "undefined" } } - + object humanReadable { - def apply[Ast <: JsonAst]()(implicit ast: Ast): Formatter[Ast] { type Out = String } = + def apply[Ast <: JsonAst]()( + implicit ast: Ast): Formatter[Ast] { type Out = String } = jsonFormatterImplicit[Ast] - implicit def jsonFormatterImplicit[Ast <: JsonAst](implicit ast: Ast, df: DecimalFormat): - Formatter[Ast] { type Out = String } = + implicit def jsonFormatterImplicit[Ast <: JsonAst]( + implicit ast: Ast, + df: DecimalFormat): Formatter[Ast] { type Out = String } = new Formatter[Ast] { type Out = String - def format(json: Any): String = general(json, 0, ast, " ", "\n") + def format(json: Any): String = general(json, 0, ast, " ", "\n") } } - } diff --git a/json/shared/src/main/scala/rapture/json/json.scala b/json/shared/src/main/scala/rapture/json/json.scala index 6117995..aab959b 100644 --- a/json/shared/src/main/scala/rapture/json/json.scala +++ b/json/shared/src/main/scala/rapture/json/json.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -23,11 +23,13 @@ import rapture.data._ import language.experimental.macros private[json] trait Json_2 { - implicit def jsonExtractorMacro[T <: Product, Th]: Extractor[T, Json] { type Throws = Th } = - macro JsonMacros.jsonExtractorMacro[T, Th] + implicit def jsonExtractorMacro[T <: Product, Th]: Extractor[T, Json] { + type Throws = Th + } = macro JsonMacros.jsonExtractorMacro[T, Th] - implicit def jsonSerializerMacro[T <: Product](implicit ast: JsonAst): Serializer[T, Json] = - macro JsonMacros.jsonSerializerMacro[T] + implicit def jsonSerializerMacro[T <: Product]( + implicit ast: JsonAst): Serializer[T, Json] = macro JsonMacros + .jsonSerializerMacro[T] } private[json] trait Json_1 extends Json_2 { @@ -40,126 +42,155 @@ private[json] class DynamicWorkaround(json: Json) { trait `Json.parse` extends MethodConstraint -private[json] trait JsonDataCompanion[+Type <: JsonDataType[Type, AstType], - AstType <: JsonAst] extends DataCompanion[Type, AstType] { +private[json] trait JsonDataCompanion[ + +Type <: JsonDataType[Type, AstType], AstType <: JsonAst] + extends DataCompanion[Type, AstType] { type ParseMethodConstraint = `Json.parse` /** Formats the JSON object for multi-line readability. */ - private[json] def doFormat(json: Any, ln: Int, ast: AstType, pad: String = " ", - brk: String = "\n"): String = { - val indent = pad*ln + private[json] def doFormat(json: Any, + ln: Int, + ast: AstType, + pad: String = " ", + brk: String = "\n"): String = { + val indent = pad * ln json match { case j => - if(ast.isString(j)) { - "\""+ast.getString(j).replaceAll("\\\\", "\\\\\\\\").replaceAll("\r", - "\\\\r").replaceAll("\n", "\\\\n").replaceAll("\"", "\\\\\"")+"\"" - } else if(ast.isBoolean(j)) { - if(ast.getBoolean(j)) "true" else "false" - } else if(ast.isNumber(j)) { + if (ast.isString(j)) { + "\"" + ast + .getString(j) + .replaceAll("\\\\", "\\\\\\\\") + .replaceAll("\r", "\\\\r") + .replaceAll("\n", "\\\\n") + .replaceAll("\"", "\\\\\"") + "\"" + } else if (ast.isBoolean(j)) { + if (ast.getBoolean(j)) "true" else "false" + } else if (ast.isNumber(j)) { val n = ast.getDouble(j) - if(n == n.floor) n.toInt.toString else String(n) - } else if(ast.isArray(j)) { + if (n == n.floor) n.toInt.toString else String(n) + } else if (ast.isArray(j)) { val arr = ast.getArray(j) - if(arr.isEmpty) "[]" else List("[", arr map { v => - s"${indent}${pad}${doFormat(v, ln + 1, ast, pad, brk)}" - } mkString s",${brk}", s"${indent}]") mkString brk - } else if(ast.isObject(j)) { + if (arr.isEmpty) "[]" + else + List("[", arr map { v => + s"${indent}${pad}${doFormat(v, ln + 1, ast, pad, brk)}" + } mkString s",${brk}", s"${indent}]") mkString brk + } else if (ast.isObject(j)) { val keys = ast.getKeys(j) - if(keys.isEmpty) "{}" else List("{", keys map { k => - val inner = ast.dereferenceObject(j, k) - s"""${indent}${pad}"${k}":${pad}${doFormat(inner, ln + 1, ast, pad, brk)}""" - } mkString s",${brk}", s"${indent}}") mkString brk - } else if(ast.isNull(j)) "null" - else if(j == DataCompanion.Empty) "empty" + if (keys.isEmpty) "{}" + else + List("{", keys map { k => + val inner = ast.dereferenceObject(j, k) + s"""${indent}${pad}"${k}":${pad}${doFormat( + inner, ln + 1, ast, pad, brk)}""" + } mkString s",${brk}", s"${indent}}") mkString brk + } else if (ast.isNull(j)) "null" + else if (j == DataCompanion.Empty) "empty" else "undefined" } } } - private[json] object JsonDataType extends Extractors with Serializers -private[json] trait JsonDataType[+T <: JsonDataType[T, AstType], AstType <: JsonAst] +private[json] trait JsonDataType[ + +T <: JsonDataType[T, AstType], AstType <: JsonAst] extends DataType[T, AstType] object JsonBuffer extends JsonDataCompanion[JsonBuffer, JsonBufferAst] { - - def construct(any: MutableCell, path: Vector[Either[Int, String]])(implicit ast: - JsonBufferAst): JsonBuffer = new JsonBuffer(any, path) + + def construct(any: MutableCell, path: Vector[Either[Int, String]])( + implicit ast: JsonBufferAst): JsonBuffer = new JsonBuffer(any, path) } /** Companion object to the `Json` type, providing factory and extractor methods, and a JSON * pretty printer. */ object Json extends JsonDataCompanion[Json, JsonAst] with Json_1 { - - def construct(any: MutableCell, path: Vector[Either[Int, String]])(implicit ast: - JsonAst): Json = new Json(any, path) + + def construct(any: MutableCell, path: Vector[Either[Int, String]])( + implicit ast: JsonAst): Json = new Json(any, path) def ast(json: Json): JsonAst = json.$ast - def extractor[T](implicit ext: Extractor[T, Json]): Extractor[T, Json] { type Throws = ext.Throws } = ext + def extractor[T](implicit ext: Extractor[T, Json] + ): Extractor[T, Json] { type Throws = ext.Throws } = ext def serializer[T](implicit ser: Serializer[T, Json]) = ser - implicit def jsonCastExtractor[T: JsonCastExtractor](implicit ast: JsonAst): - Extractor[T, JsonDataType[_, _ <: JsonAst]] = + implicit def jsonCastExtractor[T : JsonCastExtractor]( + implicit ast: JsonAst): Extractor[T, JsonDataType[_, _ <: JsonAst]] = new Extractor[T, JsonDataType[_, _ <: JsonAst]] { type Throws = DataGetException - def extract(value: JsonDataType[_, _ <: JsonAst], ast2: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DataGetException] = + def extract( + value: JsonDataType[_, _ <: JsonAst], + ast2: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DataGetException] = mode.wrap(ast2 match { case ast2: JsonAst => val norm = mode.catching[DataGetException, Any](value.$normalize) try { - if(ast == ast2) norm.asInstanceOf[T] - else JsonDataType.jsonSerializer.serialize(Json.construct(MutableCell(norm), - Vector())(ast2)).asInstanceOf[T] - } catch { case e: ClassCastException => - mode.exception[T, DataGetException](TypeMismatchException(ast.getType(norm), - implicitly[JsonCastExtractor[T]].dataType)) + if (ast == ast2) norm.asInstanceOf[T] + else + JsonDataType.jsonSerializer + .serialize(Json.construct(MutableCell(norm), Vector())(ast2)) + .asInstanceOf[T] + } catch { + case e: ClassCastException => + mode.exception[T, DataGetException](TypeMismatchException( + ast.getType(norm), + implicitly[JsonCastExtractor[T]].dataType)) } case _ => ??? }) } - } /** Represents some parsed JSON. */ -class Json(val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())(implicit - val $ast: JsonAst) extends JsonDataType[Json, JsonAst] with DynamicData[Json, JsonAst] { - +class Json( + val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())( + implicit val $ast: JsonAst) + extends JsonDataType[Json, JsonAst] with DynamicData[Json, JsonAst] { + def $wrap(any: Any, path: Vector[Either[Int, String]]): Json = new Json(MutableCell(any), path) - + def $deref(path: Vector[Either[Int, String]]): Json = new Json($root, path) def $extract(sp: Vector[Either[Int, String]]): Json = - if(sp.isEmpty) this else sp match { - case Left(i) +: tail => apply(i).$extract(tail) - case Right(e) +: tail => selectDynamic(e).$extract(tail) - } - + if (sp.isEmpty) this + else + sp match { + case Left(i) +: tail => apply(i).$extract(tail) + case Right(e) +: tail => selectDynamic(e).$extract(tail) + } + override def toString = try Json.format(this)(formatters.compact()($ast)) catch { case e: Exception => "undefined" } } -class JsonBuffer(val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector()) - (implicit val $ast: JsonBufferAst) extends - JsonDataType[JsonBuffer, JsonBufferAst] with - MutableDataType[JsonBuffer, JsonBufferAst] with DynamicData[JsonBuffer, JsonBufferAst] { +class JsonBuffer( + val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())( + implicit val $ast: JsonBufferAst) + extends JsonDataType[JsonBuffer, JsonBufferAst] + with MutableDataType[JsonBuffer, JsonBufferAst] + with DynamicData[JsonBuffer, JsonBufferAst] { def $wrap(any: Any, path: Vector[Either[Int, String]]): JsonBuffer = new JsonBuffer(MutableCell(any), path) - - def $deref(path: Vector[Either[Int, String]]): JsonBuffer = new JsonBuffer($root, path) - + + def $deref(path: Vector[Either[Int, String]]): JsonBuffer = + new JsonBuffer($root, path) + def $extract(sp: Vector[Either[Int, String]]): JsonBuffer = - if(sp.isEmpty) this else sp match { - case Left(i) +: tail => apply(i).$extract(tail) - case Right(e) +: tail => selectDynamic(e).$extract(tail) - } - + if (sp.isEmpty) this + else + sp match { + case Left(i) +: tail => apply(i).$extract(tail) + case Right(e) +: tail => selectDynamic(e).$extract(tail) + } + override def toString = try JsonBuffer.format(this)(formatters.compact()($ast)) catch { case e: Exception => "undefined" diff --git a/json/shared/src/main/scala/rapture/json/macros.scala b/json/shared/src/main/scala/rapture/json/macros.scala index bb3d0fa..51b66a8 100644 --- a/json/shared/src/main/scala/rapture/json/macros.scala +++ b/json/shared/src/main/scala/rapture/json/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -21,17 +21,18 @@ import rapture.base._ import rapture.data._ private[json] object JsonMacros { - def jsonExtractorMacro[T: c.WeakTypeTag, Th](c: WhiteboxContext): c.Expr[Extractor[T, Json] { type Throws = Th }] = + def jsonExtractorMacro[T : c.WeakTypeTag, Th]( + c: WhiteboxContext): c.Expr[Extractor[T, Json] { type Throws = Th }] = Macros.extractorMacro[T, Json, Th](c) - + //def jsonBufferExtractorMacro[T: c.WeakTypeTag](c: Context) = // Macros.extractorMacro2[T, JsonBuffer](c) - - def jsonSerializerMacro[T: c.WeakTypeTag](c: WhiteboxContext)(ast: c.Expr[JsonAst]): - c.Expr[Serializer[T, Json]] = + + def jsonSerializerMacro[T : c.WeakTypeTag](c: WhiteboxContext)( + ast: c.Expr[JsonAst]): c.Expr[Serializer[T, Json]] = Macros.serializerMacro[T, Json](c)(ast) - - def jsonBufferSerializerMacro[T: c.WeakTypeTag](c: WhiteboxContext)(ast: c.Expr[JsonBufferAst]): - c.Expr[Serializer[T, JsonBuffer]] = + + def jsonBufferSerializerMacro[T : c.WeakTypeTag](c: WhiteboxContext)( + ast: c.Expr[JsonBufferAst]): c.Expr[Serializer[T, JsonBuffer]] = Macros.serializerMacro[T, JsonBuffer](c)(ast) } diff --git a/json/shared/src/main/scala/rapture/json/package.scala b/json/shared/src/main/scala/rapture/json/package.scala index 8225e96..476201b 100644 --- a/json/shared/src/main/scala/rapture/json/package.scala +++ b/json/shared/src/main/scala/rapture/json/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -33,12 +33,14 @@ object `package` { val TypeMismatchException = rapture.data.TypeMismatchException val MissingValueException = rapture.data.MissingValueException - implicit def jsonStringContext(sc: StringContext)(implicit parser: Parser[String, JsonAst]) = + implicit def jsonStringContext(sc: StringContext)( + implicit parser: Parser[String, JsonAst]) = new JsonStrings(sc) - - implicit def jsonBufferStringContext(sc: StringContext) - (implicit parser: Parser[String, JsonBufferAst]) = + + implicit def jsonBufferStringContext(sc: StringContext)( + implicit parser: Parser[String, JsonBufferAst]) = new JsonBufferStrings(sc) - implicit class JsonOperations(json: Json) extends DataType.DataClassOperations[Json, JsonAst](json) + implicit class JsonOperations(json: Json) + extends DataType.DataClassOperations[Json, JsonAst](json) } diff --git a/json/shared/src/main/scala/rapture/json/serializers.scala b/json/shared/src/main/scala/rapture/json/serializers.scala index ee3c93d..2d63811 100644 --- a/json/shared/src/main/scala/rapture/json/serializers.scala +++ b/json/shared/src/main/scala/rapture/json/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json @@ -27,70 +27,91 @@ private[json] case class DirectJsonSerializer[T](ast: JsonAst) private[json] trait Serializers { case class BasicJsonSerializer[T](serialization: T => Any) - extends Serializer[T, Json] { def serialize(t: T): Any = serialization(t) } - - implicit def jsonBufferSerializer[T](implicit ser: Serializer[T, Json]): - Serializer[T, JsonBuffer] = - new Serializer[T, JsonBuffer] { def serialize(t: T): Any = ser.serialize(t) } + extends Serializer[T, Json] { + def serialize(t: T): Any = serialization(t) + } + + implicit def jsonBufferSerializer[T]( + implicit ser: Serializer[T, Json]): Serializer[T, JsonBuffer] = + new Serializer[T, JsonBuffer] { + def serialize(t: T): Any = ser.serialize(t) + } implicit def intSerializer(implicit ast: JsonAst): Serializer[Int, Json] = BasicJsonSerializer(ast fromDouble _.toDouble) - implicit def booleanSerializer(implicit ast: JsonAst): Serializer[Boolean, Json] = + implicit def booleanSerializer( + implicit ast: JsonAst): Serializer[Boolean, Json] = BasicJsonSerializer(ast fromBoolean _) - implicit def stringSerializer(implicit ast: JsonAst): Serializer[String, Json] = + implicit def stringSerializer( + implicit ast: JsonAst): Serializer[String, Json] = BasicJsonSerializer(ast fromString _) - implicit def floatSerializer(implicit ast: JsonAst): Serializer[Float, Json] = + implicit def floatSerializer( + implicit ast: JsonAst): Serializer[Float, Json] = BasicJsonSerializer(ast fromDouble _.toDouble) - implicit def doubleSerializer(implicit ast: JsonAst): Serializer[Double, Json] = + implicit def doubleSerializer( + implicit ast: JsonAst): Serializer[Double, Json] = BasicJsonSerializer(ast fromDouble _) - implicit def bigDecimalSerializer(implicit ast: JsonAst): Serializer[BigDecimal, Json] = + implicit def bigDecimalSerializer( + implicit ast: JsonAst): Serializer[BigDecimal, Json] = BasicJsonSerializer(ast fromBigDecimal _) - implicit def bigIntSerializer(implicit ast: JsonAst): Serializer[BigInt, Json] = + implicit def bigIntSerializer( + implicit ast: JsonAst): Serializer[BigInt, Json] = BasicJsonSerializer(ast fromBigDecimal BigDecimal(_)) implicit def longSerializer(implicit ast: JsonAst): Serializer[Long, Json] = BasicJsonSerializer(ast fromDouble _.toDouble) - implicit def shortSerializer(implicit ast: JsonAst): Serializer[Short, Json] = + implicit def shortSerializer( + implicit ast: JsonAst): Serializer[Short, Json] = BasicJsonSerializer(ast fromDouble _.toDouble) implicit def byteSerializer(implicit ast: JsonAst): Serializer[Byte, Json] = BasicJsonSerializer(ast fromDouble _.toDouble) - implicit def nilSerializer(implicit ast: JsonAst): Serializer[Nil.type, Json] = + implicit def nilSerializer( + implicit ast: JsonAst): Serializer[Nil.type, Json] = BasicJsonSerializer(v => ast fromArray Nil) - implicit def traversableSerializer[Type, Coll[T] <: Traversable[T]] - (implicit ast: JsonAst, ser: Serializer[Type, Json]): Serializer[Coll[Type], Json] = + implicit def traversableSerializer[Type, Coll[T] <: Traversable[T]]( + implicit ast: JsonAst, + ser: Serializer[Type, Json]): Serializer[Coll[Type], Json] = BasicJsonSerializer(ast fromArray _.map(ser.serialize).to[List]) - implicit def optionSerializer[Type] - (implicit ast: JsonAst, ser: Serializer[Type, Json]): Serializer[Option[Type], Json] = + implicit def optionSerializer[Type]( + implicit ast: JsonAst, + ser: Serializer[Type, Json]): Serializer[Option[Type], Json] = BasicJsonSerializer(_ map ser.serialize getOrElse ast.nullValue) - implicit def mapSerializer[K, Type, Ast <: JsonAst] - (implicit ast: Ast, ser: Serializer[Type, Json], ser2: StringSerializer[K]): Serializer[Map[K, Type], Json] = + implicit def mapSerializer[K, Type, Ast <: JsonAst]( + implicit ast: Ast, + ser: Serializer[Type, Json], + ser2: StringSerializer[K]): Serializer[Map[K, Type], Json] = new Serializer[Map[K, Type], Json] { def serialize(m: Map[K, Type]) = - ast.fromObject(m.map { case (k, v) => - ser2.serialize(k) -> ser.serialize(v) - }) + ast.fromObject( + m.map { + case (k, v) => + ser2.serialize(k) -> ser.serialize(v) + }) } - implicit def directJsonSerializer[T: DirectJsonSerializer](implicit ast: JsonAst): - Serializer[T, Json] = - BasicJsonSerializer(obj => jsonSerializer.serialize(Json.construct(MutableCell(obj), - Vector())(?[DirectJsonSerializer[T]].ast))) + implicit def directJsonSerializer[T : DirectJsonSerializer]( + implicit ast: JsonAst): Serializer[T, Json] = + BasicJsonSerializer( + obj => + jsonSerializer.serialize(Json.construct(MutableCell(obj), Vector())( + ?[DirectJsonSerializer[T]].ast))) - implicit def jsonSerializer[JsonType <: JsonDataType[JsonType, _ <: JsonAst]] - (implicit ast: JsonAst): Serializer[JsonType, Json] = + implicit def jsonSerializer[ + JsonType <: JsonDataType[JsonType, _ <: JsonAst]]( + implicit ast: JsonAst): Serializer[JsonType, Json] = BasicJsonSerializer[JsonType]({ j => - if(j.$ast == ast) j.$normalize else ast.convert(j.$normalize, j.$ast) + if (j.$ast == ast) j.$normalize else ast.convert(j.$normalize, j.$ast) }) } diff --git a/json/shared/src/main/scala/rapture/json/validator.scala b/json/shared/src/main/scala/rapture/json/validator.scala index a5053ad..c4302d3 100644 --- a/json/shared/src/main/scala/rapture/json/validator.scala +++ b/json/shared/src/main/scala/rapture/json/validator.scala @@ -13,32 +13,38 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json private[json] object JsonValidator { - case class ValidationException(strNo: Int, pos: Int, expected: String, found: Char) + case class ValidationException( + strNo: Int, pos: Int, expected: String, found: Char) extends Exception - - case class DuplicateKeyException(strNo: Int, pos: Int, key: String) extends Exception - + + case class DuplicateKeyException(strNo: Int, pos: Int, key: String) + extends Exception + case class NonStringKeyException(strNo: Int, pos: Int) extends Exception def validate(parts: List[String], stringsUsed: List[Boolean]) = { var i = 0 var n = 0 def s = parts(n) - def cur = if(i >= s.length) '\u0000' else s(i) + def cur = if (i >= s.length) '\u0000' else s(i) def fail(expected: String) = throw ValidationException(n, i, expected, cur) - def failPosition(expected: String) = throw ValidationException(n, i, expected, cur) - def duplicateKey(start: Int, key: String) = throw DuplicateKeyException(n, start, key) - - def takeWhitespace(): Unit = while(cur.isWhitespace) next() + def failPosition(expected: String) = + throw ValidationException(n, i, expected, cur) + def duplicateKey(start: Int, key: String) = + throw DuplicateKeyException(n, start, key) - def consume(cs: Char*): Unit = cs foreach { c => if(cur == c) next() else fail(s"'$c'") } + def takeWhitespace(): Unit = while (cur.isWhitespace) next() + + def consume(cs: Char*): Unit = cs foreach { c => + if (cur == c) next() else fail(s"'$c'") + } def next() = i += 1 @@ -51,7 +57,7 @@ private[json] object JsonValidator { case 'f' => takeFalse() case 'n' => takeNull() case '\u0000' => - if(n + 1 < parts.length) { + if (n + 1 < parts.length) { n += 1 i = 0 } else fail("new token or interpolated value") @@ -63,23 +69,23 @@ private[json] object JsonValidator { def takeNull() = consume('n', 'u', 'l', 'l') def takeNumber() = { - if(cur == '-') next() - - if(cur == '0') next() - else if(cur.isDigit) while(cur.isDigit) next() + if (cur == '-') next() + + if (cur == '0') next() + else if (cur.isDigit) while (cur.isDigit) next() else fail("digit") - - if(cur == '.') { + + if (cur == '.') { next() - if(cur.isDigit) next() else fail("digit") - while(cur.isDigit) next() + if (cur.isDigit) next() else fail("digit") + while (cur.isDigit) next() } - - if(cur == 'e' || cur == 'E') { + + if (cur == 'e' || cur == 'E') { next() - if(cur == '+' || cur == '-') next() - if(cur.isDigit) next() else fail("digit") - while(cur.isDigit) next() + if (cur == '+' || cur == '-') next() + if (cur.isDigit) next() else fail("digit") + while (cur.isDigit) next() } } @@ -89,15 +95,15 @@ private[json] object JsonValidator { val start = i cur match { case '\u0000' => - if(n + 1 < parts.length) { - if(!stringsUsed(n)) throw new NonStringKeyException(n, i) + if (n + 1 < parts.length) { + if (!stringsUsed(n)) throw new NonStringKeyException(n, i) n += 1 i = 0 } else fail("new token or interpolated value") case '"' => takeString() val key = s.substring(start + 1, i - 1) - if(seen contains key) duplicateKey(start, key) else seen += key + if (seen contains key) duplicateKey(start, key) else seen += key } takeWhitespace() cur match { @@ -150,7 +156,7 @@ private[json] object JsonValidator { def takeString(): Unit = { consume('"') - while(cur != '"') cur match { + while (cur != '"') cur match { case '\\' => consume('\\') cur match { @@ -158,7 +164,8 @@ private[json] object JsonValidator { case 'u' => consume('u') 1 to 4 foreach { j => - if(cur.isDigit || cur >= 'a' && cur <= 'f' || cur >= 'A' && cur <= 'F') next() + if (cur.isDigit || cur >= 'a' && cur <= 'f' || cur >= 'A' && + cur <= 'F') next() else fail("hexadecimal digit") } } @@ -171,6 +178,6 @@ private[json] object JsonValidator { takeWhitespace() takeValue() takeWhitespace() - if(i != s.length) fail("end of data") + if (i != s.length) fail("end of data") } } diff --git a/json/shared/src/main/scala/rapture/json/verifier.scala b/json/shared/src/main/scala/rapture/json/verifier.scala index 7cdf614..868b664 100644 --- a/json/shared/src/main/scala/rapture/json/verifier.scala +++ b/json/shared/src/main/scala/rapture/json/verifier.scala @@ -13,28 +13,35 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.json object JsonVerifier { - case class VerifierException(strNo: Int, pos: Int, expected: String, found: Char) extends Exception - case class DuplicateKeyException(strNo: Int, pos: Int, key: String) extends Exception + case class VerifierException( + strNo: Int, pos: Int, expected: String, found: Char) + extends Exception + case class DuplicateKeyException(strNo: Int, pos: Int, key: String) + extends Exception def verify(parts: List[String]) = { var i = 0 var n = 0 def s = parts(n) - def cur = if(i >= s.length) '\u0000' else s(i) + def cur = if (i >= s.length) '\u0000' else s(i) def fail(expected: String) = throw VerifierException(n, i, expected, cur) - def failPosition(expected: String) = throw VerifierException(n, i, expected, cur) - def duplicateKey(start: Int, key: String) = throw DuplicateKeyException(n, start, key) - - def takeWhitespace(): Unit = while(cur.isWhitespace) next() + def failPosition(expected: String) = + throw VerifierException(n, i, expected, cur) + def duplicateKey(start: Int, key: String) = + throw DuplicateKeyException(n, start, key) - def consume(cs: Char*): Unit = cs foreach { c => if(cur == c) next() else fail(s"'$c'") } + def takeWhitespace(): Unit = while (cur.isWhitespace) next() + + def consume(cs: Char*): Unit = cs foreach { c => + if (cur == c) next() else fail(s"'$c'") + } def next() = i += 1 @@ -47,7 +54,7 @@ object JsonVerifier { case 'f' => takeFalse() case 'n' => takeNull() case '\u0000' => - if(n + 1 < parts.length) { + if (n + 1 < parts.length) { n += 1 i = 0 } else fail("new token or interpolated value") @@ -59,23 +66,23 @@ object JsonVerifier { def takeNull() = consume('n', 'u', 'l', 'l') def takeNumber() = { - if(cur == '-') next() - - if(cur == '0') next() - else if(cur.isDigit) while(cur.isDigit) next() + if (cur == '-') next() + + if (cur == '0') next() + else if (cur.isDigit) while (cur.isDigit) next() else fail("digit") - - if(cur == '.') { + + if (cur == '.') { next() - if(cur.isDigit) next() else fail("digit") - while(cur.isDigit) next() + if (cur.isDigit) next() else fail("digit") + while (cur.isDigit) next() } - - if(cur == 'e' || cur == 'E') { + + if (cur == 'e' || cur == 'E') { next() - if(cur == '+' || cur == '-') next() - if(cur.isDigit) next() else fail("digit") - while(cur.isDigit) next() + if (cur == '+' || cur == '-') next() + if (cur.isDigit) next() else fail("digit") + while (cur.isDigit) next() } } @@ -85,9 +92,9 @@ object JsonVerifier { val start = i takeString() val key = s.substring(start + 1, i - 1) - - if(seen contains key) duplicateKey(start, key) else seen += key - + + if (seen contains key) duplicateKey(start, key) else seen += key + takeWhitespace() cur match { case ':' => @@ -139,7 +146,7 @@ object JsonVerifier { def takeString(): Unit = { consume('"') - while(cur != '"') cur match { + while (cur != '"') cur match { case '\\' => consume('\\') cur match { @@ -147,7 +154,8 @@ object JsonVerifier { case 'u' => consume('u') 1 to 4 foreach { j => - if(cur.isDigit || cur >= 'a' && cur <= 'f' || cur >= 'A' && cur <= 'F') next() + if (cur.isDigit || cur >= 'a' && cur <= 'f' || cur >= 'A' && + cur <= 'F') next() else fail("hexadecimal digit") } } @@ -160,6 +168,6 @@ object JsonVerifier { takeWhitespace() takeValue() takeWhitespace() - if(i != s.length) fail("end of data") + if (i != s.length) fail("end of data") } } diff --git a/log/shared/src/main/scala/rapture/log/levels.scala b/log/shared/src/main/scala/rapture/log/levels.scala index 2ec630e..f42ed7d 100644 --- a/log/shared/src/main/scala/rapture/log/levels.scala +++ b/log/shared/src/main/scala/rapture/log/levels.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.log @@ -26,29 +26,34 @@ trait Error extends Warn trait Fatal extends Error object logLevels { - + object trace { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(0, "trace") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 0, "trace") } object debug { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(1, "debug") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 1, "debug") } object info { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(2, "info") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 2, "info") } object warn { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(3, "warn") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 3, "warn") } object error { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(4, "error") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 4, "error") } object fatal { - implicit val logLevelImplicit: NamedLogAction = new NamedLogAction(5, "fatal") + implicit val logLevelImplicit: NamedLogAction = new NamedLogAction( + 5, "fatal") } } - diff --git a/log/shared/src/main/scala/rapture/log/log.scala b/log/shared/src/main/scala/rapture/log/log.scala index 4ea72ba..fe44a79 100644 --- a/log/shared/src/main/scala/rapture/log/log.scala +++ b/log/shared/src/main/scala/rapture/log/log.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.log @@ -28,13 +27,13 @@ import language.experimental.macros object `package` { val log = Log - + implicit class LogStringContext(sc: StringContext) { def log(xs: rapture.log.parts.Part*): Spec = { new Spec { def render(level: Int, lineNo: Int, source: String) = { val sb = new StringBuilder - for(i <- 0 until (sc.parts.length - 1)) { + for (i <- 0 until (sc.parts.length - 1)) { sb.append(sc.parts(i)) sb.append(xs(i).fit(level, lineNo, source)) } @@ -55,7 +54,8 @@ object LogAction { new LogAction { def level = -1 } } -@implicitNotFound("You have not specified a valid logging level. Please import one of logLevels"+ +@implicitNotFound( + "You have not specified a valid logging level. Please import one of logLevels" + ".{trace._, debug._, info._, warn._, error._, fatal._}.") trait LogAction { def level: Int @@ -68,9 +68,11 @@ object Loggable { def toArray(msg: String) = Array(msg) } - implicit val exceptionLoggable: Loggable[Throwable] = new Loggable[Throwable] { - def toArray(msg: Throwable) = Array(msg.toString) ++ msg.getStackTrace.map(" at "+_) - } + implicit val exceptionLoggable: Loggable[Throwable] = + new Loggable[Throwable] { + def toArray(msg: Throwable) = + Array(msg.toString) ++ msg.getStackTrace.map(" at " + _) + } } trait Loggable[-Msg] { def toArray(msg: Msg): Array[String] } @@ -80,13 +82,18 @@ object SourceContext { case class SourceContext(lineNo: Int, sourceFile: String) object LogMacros { - def logMacro[Msg: c.WeakTypeTag](level: Int)(c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], loggable: c.Expr[Loggable[Msg]], srcCtx: c.Expr[SourceContext]): c.Expr[Unit] = { + def logMacro[Msg : c.WeakTypeTag](level: Int)(c: BlackboxContext)( + msg: c.Expr[Msg])(log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + srcCtx: c.Expr[SourceContext]): c.Expr[Unit] = { import c.universe._ val lev = c.Expr[Int](Literal(Constant(level))) reify { - if(log.splice.action.level <= lev.splice) { - log.splice.out.log(log.splice.spec.render(lev.splice, srcCtx.splice.lineNo, - srcCtx.splice.sourceFile), loggable.splice.toArray(msg.splice)) + if (log.splice.action.level <= lev.splice) { + log.splice.out.log(log.splice.spec.render(lev.splice, + srcCtx.splice.lineNo, + srcCtx.splice.sourceFile), + loggable.splice.toArray(msg.splice)) } } } @@ -94,32 +101,45 @@ object LogMacros { def sourceContextMacro(c: BlackboxContext): c.Expr[SourceContext] = { import c.universe._ val lineNo = c.Expr[Int](Literal(Constant(c.enclosingPosition.line))) - val sourceFile = c.Expr[String](Literal(Constant(c.enclosingPosition.source.toString))) + val sourceFile = + c.Expr[String](Literal(Constant(c.enclosingPosition.source.toString))) reify { SourceContext(lineNo.splice, sourceFile.splice) } } - def traceMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + def traceMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(0)(c)(msg)(log, loggable, sourceContext) - - def debugMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + + def debugMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(1)(c)(msg)(log, loggable, sourceContext) - - def infoMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + + def infoMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(2)(c)(msg)(log, loggable, sourceContext) - - def warnMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + + def warnMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(3)(c)(msg)(log, loggable, sourceContext) - - def errorMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + + def errorMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(4)(c)(msg)(log, loggable, sourceContext) - - def fatalMacro[Msg: c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])(log: c.Expr[Log], - loggable: c.Expr[Loggable[Msg]], sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = + + def fatalMacro[Msg : c.WeakTypeTag](c: BlackboxContext)(msg: c.Expr[Msg])( + log: c.Expr[Log], + loggable: c.Expr[Loggable[Msg]], + sourceContext: c.Expr[SourceContext]): c.Expr[Unit] = logMacro(5)(c)(msg)(log, loggable, sourceContext) } @@ -138,30 +158,44 @@ abstract class Spec { }*/ object Log { - implicit def logImplicit(implicit spec: Spec, out: Outputter, action: LogAction) = + implicit def logImplicit( + implicit spec: Spec, out: Outputter, action: LogAction) = Log(spec, out, action) - - def trace[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def trace[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.traceMacro[Msg] - - def debug[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def debug[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.debugMacro[Msg] - - def info[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def info[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.infoMacro[Msg] - - def warn[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def warn[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.warnMacro[Msg] - - def error[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def error[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.errorMacro[Msg] - - def fatal[Msg](msg: Msg)(implicit log: Log, loggable: Loggable[Msg], + + def fatal[Msg](msg: Msg)( + implicit log: Log, + loggable: Loggable[Msg], sourceContext: SourceContext): Unit = macro LogMacros.fatalMacro[Msg] } case class Log(spec: Spec, out: Outputter, action: LogAction) -case class Logger[Res](res: Res)(implicit appender: Appender[Res, String]) extends Outputter { +case class Logger[Res](res: Res)(implicit appender: Appender[Res, String]) + extends Outputter { final val maxDelay = 25 final val queueThreshold = 10 @@ -173,40 +207,53 @@ case class Logger[Res](res: Res)(implicit appender: Appender[Res, String]) exten var continue = true sys.addShutdownHook { continue = false } - while(continue) { try { - queue synchronized { - queue.wait(maxDelay) - if(queue.size > 0) res handleAppend { out: Output[String] => - while(queue.size > 0) out.write(queue.dequeue) + while (continue) { + try { + queue synchronized { + queue.wait(maxDelay) + if (queue.size > 0) + res handleAppend { out: Output[String] => + while (queue.size > 0) out.write(queue.dequeue) + } } + } catch { + case e: InterruptedException => + continue = false } - } catch { case e: InterruptedException => - continue = false } - } } - - def log[L <: LogLevel](prefix: String, msg: Array[String]) = queue synchronized { - if(blankPrefix == null) blankPrefix = (" "*(prefix.length + 1)) - queue.enqueue(prefix+" "+msg(0)) - msg.tail foreach { m => queue.enqueue(blankPrefix+m) } - if(queue.size >= queueThreshold) queue.notify() } + + def log[L <: LogLevel](prefix: String, msg: Array[String]) = + queue synchronized { + if (blankPrefix == null) blankPrefix = (" " * (prefix.length + 1)) + queue.enqueue(prefix + " " + msg(0)) + msg.tail foreach { m => + queue.enqueue(blankPrefix + m) + } + if (queue.size >= queueThreshold) queue.notify() + } } object stdoutLogging { import parts._ - implicit def implicitSpec(implicit severity: Severity, date: Date, time: Time, - thread: Thread): Spec = - log"""$date $time [$severity] ${sourceFile(width = 12, Right)}:${lineNo(4)} ${thread(10)}""" - + implicit def implicitSpec(implicit severity: Severity, + date: Date, + time: Time, + thread: Thread): Spec = + log"""$date $time [$severity] ${sourceFile(width = 12, Right)}:${lineNo(4)} ${thread( + 10)}""" + implicit val output = Logger(Stdout) - def apply()(implicit severity: Severity, date: Date, time: Time, thread: Thread): - Spec with Outputter = new Spec with Outputter { - + def apply()(implicit severity: Severity, + date: Date, + time: Time, + thread: Thread): Spec with Outputter = new Spec with Outputter { + def render(level: Int, lineNo: Int, source: String): String = implicitSpec.render(level, lineNo, source) - - def log[L <: LogLevel](prefix: String, msg: Array[String]) = output.log(prefix, msg) + + def log[L <: LogLevel](prefix: String, msg: Array[String]) = + output.log(prefix, msg) } } diff --git a/log/shared/src/main/scala/rapture/log/parts.scala b/log/shared/src/main/scala/rapture/log/parts.scala index 9709f2c..5b734af 100644 --- a/log/shared/src/main/scala/rapture/log/parts.scala +++ b/log/shared/src/main/scala/rapture/log/parts.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.log @@ -26,15 +25,16 @@ object parts { def text(level: Int, lineNo: Int, source: String): String def fit(level: Int, lineNo: Int, source: String) = { val t = text(level, lineNo, source) - if(t.length > width) t.substring(0, width) - else if(align == Left) t.padTo(width, ' ') - else " "*(width - t.length)+t - } - - def apply(width: Int = width, align: Alignment = align): Part = new Part(width, align) { - def text(level: Int, lineNo: Int, source: String) = - part.text(level, lineNo, source) + if (t.length > width) t.substring(0, width) + else if (align == Left) t.padTo(width, ' ') + else " " * (width - t.length) + t } + + def apply(width: Int = width, align: Alignment = align): Part = + new Part(width, align) { + def text(level: Int, lineNo: Int, source: String) = + part.text(level, lineNo, source) + } } sealed trait Alignment @@ -62,7 +62,8 @@ object parts { } class Time(time: Long) extends Part(12, Left) { - def text(level: Int, lineNo: Int, source: String) = Time.timeFormat.format(time) + def text(level: Int, lineNo: Int, source: String) = + Time.timeFormat.format(time) } object Date { @@ -71,7 +72,8 @@ object parts { } class Date(date: Long) extends Part(9, Left) { - def text(level: Int, lineNo: Int, source: String) = Date.dateFormat.format(date) + def text(level: Int, lineNo: Int, source: String) = + Date.dateFormat.format(date) } object sourceFile extends Part(4, Left) { @@ -83,11 +85,11 @@ object parts { } object Thread { - implicit def currentThread: Thread = new Thread(java.lang.Thread.currentThread.getName) + implicit def currentThread: Thread = + new Thread(java.lang.Thread.currentThread.getName) } class Thread(name: String) extends Part(10, Left) { def text(level: Int, lineNo: Int, source: String) = name } } - diff --git a/mime/shared/src/main/scala/rapture/mime/mime.scala b/mime/shared/src/main/scala/rapture/mime/mime.scala index 3d9464b..a2e2f7b 100644 --- a/mime/shared/src/main/scala/rapture/mime/mime.scala +++ b/mime/shared/src/main/scala/rapture/mime/mime.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.mime @@ -21,10 +21,10 @@ package rapture.mime * list was produced from the public domain list of MIME types at * http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types w*/ object MimeTypes { - + private var exts = Map[String, List[MimeType]]() private var types = Map[String, MimeType]() - + def unapply(mt: String) = types.get(mt) /** Looks up the MIME type based on a file extension. */ @@ -34,22 +34,35 @@ object MimeTypes { * extensions which correspond to that type. */ case class MimeType(name: String, extensions: String*) { override def toString = name - for(ext <- extensions) exts = exts.updated(ext, this :: exts.get(ext).getOrElse(Nil)) + for (ext <- extensions) exts = exts.updated( + ext, this :: exts.get(ext).getOrElse(Nil)) types = types.updated(name, this) } - val `text/plain` = MimeType("text/plain", "asc", "conf", "def", "diff", "in", "list", "log", - "pot", "text", "txt") - - val `application/x-www-form-urlencoded` = MimeType("application/x-www-form-urlencoded") + val `text/plain` = MimeType("text/plain", + "asc", + "conf", + "def", + "diff", + "in", + "list", + "log", + "pot", + "text", + "txt") + + val `application/x-www-form-urlencoded` = MimeType( + "application/x-www-form-urlencoded") val `application/activemessage` = MimeType("application/activemessage") val `application/andrew-inset` = MimeType("application/andrew-inset", "ez") val `application/applefile` = MimeType("application/applefile") val `application/applixware` = MimeType("application/applixware", "aw") val `application/atom+xml` = MimeType("application/atom+xml", "atom") - val `application/atomcat+xml` = MimeType("application/atomcat+xml", "atomcat") + val `application/atomcat+xml` = MimeType( + "application/atomcat+xml", "atomcat") val `application/atomicmail` = MimeType("application/atomicmail") - val `application/atomsvc+xml` = MimeType("application/atomsvc+xml", "atomsvc") + val `application/atomsvc+xml` = MimeType( + "application/atomsvc+xml", "atomsvc") val `application/auth-policy+xml` = MimeType("application/auth-policy+xml") val `application/batch-smtp` = MimeType("application/batch-smtp") val `application/beep+xml` = MimeType("application/beep+xml") @@ -59,13 +72,15 @@ object MimeTypes { val `application/cellml+xml` = MimeType("application/cellml+xml") val `application/cnrp+xml` = MimeType("application/cnrp+xml") val `application/commonground` = MimeType("application/commonground") - val `application/conference-info+xml` = MimeType("application/conference-info+xml") + val `application/conference-info+xml` = MimeType( + "application/conference-info+xml") val `application/cpl+xml` = MimeType("application/cpl+xml") val `application/csta+xml` = MimeType("application/csta+xml") val `application/cstadata+xml` = MimeType("application/cstadata+xml") val `application/cu-seeme` = MimeType("application/cu-seeme", "cu") val `application/cybercash` = MimeType("application/cybercash") - val `application/davmount+xml` = MimeType("application/davmount+xml", "davmount") + val `application/davmount+xml` = MimeType( + "application/davmount+xml", "davmount") val `application/dca-rft` = MimeType("application/dca-rft") val `application/dec-dx` = MimeType("application/dec-dx") val `application/dialog-info+xml` = MimeType("application/dialog-info+xml") @@ -91,11 +106,14 @@ object MimeTypes { val `application/hta` = MimeType("application/hta", "hta") val `application/http` = MimeType("application/http") val `application/hyperstudio` = MimeType("application/hyperstudio", "stk") - val `application/ibe-key-request+xml` = MimeType("application/ibe-key-request+xml") - val `application/ibe-pkg-reply+xml` = MimeType("application/ibe-pkg-reply+xml") + val `application/ibe-key-request+xml` = MimeType( + "application/ibe-key-request+xml") + val `application/ibe-pkg-reply+xml` = MimeType( + "application/ibe-pkg-reply+xml") val `application/ibe-pp-data` = MimeType("application/ibe-pp-data") val `application/iges` = MimeType("application/iges") - val `application/im-iscomposing+xml` = MimeType("application/im-iscomposing+xml") + val `application/im-iscomposing+xml` = MimeType( + "application/im-iscomposing+xml") val `application/index` = MimeType("application/index") val `application/index.cmd` = MimeType("application/index.cmd") val `application/index.obj` = MimeType("application/index.obj") @@ -105,35 +123,49 @@ object MimeTypes { val `application/ipp` = MimeType("application/ipp") val `application/isup` = MimeType("application/isup") val `application/java-archive` = MimeType("application/java-archive", "jar") - val `application/java-serialized-object` = MimeType("application/java-serialized-object", "ser") + val `application/java-serialized-object` = MimeType( + "application/java-serialized-object", "ser") val `application/java-vm` = MimeType("application/java-vm", "class") val `application/javascript` = MimeType("application/javascript", "js") val `application/json` = MimeType("application/json", "json") val `application/kpml-request+xml` = MimeType("application/kpml-request+xml") - val `application/kpml-response+xml` = MimeType("application/kpml-response+xml") + val `application/kpml-response+xml` = MimeType( + "application/kpml-response+xml") val `application/lost+xml` = MimeType("application/lost+xml", "lostxml") val `application/mac-binhex40` = MimeType("application/mac-binhex40", "hqx") - val `application/mac-compactpro` = MimeType("application/mac-compactpro", "cpt") + val `application/mac-compactpro` = MimeType( + "application/mac-compactpro", "cpt") val `application/macwriteii` = MimeType("application/macwriteii") val `application/marc` = MimeType("application/marc", "mrc") - val `application/mathematica` = MimeType("application/mathematica", "ma", "mb", "nb") + val `application/mathematica` = MimeType( + "application/mathematica", "ma", "mb", "nb") val `application/mathml+xml` = MimeType("application/mathml+xml", "mathml") - - val `application/mbms-associated-procedure-description+xml` = - MimeType("application/mbms-associated-procedure-description+xml") - - val `application/mbms-deregister+xml` = MimeType("application/mbms-deregister+xml") - val `application/mbms-envelope+xml` = MimeType("application/mbms-envelope+xml") + + val `application/mbms-associated-procedure-description+xml` = MimeType( + "application/mbms-associated-procedure-description+xml") + + val `application/mbms-deregister+xml` = MimeType( + "application/mbms-deregister+xml") + val `application/mbms-envelope+xml` = MimeType( + "application/mbms-envelope+xml") val `application/mbms-msk+xml` = MimeType("application/mbms-msk+xml") - val `application/mbms-msk-response+xml` = MimeType("application/mbms-msk-response+xml") - val `application/mbms-protection-description+xml` = MimeType("application/mbms-protection-description+xml") - val `application/mbms-reception-report+xml` = MimeType("application/mbms-reception-report+xml") - val `application/mbms-register+xml` = MimeType("application/mbms-register+xml") - val `application/mbms-register-response+xml` = MimeType("application/mbms-register-response+xml") - val `application/mbms-user-service-description+xml` = MimeType("application/mbms-user-service-description+xml") + val `application/mbms-msk-response+xml` = MimeType( + "application/mbms-msk-response+xml") + val `application/mbms-protection-description+xml` = MimeType( + "application/mbms-protection-description+xml") + val `application/mbms-reception-report+xml` = MimeType( + "application/mbms-reception-report+xml") + val `application/mbms-register+xml` = MimeType( + "application/mbms-register+xml") + val `application/mbms-register-response+xml` = MimeType( + "application/mbms-register-response+xml") + val `application/mbms-user-service-description+xml` = MimeType( + "application/mbms-user-service-description+xml") val `application/mbox` = MimeType("application/mbox", "mbox") - val `application/media_control+xml` = MimeType("application/media_control+xml") - val `application/mediaservercontrol+xml` = MimeType("application/mediaservercontrol+xml", "mscml") + val `application/media_control+xml` = MimeType( + "application/media_control+xml") + val `application/mediaservercontrol+xml` = MimeType( + "application/mediaservercontrol+xml", "mscml") val `application/mikey` = MimeType("application/mikey") val `application/moss-keys` = MimeType("application/moss-keys") val `application/moss-signature` = MimeType("application/moss-signature") @@ -149,39 +181,63 @@ object MimeTypes { val `application/nasdata` = MimeType("application/nasdata") val `application/news-checkgroups` = MimeType("application/news-checkgroups") val `application/news-groupinfo` = MimeType("application/news-groupinfo") - val `application/news-transmission` = MimeType("application/news-transmission") + val `application/news-transmission` = MimeType( + "application/news-transmission") val `application/nss` = MimeType("application/nss") val `application/ocsp-request` = MimeType("application/ocsp-request") val `application/ocsp-response` = MimeType("application/ocsp-response") - - val `application/octet-stream` = - MimeType("application/octet-stream", "bin", "bpk", "deploy", "dist", "distz", "dmg", "dms", - "dump", "elc", "iso", "lha", "lrf", "lzh", "pkg", "so") - + + val `application/octet-stream` = MimeType("application/octet-stream", + "bin", + "bpk", + "deploy", + "dist", + "distz", + "dmg", + "dms", + "dump", + "elc", + "iso", + "lha", + "lrf", + "lzh", + "pkg", + "so") + val `application/oda` = MimeType("application/oda", "oda") - val `application/oebps-package+xml` = MimeType("application/oebps-package+xml", "opf") + val `application/oebps-package+xml` = MimeType( + "application/oebps-package+xml", "opf") val `application/ogg` = MimeType("application/ogg", "ogg", "ogx") - val `application/onenote` = MimeType("application/onenote", "onepkg", "onetmp", "onetoc", "onetoc2") + val `application/onenote` = MimeType( + "application/onenote", "onepkg", "onetmp", "onetoc", "onetoc2") val `application/parityfec` = MimeType("application/parityfec") - val `application/patch-ops-error+xml` = MimeType("application/patch-ops-error+xml", "xer") + val `application/patch-ops-error+xml` = MimeType( + "application/patch-ops-error+xml", "xer") val `application/pdf` = MimeType("application/pdf", "pdf") - val `application/pgp-encrypted` = MimeType("application/pgp-encrypted", "pgp") + val `application/pgp-encrypted` = MimeType( + "application/pgp-encrypted", "pgp") val `application/pgp-keys` = MimeType("application/pgp-keys", "key") - val `application/pgp-signature` = MimeType("application/pgp-signature", "asc", "pgp", "sig") + val `application/pgp-signature` = MimeType( + "application/pgp-signature", "asc", "pgp", "sig") val `application/pics-rules` = MimeType("application/pics-rules", "prf") val `application/pidf+xml` = MimeType("application/pidf+xml") val `application/pidf-diff+xml` = MimeType("application/pidf-diff+xml") val `application/pkcs10` = MimeType("application/pkcs10", "p10") - val `application/pkcs7-mime` = MimeType("application/pkcs7-mime", "p7c", "p7m") - val `application/pkcs7-signature` = MimeType("application/pkcs7-signature", "p7s") + val `application/pkcs7-mime` = MimeType( + "application/pkcs7-mime", "p7c", "p7m") + val `application/pkcs7-signature` = MimeType( + "application/pkcs7-signature", "p7s") val `application/pkix-cert` = MimeType("application/pkix-cert", "cer") val `application/pkix-crl` = MimeType("application/pkix-crl", "crl") - val `application/pkix-pkipath` = MimeType("application/pkix-pkipath", "pkipath") + val `application/pkix-pkipath` = MimeType( + "application/pkix-pkipath", "pkipath") val `application/pkixcmp` = MimeType("application/pkixcmp", "pki") val `application/pls+xml` = MimeType("application/pls+xml", "pls") val `application/poc-settings+xml` = MimeType("application/poc-settings+xml") - val `application/postscript` = MimeType("application/postscript", "ai", "eps", "ps") - val `application/prs.alvestrand.titrax-sheet` = MimeType("application/prs.alvestrand.titrax-sheet") + val `application/postscript` = MimeType( + "application/postscript", "ai", "eps", "ps") + val `application/prs.alvestrand.titrax-sheet` = MimeType( + "application/prs.alvestrand.titrax-sheet") val `application/prs.cww` = MimeType("application/prs.cww", "cww") val `application/prs.nprend` = MimeType("application/prs.nprend") val `application/prs.plucker` = MimeType("application/prs.plucker") @@ -189,44 +245,61 @@ object MimeTypes { val `application/rar` = MimeType("application/rar", "rar") val `application/rdf+xml` = MimeType("application/rdf+xml", "rdf") val `application/reginfo+xml` = MimeType("application/reginfo+xml", "rif") - val `application/relax-ng-compact-syntax` = MimeType("application/relax-ng-compact-syntax", "rnc") + val `application/relax-ng-compact-syntax` = MimeType( + "application/relax-ng-compact-syntax", "rnc") val `application/remote-printing` = MimeType("application/remote-printing") - val `application/resource-lists+xml` = MimeType("application/resource-lists+xml", "rl") - val `application/resource-lists-diff+xml` = MimeType("application/resource-lists-diff+xml", "rld") + val `application/resource-lists+xml` = MimeType( + "application/resource-lists+xml", "rl") + val `application/resource-lists-diff+xml` = MimeType( + "application/resource-lists-diff+xml", "rld") val `application/riscos` = MimeType("application/riscos") val `application/rlmi+xml` = MimeType("application/rlmi+xml") - val `application/rls-services+xml` = MimeType("application/rls-services+xml", "rs") + val `application/rls-services+xml` = MimeType( + "application/rls-services+xml", "rs") val `application/rsd+xml` = MimeType("application/rsd+xml", "rsd") val `application/rss+xml` = MimeType("application/rss+xml", "rss") val `application/rtf` = MimeType("application/rtf", "rtf") val `application/rtx` = MimeType("application/rtx") - val `application/samlassertion+xml` = MimeType("application/samlassertion+xml") + val `application/samlassertion+xml` = MimeType( + "application/samlassertion+xml") val `application/samlmetadata+xml` = MimeType("application/samlmetadata+xml") val `application/sbml+xml` = MimeType("application/sbml+xml", "sbml") - val `application/scvp-cv-request` = MimeType("application/scvp-cv-request", "scq") - val `application/scvp-cv-response` = MimeType("application/scvp-cv-response", "scs") - val `application/scvp-vp-request` = MimeType("application/scvp-vp-request", "spq") - val `application/scvp-vp-response` = MimeType("application/scvp-vp-response", "spp") + val `application/scvp-cv-request` = MimeType( + "application/scvp-cv-request", "scq") + val `application/scvp-cv-response` = MimeType( + "application/scvp-cv-response", "scs") + val `application/scvp-vp-request` = MimeType( + "application/scvp-vp-request", "spq") + val `application/scvp-vp-response` = MimeType( + "application/scvp-vp-response", "spp") val `application/sdp` = MimeType("application/sdp", "sdp") val `application/set-payment` = MimeType("application/set-payment") - val `application/set-payment-initiation` = MimeType("application/set-payment-initiation", "setpay") + val `application/set-payment-initiation` = MimeType( + "application/set-payment-initiation", "setpay") val `application/set-registration` = MimeType("application/set-registration") - val `application/set-registration-initiation` = MimeType("application/set-registration-initiation", "setreg") + val `application/set-registration-initiation` = MimeType( + "application/set-registration-initiation", "setreg") val `application/sgml` = MimeType("application/sgml") - val `application/sgml-open-catalog` = MimeType("application/sgml-open-catalog") + val `application/sgml-open-catalog` = MimeType( + "application/sgml-open-catalog") val `application/shf+xml` = MimeType("application/shf+xml", "shf") val `application/sieve` = MimeType("application/sieve") - val `application/simple-filter+xml` = MimeType("application/simple-filter+xml") - val `application/simple-message-summary` = MimeType("application/simple-message-summary") - val `application/simplesymbolcontainer` = MimeType("application/simplesymbolcontainer") + val `application/simple-filter+xml` = MimeType( + "application/simple-filter+xml") + val `application/simple-message-summary` = MimeType( + "application/simple-message-summary") + val `application/simplesymbolcontainer` = MimeType( + "application/simplesymbolcontainer") val `application/slate` = MimeType("application/slate") val `application/smil` = MimeType("application/smil", "smi", "smil") val `application/smil+xml` = MimeType("application/smil+xml", "smi", "smil") val `application/soap+fastinfoset` = MimeType("application/soap+fastinfoset") val `application/soap+xml` = MimeType("application/soap+xml") val `application/sparql-query` = MimeType("application/sparql-query", "rq") - val `application/sparql-results+xml` = MimeType("application/sparql-results+xml", "srx") - val `application/spirits-event+xml` = MimeType("application/spirits-event+xml") + val `application/sparql-results+xml` = MimeType( + "application/sparql-results+xml", "srx") + val `application/spirits-event+xml` = MimeType( + "application/spirits-event+xml") val `application/srgs` = MimeType("application/srgs", "gram") val `application/srgs+xml` = MimeType("application/srgs+xml", "grxml") val `application/ssml+xml` = MimeType("application/ssml+xml", "ssml") @@ -235,548 +308,884 @@ object MimeTypes { val `application/tve-trigger` = MimeType("application/tve-trigger") val `application/ulpfec` = MimeType("application/ulpfec") val `application/vemmi` = MimeType("application/vemmi") - val `application/vividence.scriptfile` = MimeType("application/vividence.scriptfile") + val `application/vividence.scriptfile` = MimeType( + "application/vividence.scriptfile") val `application/vnd.3gpp.bsf+xml` = MimeType("application/vnd.3gpp.bsf+xml") - val `application/vnd.3gpp.pic-bw-large` = MimeType("application/vnd.3gpp.pic-bw-large", "plb") - val `application/vnd.3gpp.pic-bw-small` = MimeType("application/vnd.3gpp.pic-bw-small", "psb") - val `application/vnd.3gpp.pic-bw-var` = MimeType("application/vnd.3gpp.pic-bw-var", "pvb") + val `application/vnd.3gpp.pic-bw-large` = MimeType( + "application/vnd.3gpp.pic-bw-large", "plb") + val `application/vnd.3gpp.pic-bw-small` = MimeType( + "application/vnd.3gpp.pic-bw-small", "psb") + val `application/vnd.3gpp.pic-bw-var` = MimeType( + "application/vnd.3gpp.pic-bw-var", "pvb") val `application/vnd.3gpp.sms` = MimeType("application/vnd.3gpp.sms") - val `application/vnd.3gpp2.bcmcsinfo+xml` = MimeType("application/vnd.3gpp2.bcmcsinfo+xml") + val `application/vnd.3gpp2.bcmcsinfo+xml` = MimeType( + "application/vnd.3gpp2.bcmcsinfo+xml") val `application/vnd.3gpp2.sms` = MimeType("application/vnd.3gpp2.sms") - val `application/vnd.3gpp2.tcap` = MimeType("application/vnd.3gpp2.tcap", "tcap") - val `application/vnd.3m.post-it-notes` = MimeType("application/vnd.3m.post-it-notes", "pwn") - val `application/vnd.accpac.simply.aso` = MimeType("application/vnd.accpac.simply.aso", "aso") - val `application/vnd.accpac.simply.imp` = MimeType("application/vnd.accpac.simply.imp", "imp") + val `application/vnd.3gpp2.tcap` = MimeType( + "application/vnd.3gpp2.tcap", "tcap") + val `application/vnd.3m.post-it-notes` = MimeType( + "application/vnd.3m.post-it-notes", "pwn") + val `application/vnd.accpac.simply.aso` = MimeType( + "application/vnd.accpac.simply.aso", "aso") + val `application/vnd.accpac.simply.imp` = MimeType( + "application/vnd.accpac.simply.imp", "imp") val `application/vnd.acucobol` = MimeType("application/vnd.acucobol", "acu") - val `application/vnd.acucorp` = MimeType("application/vnd.acucorp", "acutc", "atc") - - val `application/vnd.adobe.air-application-installer-package+zip` = - MimeType("application/vnd.adobe.air-application-installer-package+zip", "air") - - val `application/vnd.adobe.xdp+xml` = MimeType("application/vnd.adobe.xdp+xml", "xdp") - val `application/vnd.adobe.xfdf` = MimeType("application/vnd.adobe.xfdf", "xfdf") + val `application/vnd.acucorp` = MimeType( + "application/vnd.acucorp", "acutc", "atc") + + val `application/vnd.adobe.air-application-installer-package+zip` = MimeType( + "application/vnd.adobe.air-application-installer-package+zip", "air") + + val `application/vnd.adobe.xdp+xml` = MimeType( + "application/vnd.adobe.xdp+xml", "xdp") + val `application/vnd.adobe.xfdf` = MimeType( + "application/vnd.adobe.xfdf", "xfdf") val `application/vnd.aether.imp` = MimeType("application/vnd.aether.imp") - val `application/vnd.airzip.filesecure.azf` = MimeType("application/vnd.airzip.filesecure.azf", "azf") - val `application/vnd.airzip.filesecure.azs` = MimeType("application/vnd.airzip.filesecure.azs", "azs") - val `application/vnd.amazon.ebook` = MimeType("application/vnd.amazon.ebook", "azw") - val `application/vnd.americandynamics.acc` = MimeType("application/vnd.americandynamics.acc", "acc") - val `application/vnd.amiga.ami` = MimeType("application/vnd.amiga.ami", "ami") - val `application/vnd.android.package-archive` = MimeType("application/vnd.android.package-archive", "apk") - - val `application/vnd.anser-web-certificate-issue-initiation` = - MimeType("application/vnd.anser-web-certificate-issue-initiation", "cii") - - val `application/vnd.anser-web-funds-transfer-initiation` = - MimeType("application/vnd.anser-web-funds-transfer-initiation", "fti") - - val `application/vnd.antix.game-component` = MimeType("application/vnd.antix.game-component", "atx") - val `application/vnd.apple.installer+xml` = MimeType("application/vnd.apple.installer+xml", "mpkg") - val `application/vnd.arastra.swi` = MimeType("application/vnd.arastra.swi", "swi") - val `application/vnd.audiograph` = MimeType("application/vnd.audiograph", "aep") + val `application/vnd.airzip.filesecure.azf` = MimeType( + "application/vnd.airzip.filesecure.azf", "azf") + val `application/vnd.airzip.filesecure.azs` = MimeType( + "application/vnd.airzip.filesecure.azs", "azs") + val `application/vnd.amazon.ebook` = MimeType( + "application/vnd.amazon.ebook", "azw") + val `application/vnd.americandynamics.acc` = MimeType( + "application/vnd.americandynamics.acc", "acc") + val `application/vnd.amiga.ami` = MimeType( + "application/vnd.amiga.ami", "ami") + val `application/vnd.android.package-archive` = MimeType( + "application/vnd.android.package-archive", "apk") + + val `application/vnd.anser-web-certificate-issue-initiation` = MimeType( + "application/vnd.anser-web-certificate-issue-initiation", "cii") + + val `application/vnd.anser-web-funds-transfer-initiation` = MimeType( + "application/vnd.anser-web-funds-transfer-initiation", "fti") + + val `application/vnd.antix.game-component` = MimeType( + "application/vnd.antix.game-component", "atx") + val `application/vnd.apple.installer+xml` = MimeType( + "application/vnd.apple.installer+xml", "mpkg") + val `application/vnd.arastra.swi` = MimeType( + "application/vnd.arastra.swi", "swi") + val `application/vnd.audiograph` = MimeType( + "application/vnd.audiograph", "aep") val `application/vnd.autopackage` = MimeType("application/vnd.autopackage") val `application/vnd.avistar+xml` = MimeType("application/vnd.avistar+xml") - val `application/vnd.blueice.multipass` = MimeType("application/vnd.blueice.multipass", "mpm") - val `application/vnd.bluetooth.ep.oob` = MimeType("application/vnd.bluetooth.ep.oob") + val `application/vnd.blueice.multipass` = MimeType( + "application/vnd.blueice.multipass", "mpm") + val `application/vnd.bluetooth.ep.oob` = MimeType( + "application/vnd.bluetooth.ep.oob") val `application/vnd.bmi` = MimeType("application/vnd.bmi", "bmi") - val `application/vnd.businessobjects` = MimeType("application/vnd.businessobjects", "rep") + val `application/vnd.businessobjects` = MimeType( + "application/vnd.businessobjects", "rep") val `application/vnd.cab-jscript` = MimeType("application/vnd.cab-jscript") val `application/vnd.canon-cpdl` = MimeType("application/vnd.canon-cpdl") val `application/vnd.canon-lips` = MimeType("application/vnd.canon-lips") - val `application/vnd.cendio.thinlinc.clientconf` = MimeType("application/vnd.cendio.thinlinc.clientconf") - val `application/vnd.chemdraw+xml` = MimeType("application/vnd.chemdraw+xml", "cdxml") - val `application/vnd.chipnuts.karaoke-mmd` = MimeType("application/vnd.chipnuts.karaoke-mmd", "mmd") - val `application/vnd.cinderella` = MimeType("application/vnd.cinderella", "cdy") - val `application/vnd.cirpack.isdn-ext` = MimeType("application/vnd.cirpack.isdn-ext") + val `application/vnd.cendio.thinlinc.clientconf` = MimeType( + "application/vnd.cendio.thinlinc.clientconf") + val `application/vnd.chemdraw+xml` = MimeType( + "application/vnd.chemdraw+xml", "cdxml") + val `application/vnd.chipnuts.karaoke-mmd` = MimeType( + "application/vnd.chipnuts.karaoke-mmd", "mmd") + val `application/vnd.cinderella` = MimeType( + "application/vnd.cinderella", "cdy") + val `application/vnd.cirpack.isdn-ext` = MimeType( + "application/vnd.cirpack.isdn-ext") val `application/vnd.claymore` = MimeType("application/vnd.claymore", "cla") - val `application/vnd.clonk.c4group` = MimeType("application/vnd.clonk.c4group", "c4d", "c4f", "c4g", "c4p", "c4u") - val `application/vnd.commerce-battelle` = MimeType("application/vnd.commerce-battelle") - val `application/vnd.commonspace` = MimeType("application/vnd.commonspace", "csp") - val `application/vnd.contact.cmsg` = MimeType("application/vnd.contact.cmsg", "cdbcmsg") - val `application/vnd.cosmocaller` = MimeType("application/vnd.cosmocaller", "cmc") - val `application/vnd.crick.clicker` = MimeType("application/vnd.crick.clicker", "clkx") - val `application/vnd.crick.clicker.keyboard` = MimeType("application/vnd.crick.clicker.keyboard", "clkk") - val `application/vnd.crick.clicker.palette` = MimeType("application/vnd.crick.clicker.palette", "clkp") - val `application/vnd.crick.clicker.template` = MimeType("application/vnd.crick.clicker.template", "clkt") - val `application/vnd.crick.clicker.wordbank` = MimeType("application/vnd.crick.clicker.wordbank", "clkw") - val `application/vnd.criticaltools.wbs+xml` = MimeType("application/vnd.criticaltools.wbs+xml", "wbs") - val `application/vnd.ctc-posml` = MimeType("application/vnd.ctc-posml", "pml") + val `application/vnd.clonk.c4group` = MimeType( + "application/vnd.clonk.c4group", "c4d", "c4f", "c4g", "c4p", "c4u") + val `application/vnd.commerce-battelle` = MimeType( + "application/vnd.commerce-battelle") + val `application/vnd.commonspace` = MimeType( + "application/vnd.commonspace", "csp") + val `application/vnd.contact.cmsg` = MimeType( + "application/vnd.contact.cmsg", "cdbcmsg") + val `application/vnd.cosmocaller` = MimeType( + "application/vnd.cosmocaller", "cmc") + val `application/vnd.crick.clicker` = MimeType( + "application/vnd.crick.clicker", "clkx") + val `application/vnd.crick.clicker.keyboard` = MimeType( + "application/vnd.crick.clicker.keyboard", "clkk") + val `application/vnd.crick.clicker.palette` = MimeType( + "application/vnd.crick.clicker.palette", "clkp") + val `application/vnd.crick.clicker.template` = MimeType( + "application/vnd.crick.clicker.template", "clkt") + val `application/vnd.crick.clicker.wordbank` = MimeType( + "application/vnd.crick.clicker.wordbank", "clkw") + val `application/vnd.criticaltools.wbs+xml` = MimeType( + "application/vnd.criticaltools.wbs+xml", "wbs") + val `application/vnd.ctc-posml` = MimeType( + "application/vnd.ctc-posml", "pml") val `application/vnd.ctct.ws+xml` = MimeType("application/vnd.ctct.ws+xml") val `application/vnd.cups-pdf` = MimeType("application/vnd.cups-pdf") - val `application/vnd.cups-postscript` = MimeType("application/vnd.cups-postscript") + val `application/vnd.cups-postscript` = MimeType( + "application/vnd.cups-postscript") val `application/vnd.cups-ppd` = MimeType("application/vnd.cups-ppd", "ppd") val `application/vnd.cups-raster` = MimeType("application/vnd.cups-raster") val `application/vnd.cups-raw` = MimeType("application/vnd.cups-raw") val `application/vnd.curl.car` = MimeType("application/vnd.curl.car", "car") - val `application/vnd.curl.pcurl` = MimeType("application/vnd.curl.pcurl", "pcurl") + val `application/vnd.curl.pcurl` = MimeType( + "application/vnd.curl.pcurl", "pcurl") val `application/vnd.cybank` = MimeType("application/vnd.cybank") - val `application/vnd.data-vision.rdz` = MimeType("application/vnd.data-vision.rdz", "rdz") - val `application/vnd.denovo.fcselayout-link` = MimeType("application/vnd.denovo.fcselayout-link", "fe", "_launch") - val `application/vnd.dir-bi.plate-dl-nosuffix` = MimeType("application/vnd.dir-bi.plate-dl-nosuffix") + val `application/vnd.data-vision.rdz` = MimeType( + "application/vnd.data-vision.rdz", "rdz") + val `application/vnd.denovo.fcselayout-link` = MimeType( + "application/vnd.denovo.fcselayout-link", "fe", "_launch") + val `application/vnd.dir-bi.plate-dl-nosuffix` = MimeType( + "application/vnd.dir-bi.plate-dl-nosuffix") val `application/vnd.dna` = MimeType("application/vnd.dna", "dna") - val `application/vnd.dolby.mlp` = MimeType("application/vnd.dolby.mlp", "mlp") - val `application/vnd.dolby.mobile.1` = MimeType("application/vnd.dolby.mobile.1") - val `application/vnd.dolby.mobile.2` = MimeType("application/vnd.dolby.mobile.2") + val `application/vnd.dolby.mlp` = MimeType( + "application/vnd.dolby.mlp", "mlp") + val `application/vnd.dolby.mobile.1` = MimeType( + "application/vnd.dolby.mobile.1") + val `application/vnd.dolby.mobile.2` = MimeType( + "application/vnd.dolby.mobile.2") val `application/vnd.dpgraph` = MimeType("application/vnd.dpgraph", "dpg") - val `application/vnd.dreamfactory` = MimeType("application/vnd.dreamfactory", "dfac") - val `application/vnd.dvb.esgcontainer` = MimeType("application/vnd.dvb.esgcontainer") - val `application/vnd.dvb.ipdcdftnotifaccess` = MimeType("application/vnd.dvb.ipdcdftnotifaccess") - val `application/vnd.dvb.ipdcesgaccess` = MimeType("application/vnd.dvb.ipdcesgaccess") - val `application/vnd.dvb.ipdcroaming` = MimeType("application/vnd.dvb.ipdcroaming") - val `application/vnd.dvb.iptv.alfec-base` = MimeType("application/vnd.dvb.iptv.alfec-base") - val `application/vnd.dvb.iptv.alfec-enhancement` = MimeType("application/vnd.dvb.iptv.alfec-enhancement") - val `application/vnd.dvb.notif-aggregate-root+xml` = MimeType("application/vnd.dvb.notif-aggregate-root+xml") - val `application/vnd.dvb.notif-container+xml` = MimeType("application/vnd.dvb.notif-container+xml") - val `application/vnd.dvb.notif-generic+xml` = MimeType("application/vnd.dvb.notif-generic+xml") - val `application/vnd.dvb.notif-ia-msglist+xml` = MimeType("application/vnd.dvb.notif-ia-msglist+xml") - - val `application/vnd.dvb.notif-ia-registration-request+xml` = - MimeType("application/vnd.dvb.notif-ia-registration-request+xml") - - val `application/vnd.dvb.notif-ia-registration-response+xml` = - MimeType("application/vnd.dvb.notif-ia-registration-response+xml") - - val `application/vnd.dvb.notif-init+xml` = MimeType("application/vnd.dvb.notif-init+xml") + val `application/vnd.dreamfactory` = MimeType( + "application/vnd.dreamfactory", "dfac") + val `application/vnd.dvb.esgcontainer` = MimeType( + "application/vnd.dvb.esgcontainer") + val `application/vnd.dvb.ipdcdftnotifaccess` = MimeType( + "application/vnd.dvb.ipdcdftnotifaccess") + val `application/vnd.dvb.ipdcesgaccess` = MimeType( + "application/vnd.dvb.ipdcesgaccess") + val `application/vnd.dvb.ipdcroaming` = MimeType( + "application/vnd.dvb.ipdcroaming") + val `application/vnd.dvb.iptv.alfec-base` = MimeType( + "application/vnd.dvb.iptv.alfec-base") + val `application/vnd.dvb.iptv.alfec-enhancement` = MimeType( + "application/vnd.dvb.iptv.alfec-enhancement") + val `application/vnd.dvb.notif-aggregate-root+xml` = MimeType( + "application/vnd.dvb.notif-aggregate-root+xml") + val `application/vnd.dvb.notif-container+xml` = MimeType( + "application/vnd.dvb.notif-container+xml") + val `application/vnd.dvb.notif-generic+xml` = MimeType( + "application/vnd.dvb.notif-generic+xml") + val `application/vnd.dvb.notif-ia-msglist+xml` = MimeType( + "application/vnd.dvb.notif-ia-msglist+xml") + + val `application/vnd.dvb.notif-ia-registration-request+xml` = MimeType( + "application/vnd.dvb.notif-ia-registration-request+xml") + + val `application/vnd.dvb.notif-ia-registration-response+xml` = MimeType( + "application/vnd.dvb.notif-ia-registration-response+xml") + + val `application/vnd.dvb.notif-init+xml` = MimeType( + "application/vnd.dvb.notif-init+xml") val `application/vnd.dxr` = MimeType("application/vnd.dxr") val `application/vnd.dynageo` = MimeType("application/vnd.dynageo", "geo") val `application/vnd.ecdis-update` = MimeType("application/vnd.ecdis-update") - val `application/vnd.ecowin.chart` = MimeType("application/vnd.ecowin.chart", "mag") - val `application/vnd.ecowin.filerequest` = MimeType("application/vnd.ecowin.filerequest") - val `application/vnd.ecowin.fileupdate` = MimeType("application/vnd.ecowin.fileupdate") - val `application/vnd.ecowin.series` = MimeType("application/vnd.ecowin.series") - val `application/vnd.ecowin.seriesrequest` = MimeType("application/vnd.ecowin.seriesrequest") - val `application/vnd.ecowin.seriesupdate` = MimeType("application/vnd.ecowin.seriesupdate") - val `application/vnd.emclient.accessrequest+xml` = MimeType("application/vnd.emclient.accessrequest+xml") + val `application/vnd.ecowin.chart` = MimeType( + "application/vnd.ecowin.chart", "mag") + val `application/vnd.ecowin.filerequest` = MimeType( + "application/vnd.ecowin.filerequest") + val `application/vnd.ecowin.fileupdate` = MimeType( + "application/vnd.ecowin.fileupdate") + val `application/vnd.ecowin.series` = MimeType( + "application/vnd.ecowin.series") + val `application/vnd.ecowin.seriesrequest` = MimeType( + "application/vnd.ecowin.seriesrequest") + val `application/vnd.ecowin.seriesupdate` = MimeType( + "application/vnd.ecowin.seriesupdate") + val `application/vnd.emclient.accessrequest+xml` = MimeType( + "application/vnd.emclient.accessrequest+xml") val `application/vnd.enliven` = MimeType("application/vnd.enliven", "nml") - val `application/vnd.epson.esf` = MimeType("application/vnd.epson.esf", "esf") - val `application/vnd.epson.msf` = MimeType("application/vnd.epson.msf", "msf") - val `application/vnd.epson.quickanime` = MimeType("application/vnd.epson.quickanime", "qam") - val `application/vnd.epson.salt` = MimeType("application/vnd.epson.salt", "slt") - val `application/vnd.epson.ssf` = MimeType("application/vnd.epson.ssf", "ssf") - val `application/vnd.ericsson.quickcall` = MimeType("application/vnd.ericsson.quickcall") - val `application/vnd.eszigno3+xml` = MimeType("application/vnd.eszigno3+xml", "es3", "et3") + val `application/vnd.epson.esf` = MimeType( + "application/vnd.epson.esf", "esf") + val `application/vnd.epson.msf` = MimeType( + "application/vnd.epson.msf", "msf") + val `application/vnd.epson.quickanime` = MimeType( + "application/vnd.epson.quickanime", "qam") + val `application/vnd.epson.salt` = MimeType( + "application/vnd.epson.salt", "slt") + val `application/vnd.epson.ssf` = MimeType( + "application/vnd.epson.ssf", "ssf") + val `application/vnd.ericsson.quickcall` = MimeType( + "application/vnd.ericsson.quickcall") + val `application/vnd.eszigno3+xml` = MimeType( + "application/vnd.eszigno3+xml", "es3", "et3") val `application/vnd.etsi.aoc+xml` = MimeType("application/vnd.etsi.aoc+xml") val `application/vnd.etsi.cug+xml` = MimeType("application/vnd.etsi.cug+xml") - val `application/vnd.etsi.iptvcommand+xml` = MimeType("application/vnd.etsi.iptvcommand+xml") - val `application/vnd.etsi.iptvdiscovery+xml` = MimeType("application/vnd.etsi.iptvdiscovery+xml") - val `application/vnd.etsi.iptvprofile+xml` = MimeType("application/vnd.etsi.iptvprofile+xml") - val `application/vnd.etsi.iptvsad-bc+xml` = MimeType("application/vnd.etsi.iptvsad-bc+xml") - val `application/vnd.etsi.iptvsad-cod+xml` = MimeType("application/vnd.etsi.iptvsad-cod+xml") - val `application/vnd.etsi.iptvsad-npvr+xml` = MimeType("application/vnd.etsi.iptvsad-npvr+xml") - val `application/vnd.etsi.iptvueprofile+xml` = MimeType("application/vnd.etsi.iptvueprofile+xml") - val `application/vnd.etsi.mcid+xml` = MimeType("application/vnd.etsi.mcid+xml") + val `application/vnd.etsi.iptvcommand+xml` = MimeType( + "application/vnd.etsi.iptvcommand+xml") + val `application/vnd.etsi.iptvdiscovery+xml` = MimeType( + "application/vnd.etsi.iptvdiscovery+xml") + val `application/vnd.etsi.iptvprofile+xml` = MimeType( + "application/vnd.etsi.iptvprofile+xml") + val `application/vnd.etsi.iptvsad-bc+xml` = MimeType( + "application/vnd.etsi.iptvsad-bc+xml") + val `application/vnd.etsi.iptvsad-cod+xml` = MimeType( + "application/vnd.etsi.iptvsad-cod+xml") + val `application/vnd.etsi.iptvsad-npvr+xml` = MimeType( + "application/vnd.etsi.iptvsad-npvr+xml") + val `application/vnd.etsi.iptvueprofile+xml` = MimeType( + "application/vnd.etsi.iptvueprofile+xml") + val `application/vnd.etsi.mcid+xml` = MimeType( + "application/vnd.etsi.mcid+xml") val `application/vnd.etsi.sci+xml` = MimeType("application/vnd.etsi.sci+xml") - val `application/vnd.etsi.simservs+xml` = MimeType("application/vnd.etsi.simservs+xml") + val `application/vnd.etsi.simservs+xml` = MimeType( + "application/vnd.etsi.simservs+xml") val `application/vnd.eudora.data` = MimeType("application/vnd.eudora.data") - val `application/vnd.ezpix-album` = MimeType("application/vnd.ezpix-album", "ez2") - val `application/vnd.ezpix-package` = MimeType("application/vnd.ezpix-package", "ez3") - val `application/vnd.f-secure.mobile` = MimeType("application/vnd.f-secure.mobile") + val `application/vnd.ezpix-album` = MimeType( + "application/vnd.ezpix-album", "ez2") + val `application/vnd.ezpix-package` = MimeType( + "application/vnd.ezpix-package", "ez3") + val `application/vnd.f-secure.mobile` = MimeType( + "application/vnd.f-secure.mobile") val `application/vnd.fdf` = MimeType("application/vnd.fdf", "fdf") - val `application/vnd.fdsn.mseed` = MimeType("application/vnd.fdsn.mseed", "mseed") - val `application/vnd.fdsn.seed` = MimeType("application/vnd.fdsn.seed", "dataless", "seed") + val `application/vnd.fdsn.mseed` = MimeType( + "application/vnd.fdsn.mseed", "mseed") + val `application/vnd.fdsn.seed` = MimeType( + "application/vnd.fdsn.seed", "dataless", "seed") val `application/vnd.ffsns` = MimeType("application/vnd.ffsns") val `application/vnd.fints` = MimeType("application/vnd.fints") - val `application/vnd.flographit` = MimeType("application/vnd.flographit", "gph") - val `application/vnd.fluxtime.clip` = MimeType("application/vnd.fluxtime.clip", "ftc") - val `application/vnd.font-fontforge-sfd` = MimeType("application/vnd.font-fontforge-sfd") - val `application/vnd.framemaker` = MimeType("application/vnd.framemaker", "book", "fm", "frame", "maker") - val `application/vnd.frogans.fnc` = MimeType("application/vnd.frogans.fnc", "fnc") - val `application/vnd.frogans.ltf` = MimeType("application/vnd.frogans.ltf", "ltf") - val `application/vnd.fsc.weblaunch` = MimeType("application/vnd.fsc.weblaunch", "fsc") - val `application/vnd.fujitsu.oasys` = MimeType("application/vnd.fujitsu.oasys", "oas") - val `application/vnd.fujitsu.oasys2` = MimeType("application/vnd.fujitsu.oasys2", "oa2") - val `application/vnd.fujitsu.oasys3` = MimeType("application/vnd.fujitsu.oasys3", "oa3") - val `application/vnd.fujitsu.oasysgp` = MimeType("application/vnd.fujitsu.oasysgp", "fg5") - val `application/vnd.fujitsu.oasysprs` = MimeType("application/vnd.fujitsu.oasysprs", "bh2") - val `application/vnd.fujixerox.art-ex` = MimeType("application/vnd.fujixerox.art-ex") - val `application/vnd.fujixerox.art4` = MimeType("application/vnd.fujixerox.art4") - val `application/vnd.fujixerox.ddd` = MimeType("application/vnd.fujixerox.ddd", "ddd") - val `application/vnd.fujixerox.docuworks` = MimeType("application/vnd.fujixerox.docuworks", "xdw") - val `application/vnd.fujixerox.docuworks.binder` = MimeType("application/vnd.fujixerox.docuworks.binder", "xbd") - val `application/vnd.fujixerox.hbpl` = MimeType("application/vnd.fujixerox.hbpl") + val `application/vnd.flographit` = MimeType( + "application/vnd.flographit", "gph") + val `application/vnd.fluxtime.clip` = MimeType( + "application/vnd.fluxtime.clip", "ftc") + val `application/vnd.font-fontforge-sfd` = MimeType( + "application/vnd.font-fontforge-sfd") + val `application/vnd.framemaker` = MimeType( + "application/vnd.framemaker", "book", "fm", "frame", "maker") + val `application/vnd.frogans.fnc` = MimeType( + "application/vnd.frogans.fnc", "fnc") + val `application/vnd.frogans.ltf` = MimeType( + "application/vnd.frogans.ltf", "ltf") + val `application/vnd.fsc.weblaunch` = MimeType( + "application/vnd.fsc.weblaunch", "fsc") + val `application/vnd.fujitsu.oasys` = MimeType( + "application/vnd.fujitsu.oasys", "oas") + val `application/vnd.fujitsu.oasys2` = MimeType( + "application/vnd.fujitsu.oasys2", "oa2") + val `application/vnd.fujitsu.oasys3` = MimeType( + "application/vnd.fujitsu.oasys3", "oa3") + val `application/vnd.fujitsu.oasysgp` = MimeType( + "application/vnd.fujitsu.oasysgp", "fg5") + val `application/vnd.fujitsu.oasysprs` = MimeType( + "application/vnd.fujitsu.oasysprs", "bh2") + val `application/vnd.fujixerox.art-ex` = MimeType( + "application/vnd.fujixerox.art-ex") + val `application/vnd.fujixerox.art4` = MimeType( + "application/vnd.fujixerox.art4") + val `application/vnd.fujixerox.ddd` = MimeType( + "application/vnd.fujixerox.ddd", "ddd") + val `application/vnd.fujixerox.docuworks` = MimeType( + "application/vnd.fujixerox.docuworks", "xdw") + val `application/vnd.fujixerox.docuworks.binder` = MimeType( + "application/vnd.fujixerox.docuworks.binder", "xbd") + val `application/vnd.fujixerox.hbpl` = MimeType( + "application/vnd.fujixerox.hbpl") val `application/vnd.fut-misnet` = MimeType("application/vnd.fut-misnet") - val `application/vnd.fuzzysheet` = MimeType("application/vnd.fuzzysheet", "fzs") - val `application/vnd.genomatix.tuxedo` = MimeType("application/vnd.genomatix.tuxedo", "txd") - val `application/vnd.geogebra.file` = MimeType("application/vnd.geogebra.file", "ggb") - val `application/vnd.geogebra.tool` = MimeType("application/vnd.geogebra.tool", "ggt") - val `application/vnd.geometry-explorer` = MimeType("application/vnd.geometry-explorer", "gex", "gre") + val `application/vnd.fuzzysheet` = MimeType( + "application/vnd.fuzzysheet", "fzs") + val `application/vnd.genomatix.tuxedo` = MimeType( + "application/vnd.genomatix.tuxedo", "txd") + val `application/vnd.geogebra.file` = MimeType( + "application/vnd.geogebra.file", "ggb") + val `application/vnd.geogebra.tool` = MimeType( + "application/vnd.geogebra.tool", "ggt") + val `application/vnd.geometry-explorer` = MimeType( + "application/vnd.geometry-explorer", "gex", "gre") val `application/vnd.gmx` = MimeType("application/vnd.gmx", "gmx") - val `application/vnd.google-earth.kml+xml` = MimeType("application/vnd.google-earth.kml+xml", "kml") - val `application/vnd.google-earth.kmz` = MimeType("application/vnd.google-earth.kmz", "kmz") - val `application/vnd.grafeq` = MimeType("application/vnd.grafeq", "gqf", "gqs") + val `application/vnd.google-earth.kml+xml` = MimeType( + "application/vnd.google-earth.kml+xml", "kml") + val `application/vnd.google-earth.kmz` = MimeType( + "application/vnd.google-earth.kmz", "kmz") + val `application/vnd.grafeq` = MimeType( + "application/vnd.grafeq", "gqf", "gqs") val `application/vnd.gridmp` = MimeType("application/vnd.gridmp") - val `application/vnd.groove-account` = MimeType("application/vnd.groove-account", "gac") - val `application/vnd.groove-help` = MimeType("application/vnd.groove-help", "ghf") - val `application/vnd.groove-identity-message` = MimeType("application/vnd.groove-identity-message", "gim") - val `application/vnd.groove-injector` = MimeType("application/vnd.groove-injector", "grv") - val `application/vnd.groove-tool-message` = MimeType("application/vnd.groove-tool-message", "gtm") - val `application/vnd.groove-tool-template` = MimeType("application/vnd.groove-tool-template", "tpl") - val `application/vnd.groove-vcard` = MimeType("application/vnd.groove-vcard", "vcg") - val `application/vnd.handheld-entertainment+xml` = MimeType("application/vnd.handheld-entertainment+xml", "zmm") + val `application/vnd.groove-account` = MimeType( + "application/vnd.groove-account", "gac") + val `application/vnd.groove-help` = MimeType( + "application/vnd.groove-help", "ghf") + val `application/vnd.groove-identity-message` = MimeType( + "application/vnd.groove-identity-message", "gim") + val `application/vnd.groove-injector` = MimeType( + "application/vnd.groove-injector", "grv") + val `application/vnd.groove-tool-message` = MimeType( + "application/vnd.groove-tool-message", "gtm") + val `application/vnd.groove-tool-template` = MimeType( + "application/vnd.groove-tool-template", "tpl") + val `application/vnd.groove-vcard` = MimeType( + "application/vnd.groove-vcard", "vcg") + val `application/vnd.handheld-entertainment+xml` = MimeType( + "application/vnd.handheld-entertainment+xml", "zmm") val `application/vnd.hbci` = MimeType("application/vnd.hbci", "hbci") - val `application/vnd.hcl-bireports` = MimeType("application/vnd.hcl-bireports") - val `application/vnd.hhe.lesson-player` = MimeType("application/vnd.hhe.lesson-player", "les") + val `application/vnd.hcl-bireports` = MimeType( + "application/vnd.hcl-bireports") + val `application/vnd.hhe.lesson-player` = MimeType( + "application/vnd.hhe.lesson-player", "les") val `application/vnd.hp-hpgl` = MimeType("application/vnd.hp-hpgl", "hpgl") val `application/vnd.hp-hpid` = MimeType("application/vnd.hp-hpid", "hpid") val `application/vnd.hp-hps` = MimeType("application/vnd.hp-hps", "hps") val `application/vnd.hp-jlyt` = MimeType("application/vnd.hp-jlyt", "jlt") val `application/vnd.hp-pcl` = MimeType("application/vnd.hp-pcl", "pcl") - val `application/vnd.hp-pclxl` = MimeType("application/vnd.hp-pclxl", "pclxl") + val `application/vnd.hp-pclxl` = MimeType( + "application/vnd.hp-pclxl", "pclxl") val `application/vnd.httphone` = MimeType("application/vnd.httphone") - val `application/vnd.hydrostatix.sof-data` = MimeType("application/vnd.hydrostatix.sof-data", "sfd", "-hdstx") - val `application/vnd.hzn-3d-crossword` = MimeType("application/vnd.hzn-3d-crossword", "x3d") - val `application/vnd.ibm.afplinedata` = MimeType("application/vnd.ibm.afplinedata") - val `application/vnd.ibm.electronic-media` = MimeType("application/vnd.ibm.electronic-media") - val `application/vnd.ibm.minipay` = MimeType("application/vnd.ibm.minipay", "mpy") - val `application/vnd.ibm.modcap` = MimeType("application/vnd.ibm.modcap", "afp", "list3820", "listafp") - val `application/vnd.ibm.rights-management` = MimeType("application/vnd.ibm.rights-management", "irm") - val `application/vnd.ibm.secure-container` = MimeType("application/vnd.ibm.secure-container", "sc") - val `application/vnd.iccprofile` = MimeType("application/vnd.iccprofile", "icc", "icm") + val `application/vnd.hydrostatix.sof-data` = MimeType( + "application/vnd.hydrostatix.sof-data", "sfd", "-hdstx") + val `application/vnd.hzn-3d-crossword` = MimeType( + "application/vnd.hzn-3d-crossword", "x3d") + val `application/vnd.ibm.afplinedata` = MimeType( + "application/vnd.ibm.afplinedata") + val `application/vnd.ibm.electronic-media` = MimeType( + "application/vnd.ibm.electronic-media") + val `application/vnd.ibm.minipay` = MimeType( + "application/vnd.ibm.minipay", "mpy") + val `application/vnd.ibm.modcap` = MimeType( + "application/vnd.ibm.modcap", "afp", "list3820", "listafp") + val `application/vnd.ibm.rights-management` = MimeType( + "application/vnd.ibm.rights-management", "irm") + val `application/vnd.ibm.secure-container` = MimeType( + "application/vnd.ibm.secure-container", "sc") + val `application/vnd.iccprofile` = MimeType( + "application/vnd.iccprofile", "icc", "icm") val `application/vnd.igloader` = MimeType("application/vnd.igloader", "igl") - val `application/vnd.immervision-ivp` = MimeType("application/vnd.immervision-ivp", "ivp") - val `application/vnd.immervision-ivu` = MimeType("application/vnd.immervision-ivu", "ivu") - val `application/vnd.informedcontrol.rms+xml` = MimeType("application/vnd.informedcontrol.rms+xml") - val `application/vnd.informix-visionary` = MimeType("application/vnd.informix-visionary") - val `application/vnd.intercon.formnet` = MimeType("application/vnd.intercon.formnet", "xpw", "xpx") - val `application/vnd.intertrust.digibox` = MimeType("application/vnd.intertrust.digibox") - val `application/vnd.intertrust.nncp` = MimeType("application/vnd.intertrust.nncp") + val `application/vnd.immervision-ivp` = MimeType( + "application/vnd.immervision-ivp", "ivp") + val `application/vnd.immervision-ivu` = MimeType( + "application/vnd.immervision-ivu", "ivu") + val `application/vnd.informedcontrol.rms+xml` = MimeType( + "application/vnd.informedcontrol.rms+xml") + val `application/vnd.informix-visionary` = MimeType( + "application/vnd.informix-visionary") + val `application/vnd.intercon.formnet` = MimeType( + "application/vnd.intercon.formnet", "xpw", "xpx") + val `application/vnd.intertrust.digibox` = MimeType( + "application/vnd.intertrust.digibox") + val `application/vnd.intertrust.nncp` = MimeType( + "application/vnd.intertrust.nncp") val `application/vnd.intu.qbo` = MimeType("application/vnd.intu.qbo", "qbo") val `application/vnd.intu.qfx` = MimeType("application/vnd.intu.qfx", "qfx") - val `application/vnd.iptc.g2.conceptitem+xml` = MimeType("application/vnd.iptc.g2.conceptitem+xml") - val `application/vnd.iptc.g2.knowledgeitem+xml` = MimeType("application/vnd.iptc.g2.knowledgeitem+xml") - val `application/vnd.iptc.g2.newsitem+xml` = MimeType("application/vnd.iptc.g2.newsitem+xml") - val `application/vnd.iptc.g2.packageitem+xml` = MimeType("application/vnd.iptc.g2.packageitem+xml") - val `application/vnd.ipunplugged.rcprofile` = MimeType("application/vnd.ipunplugged.rcprofile", "rcprofile") - val `application/vnd.irepository.package+xml` = MimeType("application/vnd.irepository.package+xml", "irp") + val `application/vnd.iptc.g2.conceptitem+xml` = MimeType( + "application/vnd.iptc.g2.conceptitem+xml") + val `application/vnd.iptc.g2.knowledgeitem+xml` = MimeType( + "application/vnd.iptc.g2.knowledgeitem+xml") + val `application/vnd.iptc.g2.newsitem+xml` = MimeType( + "application/vnd.iptc.g2.newsitem+xml") + val `application/vnd.iptc.g2.packageitem+xml` = MimeType( + "application/vnd.iptc.g2.packageitem+xml") + val `application/vnd.ipunplugged.rcprofile` = MimeType( + "application/vnd.ipunplugged.rcprofile", "rcprofile") + val `application/vnd.irepository.package+xml` = MimeType( + "application/vnd.irepository.package+xml", "irp") val `application/vnd.is-xpr` = MimeType("application/vnd.is-xpr", "xpr") val `application/vnd.jam` = MimeType("application/vnd.jam", "jam") - val `application/vnd.japannet-directory-service` = MimeType("application/vnd.japannet-directory-service") - val `application/vnd.japannet-jpnstore-wakeup` = MimeType("application/vnd.japannet-jpnstore-wakeup") - val `application/vnd.japannet-payment-wakeup` = MimeType("application/vnd.japannet-payment-wakeup") - val `application/vnd.japannet-registration` = MimeType("application/vnd.japannet-registration") - val `application/vnd.japannet-registration-wakeup` = MimeType("application/vnd.japannet-registration-wakeup") - val `application/vnd.japannet-setstore-wakeup` = MimeType("application/vnd.japannet-setstore-wakeup") - val `application/vnd.japannet-verification` = MimeType("application/vnd.japannet-verification") - val `application/vnd.japannet-verification-wakeup` = MimeType("application/vnd.japannet-verification-wakeup") - val `application/vnd.jcp.javame.midlet-rms` = MimeType("application/vnd.jcp.javame.midlet-rms", "rms") + val `application/vnd.japannet-directory-service` = MimeType( + "application/vnd.japannet-directory-service") + val `application/vnd.japannet-jpnstore-wakeup` = MimeType( + "application/vnd.japannet-jpnstore-wakeup") + val `application/vnd.japannet-payment-wakeup` = MimeType( + "application/vnd.japannet-payment-wakeup") + val `application/vnd.japannet-registration` = MimeType( + "application/vnd.japannet-registration") + val `application/vnd.japannet-registration-wakeup` = MimeType( + "application/vnd.japannet-registration-wakeup") + val `application/vnd.japannet-setstore-wakeup` = MimeType( + "application/vnd.japannet-setstore-wakeup") + val `application/vnd.japannet-verification` = MimeType( + "application/vnd.japannet-verification") + val `application/vnd.japannet-verification-wakeup` = MimeType( + "application/vnd.japannet-verification-wakeup") + val `application/vnd.jcp.javame.midlet-rms` = MimeType( + "application/vnd.jcp.javame.midlet-rms", "rms") val `application/vnd.jisp` = MimeType("application/vnd.jisp", "jisp") - val `application/vnd.joost.joda-archive` = MimeType("application/vnd.joost.joda-archive", "joda") - val `application/vnd.kahootz` = MimeType("application/vnd.kahootz", "ktr", "ktz") - val `application/vnd.kde.karbon` = MimeType("application/vnd.kde.karbon", "karbon") - val `application/vnd.kde.kchart` = MimeType("application/vnd.kde.kchart", "chrt") - val `application/vnd.kde.kformula` = MimeType("application/vnd.kde.kformula", "kfo") - val `application/vnd.kde.kivio` = MimeType("application/vnd.kde.kivio", "flw") - val `application/vnd.kde.kontour` = MimeType("application/vnd.kde.kontour", "kon") - val `application/vnd.kde.kpresenter` = MimeType("application/vnd.kde.kpresenter", "kpr", "kpt") - val `application/vnd.kde.kspread` = MimeType("application/vnd.kde.kspread", "ksp") - val `application/vnd.kde.kword` = MimeType("application/vnd.kde.kword", "kwd", "kwt") - val `application/vnd.kenameaapp` = MimeType("application/vnd.kenameaapp", "htke") - val `application/vnd.kidspiration` = MimeType("application/vnd.kidspiration", "kia") + val `application/vnd.joost.joda-archive` = MimeType( + "application/vnd.joost.joda-archive", "joda") + val `application/vnd.kahootz` = MimeType( + "application/vnd.kahootz", "ktr", "ktz") + val `application/vnd.kde.karbon` = MimeType( + "application/vnd.kde.karbon", "karbon") + val `application/vnd.kde.kchart` = MimeType( + "application/vnd.kde.kchart", "chrt") + val `application/vnd.kde.kformula` = MimeType( + "application/vnd.kde.kformula", "kfo") + val `application/vnd.kde.kivio` = MimeType( + "application/vnd.kde.kivio", "flw") + val `application/vnd.kde.kontour` = MimeType( + "application/vnd.kde.kontour", "kon") + val `application/vnd.kde.kpresenter` = MimeType( + "application/vnd.kde.kpresenter", "kpr", "kpt") + val `application/vnd.kde.kspread` = MimeType( + "application/vnd.kde.kspread", "ksp") + val `application/vnd.kde.kword` = MimeType( + "application/vnd.kde.kword", "kwd", "kwt") + val `application/vnd.kenameaapp` = MimeType( + "application/vnd.kenameaapp", "htke") + val `application/vnd.kidspiration` = MimeType( + "application/vnd.kidspiration", "kia") val `application/vnd.kinar` = MimeType("application/vnd.kinar", "kne", "knp") - val `application/vnd.koan` = MimeType("application/vnd.koan", "skd", "skm", "skp", "skt") - val `application/vnd.kodak-descriptor` = MimeType("application/vnd.kodak-descriptor", "sse") - val `application/vnd.liberty-request+xml` = MimeType("application/vnd.liberty-request+xml") - - val `application/vnd.llamagraphics.life-balance.desktop` = - MimeType("application/vnd.llamagraphics.life-balance.desktop", "lbd") - - val `application/vnd.llamagraphics.life-balance.exchange+xml` = - MimeType("application/vnd.llamagraphics.life-balance.exchange+xml", "lbe") - - val `application/vnd.lotus-1-2-3` = MimeType("application/vnd.lotus-1-2-3", "123") - val `application/vnd.lotus-approach` = MimeType("application/vnd.lotus-approach", "apr") - val `application/vnd.lotus-freelance` = MimeType("application/vnd.lotus-freelance", "pre") - val `application/vnd.lotus-notes` = MimeType("application/vnd.lotus-notes", "nsf") - val `application/vnd.lotus-organizer` = MimeType("application/vnd.lotus-organizer", "org") - val `application/vnd.lotus-screencam` = MimeType("application/vnd.lotus-screencam", "scm") - val `application/vnd.lotus-wordpro` = MimeType("application/vnd.lotus-wordpro", "lwp") - val `application/vnd.macports.portpkg` = MimeType("application/vnd.macports.portpkg", "portpkg") - val `application/vnd.marlin.drm.actiontoken+xml` = MimeType("application/vnd.marlin.drm.actiontoken+xml") - val `application/vnd.marlin.drm.conftoken+xml` = MimeType("application/vnd.marlin.drm.conftoken+xml") - val `application/vnd.marlin.drm.license+xml` = MimeType("application/vnd.marlin.drm.license+xml") - val `application/vnd.marlin.drm.mdcf` = MimeType("application/vnd.marlin.drm.mdcf") + val `application/vnd.koan` = MimeType( + "application/vnd.koan", "skd", "skm", "skp", "skt") + val `application/vnd.kodak-descriptor` = MimeType( + "application/vnd.kodak-descriptor", "sse") + val `application/vnd.liberty-request+xml` = MimeType( + "application/vnd.liberty-request+xml") + + val `application/vnd.llamagraphics.life-balance.desktop` = MimeType( + "application/vnd.llamagraphics.life-balance.desktop", "lbd") + + val `application/vnd.llamagraphics.life-balance.exchange+xml` = MimeType( + "application/vnd.llamagraphics.life-balance.exchange+xml", "lbe") + + val `application/vnd.lotus-1-2-3` = MimeType( + "application/vnd.lotus-1-2-3", "123") + val `application/vnd.lotus-approach` = MimeType( + "application/vnd.lotus-approach", "apr") + val `application/vnd.lotus-freelance` = MimeType( + "application/vnd.lotus-freelance", "pre") + val `application/vnd.lotus-notes` = MimeType( + "application/vnd.lotus-notes", "nsf") + val `application/vnd.lotus-organizer` = MimeType( + "application/vnd.lotus-organizer", "org") + val `application/vnd.lotus-screencam` = MimeType( + "application/vnd.lotus-screencam", "scm") + val `application/vnd.lotus-wordpro` = MimeType( + "application/vnd.lotus-wordpro", "lwp") + val `application/vnd.macports.portpkg` = MimeType( + "application/vnd.macports.portpkg", "portpkg") + val `application/vnd.marlin.drm.actiontoken+xml` = MimeType( + "application/vnd.marlin.drm.actiontoken+xml") + val `application/vnd.marlin.drm.conftoken+xml` = MimeType( + "application/vnd.marlin.drm.conftoken+xml") + val `application/vnd.marlin.drm.license+xml` = MimeType( + "application/vnd.marlin.drm.license+xml") + val `application/vnd.marlin.drm.mdcf` = MimeType( + "application/vnd.marlin.drm.mdcf") val `application/vnd.mcd` = MimeType("application/vnd.mcd", "mcd") - val `application/vnd.medcalcdata` = MimeType("application/vnd.medcalcdata", "mc1") - val `application/vnd.mediastation.cdkey` = MimeType("application/vnd.mediastation.cdkey", "cdkey") - val `application/vnd.meridian-slingshot` = MimeType("application/vnd.meridian-slingshot") + val `application/vnd.medcalcdata` = MimeType( + "application/vnd.medcalcdata", "mc1") + val `application/vnd.mediastation.cdkey` = MimeType( + "application/vnd.mediastation.cdkey", "cdkey") + val `application/vnd.meridian-slingshot` = MimeType( + "application/vnd.meridian-slingshot") val `application/vnd.mfer` = MimeType("application/vnd.mfer", "mwf") val `application/vnd.mfmp` = MimeType("application/vnd.mfmp", "mfm") - val `application/vnd.micrografx.flo` = MimeType("application/vnd.micrografx.flo", "flo") - val `application/vnd.micrografx.igx` = MimeType("application/vnd.micrografx.igx", "igx") + val `application/vnd.micrografx.flo` = MimeType( + "application/vnd.micrografx.flo", "flo") + val `application/vnd.micrografx.igx` = MimeType( + "application/vnd.micrografx.igx", "igx") val `application/vnd.mif` = MimeType("application/vnd.mif", "mif") - val `application/vnd.minisoft-hp3000-save` = MimeType("application/vnd.minisoft-hp3000-save") - - val `application/vnd.mitsubishi.misty-guard.trustweb` = - MimeType("application/vnd.mitsubishi.misty-guard.trustweb") - - val `application/vnd.mobius.daf` = MimeType("application/vnd.mobius.daf", "daf") - val `application/vnd.mobius.dis` = MimeType("application/vnd.mobius.dis", "dis") - val `application/vnd.mobius.mbk` = MimeType("application/vnd.mobius.mbk", "mbk") - val `application/vnd.mobius.mqy` = MimeType("application/vnd.mobius.mqy", "mqy") - val `application/vnd.mobius.msl` = MimeType("application/vnd.mobius.msl", "msl") - val `application/vnd.mobius.plc` = MimeType("application/vnd.mobius.plc", "plc") - val `application/vnd.mobius.txf` = MimeType("application/vnd.mobius.txf", "txf") - val `application/vnd.mophun.application` = MimeType("application/vnd.mophun.application", "mpn") - val `application/vnd.mophun.certificate` = MimeType("application/vnd.mophun.certificate", "mpc") - val `application/vnd.motorola.flexsuite` = MimeType("application/vnd.motorola.flexsuite") - val `application/vnd.motorola.flexsuite.adsi` = MimeType("application/vnd.motorola.flexsuite.adsi") - val `application/vnd.motorola.flexsuite.fis` = MimeType("application/vnd.motorola.flexsuite.fis") - val `application/vnd.motorola.flexsuite.gotap` = MimeType("application/vnd.motorola.flexsuite.gotap") - val `application/vnd.motorola.flexsuite.kmr` = MimeType("application/vnd.motorola.flexsuite.kmr") - val `application/vnd.motorola.flexsuite.ttc` = MimeType("application/vnd.motorola.flexsuite.ttc") - val `application/vnd.motorola.flexsuite.wem` = MimeType("application/vnd.motorola.flexsuite.wem") - val `application/vnd.motorola.iprm` = MimeType("application/vnd.motorola.iprm") - val `application/vnd.mozilla.xul+xml` = MimeType("application/vnd.mozilla.xul+xml", "xul") - val `application/vnd.ms-artgalry` = MimeType("application/vnd.ms-artgalry", "cil") + val `application/vnd.minisoft-hp3000-save` = MimeType( + "application/vnd.minisoft-hp3000-save") + + val `application/vnd.mitsubishi.misty-guard.trustweb` = MimeType( + "application/vnd.mitsubishi.misty-guard.trustweb") + + val `application/vnd.mobius.daf` = MimeType( + "application/vnd.mobius.daf", "daf") + val `application/vnd.mobius.dis` = MimeType( + "application/vnd.mobius.dis", "dis") + val `application/vnd.mobius.mbk` = MimeType( + "application/vnd.mobius.mbk", "mbk") + val `application/vnd.mobius.mqy` = MimeType( + "application/vnd.mobius.mqy", "mqy") + val `application/vnd.mobius.msl` = MimeType( + "application/vnd.mobius.msl", "msl") + val `application/vnd.mobius.plc` = MimeType( + "application/vnd.mobius.plc", "plc") + val `application/vnd.mobius.txf` = MimeType( + "application/vnd.mobius.txf", "txf") + val `application/vnd.mophun.application` = MimeType( + "application/vnd.mophun.application", "mpn") + val `application/vnd.mophun.certificate` = MimeType( + "application/vnd.mophun.certificate", "mpc") + val `application/vnd.motorola.flexsuite` = MimeType( + "application/vnd.motorola.flexsuite") + val `application/vnd.motorola.flexsuite.adsi` = MimeType( + "application/vnd.motorola.flexsuite.adsi") + val `application/vnd.motorola.flexsuite.fis` = MimeType( + "application/vnd.motorola.flexsuite.fis") + val `application/vnd.motorola.flexsuite.gotap` = MimeType( + "application/vnd.motorola.flexsuite.gotap") + val `application/vnd.motorola.flexsuite.kmr` = MimeType( + "application/vnd.motorola.flexsuite.kmr") + val `application/vnd.motorola.flexsuite.ttc` = MimeType( + "application/vnd.motorola.flexsuite.ttc") + val `application/vnd.motorola.flexsuite.wem` = MimeType( + "application/vnd.motorola.flexsuite.wem") + val `application/vnd.motorola.iprm` = MimeType( + "application/vnd.motorola.iprm") + val `application/vnd.mozilla.xul+xml` = MimeType( + "application/vnd.mozilla.xul+xml", "xul") + val `application/vnd.ms-artgalry` = MimeType( + "application/vnd.ms-artgalry", "cil") val `application/vnd.ms-asf` = MimeType("application/vnd.ms-asf") - val `application/vnd.ms-cab-compressed` = MimeType("application/vnd.ms-cab-compressed", "cab") - - val `application/vnd.ms-excel` = - MimeType("application/vnd.ms-excel", "xla", "xlb", "xlc", "xlm", "xls", "xlt", "xlw") - - val `application/vnd.ms-excel.addin.macroenabled.12` = - MimeType("application/vnd.ms-excel.addin.macroenabled.12", "xlam") - - val `application/vnd.ms-excel.sheet.binary.macroenabled.12` = - MimeType("application/vnd.ms-excel.sheet.binary.macroenabled.12", "xlsb") - - val `application/vnd.ms-excel.sheet.macroenabled.12` = - MimeType("application/vnd.ms-excel.sheet.macroenabled.12", "xlsm") - - val `application/vnd.ms-excel.template.macroenabled.12` = - MimeType("application/vnd.ms-excel.template.macroenabled.12", "xltm") - - val `application/vnd.ms-fontobject` = MimeType("application/vnd.ms-fontobject", "eot") - val `application/vnd.ms-htmlhelp` = MimeType("application/vnd.ms-htmlhelp", "chm") + val `application/vnd.ms-cab-compressed` = MimeType( + "application/vnd.ms-cab-compressed", "cab") + + val `application/vnd.ms-excel` = MimeType("application/vnd.ms-excel", + "xla", + "xlb", + "xlc", + "xlm", + "xls", + "xlt", + "xlw") + + val `application/vnd.ms-excel.addin.macroenabled.12` = MimeType( + "application/vnd.ms-excel.addin.macroenabled.12", "xlam") + + val `application/vnd.ms-excel.sheet.binary.macroenabled.12` = MimeType( + "application/vnd.ms-excel.sheet.binary.macroenabled.12", "xlsb") + + val `application/vnd.ms-excel.sheet.macroenabled.12` = MimeType( + "application/vnd.ms-excel.sheet.macroenabled.12", "xlsm") + + val `application/vnd.ms-excel.template.macroenabled.12` = MimeType( + "application/vnd.ms-excel.template.macroenabled.12", "xltm") + + val `application/vnd.ms-fontobject` = MimeType( + "application/vnd.ms-fontobject", "eot") + val `application/vnd.ms-htmlhelp` = MimeType( + "application/vnd.ms-htmlhelp", "chm") val `application/vnd.ms-ims` = MimeType("application/vnd.ms-ims", "ims") val `application/vnd.ms-lrm` = MimeType("application/vnd.ms-lrm", "lrm") - val `application/vnd.ms-pki.seccat` = MimeType("application/vnd.ms-pki.seccat", "cat") - val `application/vnd.ms-pki.stl` = MimeType("application/vnd.ms-pki.stl", "stl") - val `application/vnd.ms-playready.initiator+xml` = MimeType("application/vnd.ms-playready.initiator+xml") - val `application/vnd.ms-powerpoint` = MimeType("application/vnd.ms-powerpoint", "pot", "pps", "ppt") - - val `application/vnd.ms-powerpoint.addin.macroenabled.12` = - MimeType("application/vnd.ms-powerpoint.addin.macroenabled.12", "ppam") - - val `application/vnd.ms-powerpoint.presentation.macroenabled.12` = - MimeType("application/vnd.ms-powerpoint.presentation.macroenabled.12", "pptm") - - val `application/vnd.ms-powerpoint.slide.macroenabled.12` = - MimeType("application/vnd.ms-powerpoint.slide.macroenabled.12", "sldm") - - val `application/vnd.ms-powerpoint.slideshow.macroenabled.12` = - MimeType("application/vnd.ms-powerpoint.slideshow.macroenabled.12", "ppsm") - - val `application/vnd.ms-powerpoint.template.macroenabled.12` = - MimeType("application/vnd.ms-powerpoint.template.macroenabled.12", "potm") - - val `application/vnd.ms-project` = MimeType("application/vnd.ms-project", "mpp", "mpt") + val `application/vnd.ms-pki.seccat` = MimeType( + "application/vnd.ms-pki.seccat", "cat") + val `application/vnd.ms-pki.stl` = MimeType( + "application/vnd.ms-pki.stl", "stl") + val `application/vnd.ms-playready.initiator+xml` = MimeType( + "application/vnd.ms-playready.initiator+xml") + val `application/vnd.ms-powerpoint` = MimeType( + "application/vnd.ms-powerpoint", "pot", "pps", "ppt") + + val `application/vnd.ms-powerpoint.addin.macroenabled.12` = MimeType( + "application/vnd.ms-powerpoint.addin.macroenabled.12", "ppam") + + val `application/vnd.ms-powerpoint.presentation.macroenabled.12` = MimeType( + "application/vnd.ms-powerpoint.presentation.macroenabled.12", "pptm") + + val `application/vnd.ms-powerpoint.slide.macroenabled.12` = MimeType( + "application/vnd.ms-powerpoint.slide.macroenabled.12", "sldm") + + val `application/vnd.ms-powerpoint.slideshow.macroenabled.12` = MimeType( + "application/vnd.ms-powerpoint.slideshow.macroenabled.12", "ppsm") + + val `application/vnd.ms-powerpoint.template.macroenabled.12` = MimeType( + "application/vnd.ms-powerpoint.template.macroenabled.12", "potm") + + val `application/vnd.ms-project` = MimeType( + "application/vnd.ms-project", "mpp", "mpt") val `application/vnd.ms-tnef` = MimeType("application/vnd.ms-tnef") - val `application/vnd.ms-wmdrm.lic-chlg-req` = MimeType("application/vnd.ms-wmdrm.lic-chlg-req") - val `application/vnd.ms-wmdrm.lic-resp` = MimeType("application/vnd.ms-wmdrm.lic-resp") - val `application/vnd.ms-wmdrm.meter-chlg-req` = MimeType("application/vnd.ms-wmdrm.meter-chlg-req") - val `application/vnd.ms-wmdrm.meter-resp` = MimeType("application/vnd.ms-wmdrm.meter-resp") - - val `application/vnd.ms-word.document.macroenabled.12` = - MimeType("application/vnd.ms-word.document.macroenabled.12", "docm") - - val `application/vnd.ms-word.template.macroenabled.12` = - MimeType("application/vnd.ms-word.template.macroenabled.12", "dotm") + val `application/vnd.ms-wmdrm.lic-chlg-req` = MimeType( + "application/vnd.ms-wmdrm.lic-chlg-req") + val `application/vnd.ms-wmdrm.lic-resp` = MimeType( + "application/vnd.ms-wmdrm.lic-resp") + val `application/vnd.ms-wmdrm.meter-chlg-req` = MimeType( + "application/vnd.ms-wmdrm.meter-chlg-req") + val `application/vnd.ms-wmdrm.meter-resp` = MimeType( + "application/vnd.ms-wmdrm.meter-resp") + + val `application/vnd.ms-word.document.macroenabled.12` = MimeType( + "application/vnd.ms-word.document.macroenabled.12", "docm") + + val `application/vnd.ms-word.template.macroenabled.12` = MimeType( + "application/vnd.ms-word.template.macroenabled.12", "dotm") - val `application/vnd.ms-works` = MimeType("application/vnd.ms-works", "wcm", "wdb", "wks", "wps") + val `application/vnd.ms-works` = MimeType( + "application/vnd.ms-works", "wcm", "wdb", "wks", "wps") val `application/vnd.ms-wpl` = MimeType("application/vnd.ms-wpl", "wpl") - val `application/vnd.ms-xpsdocument` = MimeType("application/vnd.ms-xpsdocument", "xps") + val `application/vnd.ms-xpsdocument` = MimeType( + "application/vnd.ms-xpsdocument", "xps") val `application/vnd.mseq` = MimeType("application/vnd.mseq", "mseq") val `application/vnd.msign` = MimeType("application/vnd.msign") - val `application/vnd.multiad.creator` = MimeType("application/vnd.multiad.creator") - val `application/vnd.multiad.creator.cif` = MimeType("application/vnd.multiad.creator.cif") + val `application/vnd.multiad.creator` = MimeType( + "application/vnd.multiad.creator") + val `application/vnd.multiad.creator.cif` = MimeType( + "application/vnd.multiad.creator.cif") val `application/vnd.music-niff` = MimeType("application/vnd.music-niff") val `application/vnd.musician` = MimeType("application/vnd.musician", "mus") - val `application/vnd.muvee.style` = MimeType("application/vnd.muvee.style", "msty") + val `application/vnd.muvee.style` = MimeType( + "application/vnd.muvee.style", "msty") val `application/vnd.ncd.control` = MimeType("application/vnd.ncd.control") - val `application/vnd.ncd.reference` = MimeType("application/vnd.ncd.reference") + val `application/vnd.ncd.reference` = MimeType( + "application/vnd.ncd.reference") val `application/vnd.nervana` = MimeType("application/vnd.nervana") val `application/vnd.netfpx` = MimeType("application/vnd.netfpx") - val `application/vnd.neurolanguage.nlu` = MimeType("application/vnd.neurolanguage.nlu", "nlu") - val `application/vnd.noblenet-directory` = MimeType("application/vnd.noblenet-directory", "nnd") - val `application/vnd.noblenet-sealer` = MimeType("application/vnd.noblenet-sealer", "nns") - val `application/vnd.noblenet-web` = MimeType("application/vnd.noblenet-web", "nnw") - val `application/vnd.nokia.catalogs` = MimeType("application/vnd.nokia.catalogs") - val `application/vnd.nokia.conml+wbxml` = MimeType("application/vnd.nokia.conml+wbxml") - val `application/vnd.nokia.conml+xml` = MimeType("application/vnd.nokia.conml+xml") - val `application/vnd.nokia.iptv.config+xml` = MimeType("application/vnd.nokia.iptv.config+xml") - val `application/vnd.nokia.isds-radio-presets` = MimeType("application/vnd.nokia.isds-radio-presets") - val `application/vnd.nokia.landmark+wbxml` = MimeType("application/vnd.nokia.landmark+wbxml") - val `application/vnd.nokia.landmark+xml` = MimeType("application/vnd.nokia.landmark+xml") - val `application/vnd.nokia.landmarkcollection+xml` = MimeType("application/vnd.nokia.landmarkcollection+xml") - val `application/vnd.nokia.n-gage.ac+xml` = MimeType("application/vnd.nokia.n-gage.ac+xml") - val `application/vnd.nokia.n-gage.data` = MimeType("application/vnd.nokia.n-gage.data", "ngdat") - - val `application/vnd.nokia.n-gage.symbian.install` = - MimeType("application/vnd.nokia.n-gage.symbian.install", "n", "-gage") - + val `application/vnd.neurolanguage.nlu` = MimeType( + "application/vnd.neurolanguage.nlu", "nlu") + val `application/vnd.noblenet-directory` = MimeType( + "application/vnd.noblenet-directory", "nnd") + val `application/vnd.noblenet-sealer` = MimeType( + "application/vnd.noblenet-sealer", "nns") + val `application/vnd.noblenet-web` = MimeType( + "application/vnd.noblenet-web", "nnw") + val `application/vnd.nokia.catalogs` = MimeType( + "application/vnd.nokia.catalogs") + val `application/vnd.nokia.conml+wbxml` = MimeType( + "application/vnd.nokia.conml+wbxml") + val `application/vnd.nokia.conml+xml` = MimeType( + "application/vnd.nokia.conml+xml") + val `application/vnd.nokia.iptv.config+xml` = MimeType( + "application/vnd.nokia.iptv.config+xml") + val `application/vnd.nokia.isds-radio-presets` = MimeType( + "application/vnd.nokia.isds-radio-presets") + val `application/vnd.nokia.landmark+wbxml` = MimeType( + "application/vnd.nokia.landmark+wbxml") + val `application/vnd.nokia.landmark+xml` = MimeType( + "application/vnd.nokia.landmark+xml") + val `application/vnd.nokia.landmarkcollection+xml` = MimeType( + "application/vnd.nokia.landmarkcollection+xml") + val `application/vnd.nokia.n-gage.ac+xml` = MimeType( + "application/vnd.nokia.n-gage.ac+xml") + val `application/vnd.nokia.n-gage.data` = MimeType( + "application/vnd.nokia.n-gage.data", "ngdat") + + val `application/vnd.nokia.n-gage.symbian.install` = MimeType( + "application/vnd.nokia.n-gage.symbian.install", "n", "-gage") + val `application/vnd.nokia.ncd` = MimeType("application/vnd.nokia.ncd") - val `application/vnd.nokia.pcd+wbxml` = MimeType("application/vnd.nokia.pcd+wbxml") - val `application/vnd.nokia.pcd+xml` = MimeType("application/vnd.nokia.pcd+xml") - val `application/vnd.nokia.radio-preset` = MimeType("application/vnd.nokia.radio-preset", "rpst") - val `application/vnd.nokia.radio-presets` = MimeType("application/vnd.nokia.radio-presets", "rpss") - val `application/vnd.novadigm.edm` = MimeType("application/vnd.novadigm.edm", "edm") - val `application/vnd.novadigm.edx` = MimeType("application/vnd.novadigm.edx", "edx") - val `application/vnd.novadigm.ext` = MimeType("application/vnd.novadigm.ext", "ext") - val `application/vnd.oasis.opendocument.chart` = MimeType("application/vnd.oasis.opendocument.chart", "odc") - - val `application/vnd.oasis.opendocument.chart-template` = - MimeType("application/vnd.oasis.opendocument.chart-template", "otc") - - val `application/vnd.oasis.opendocument.database` = MimeType("application/vnd.oasis.opendocument.database", "odb") - val `application/vnd.oasis.opendocument.formula` = MimeType("application/vnd.oasis.opendocument.formula", "odf") - - val `application/vnd.oasis.opendocument.formula-template` = - MimeType("application/vnd.oasis.opendocument.formula-template", "odft") - - val `application/vnd.oasis.opendocument.graphics` = MimeType("application/vnd.oasis.opendocument.graphics", "odg") - - val `application/vnd.oasis.opendocument.graphics-template` = - MimeType("application/vnd.oasis.opendocument.graphics-template", "otg") - - val `application/vnd.oasis.opendocument.image` = MimeType("application/vnd.oasis.opendocument.image", "odi") - - val `application/vnd.oasis.opendocument.image-template` = - MimeType("application/vnd.oasis.opendocument.image-template", "oti") - - val `application/vnd.oasis.opendocument.presentation` = - MimeType("application/vnd.oasis.opendocument.presentation", "odp") - - val `application/vnd.oasis.opendocument.presentation-template` = - MimeType("application/vnd.oasis.opendocument.presentation-template", "otp") - - val `application/vnd.oasis.opendocument.spreadsheet` = - MimeType("application/vnd.oasis.opendocument.spreadsheet", "ods") - - val `application/vnd.oasis.opendocument.spreadsheet-template` = - MimeType("application/vnd.oasis.opendocument.spreadsheet-template", "ots") - - val `application/vnd.oasis.opendocument.text` = MimeType("application/vnd.oasis.opendocument.text", "odt") - - val `application/vnd.oasis.opendocument.text-master` = - MimeType("application/vnd.oasis.opendocument.text-master", "odm", "otm") - - val `application/vnd.oasis.opendocument.text-template` = - MimeType("application/vnd.oasis.opendocument.text-template", "ott") - - val `application/vnd.oasis.opendocument.text-web` = MimeType("application/vnd.oasis.opendocument.text-web", "oth") + val `application/vnd.nokia.pcd+wbxml` = MimeType( + "application/vnd.nokia.pcd+wbxml") + val `application/vnd.nokia.pcd+xml` = MimeType( + "application/vnd.nokia.pcd+xml") + val `application/vnd.nokia.radio-preset` = MimeType( + "application/vnd.nokia.radio-preset", "rpst") + val `application/vnd.nokia.radio-presets` = MimeType( + "application/vnd.nokia.radio-presets", "rpss") + val `application/vnd.novadigm.edm` = MimeType( + "application/vnd.novadigm.edm", "edm") + val `application/vnd.novadigm.edx` = MimeType( + "application/vnd.novadigm.edx", "edx") + val `application/vnd.novadigm.ext` = MimeType( + "application/vnd.novadigm.ext", "ext") + val `application/vnd.oasis.opendocument.chart` = MimeType( + "application/vnd.oasis.opendocument.chart", "odc") + + val `application/vnd.oasis.opendocument.chart-template` = MimeType( + "application/vnd.oasis.opendocument.chart-template", "otc") + + val `application/vnd.oasis.opendocument.database` = MimeType( + "application/vnd.oasis.opendocument.database", "odb") + val `application/vnd.oasis.opendocument.formula` = MimeType( + "application/vnd.oasis.opendocument.formula", "odf") + + val `application/vnd.oasis.opendocument.formula-template` = MimeType( + "application/vnd.oasis.opendocument.formula-template", "odft") + + val `application/vnd.oasis.opendocument.graphics` = MimeType( + "application/vnd.oasis.opendocument.graphics", "odg") + + val `application/vnd.oasis.opendocument.graphics-template` = MimeType( + "application/vnd.oasis.opendocument.graphics-template", "otg") + + val `application/vnd.oasis.opendocument.image` = MimeType( + "application/vnd.oasis.opendocument.image", "odi") + + val `application/vnd.oasis.opendocument.image-template` = MimeType( + "application/vnd.oasis.opendocument.image-template", "oti") + + val `application/vnd.oasis.opendocument.presentation` = MimeType( + "application/vnd.oasis.opendocument.presentation", "odp") + + val `application/vnd.oasis.opendocument.presentation-template` = MimeType( + "application/vnd.oasis.opendocument.presentation-template", "otp") + + val `application/vnd.oasis.opendocument.spreadsheet` = MimeType( + "application/vnd.oasis.opendocument.spreadsheet", "ods") + + val `application/vnd.oasis.opendocument.spreadsheet-template` = MimeType( + "application/vnd.oasis.opendocument.spreadsheet-template", "ots") + + val `application/vnd.oasis.opendocument.text` = MimeType( + "application/vnd.oasis.opendocument.text", "odt") + + val `application/vnd.oasis.opendocument.text-master` = MimeType( + "application/vnd.oasis.opendocument.text-master", "odm", "otm") + + val `application/vnd.oasis.opendocument.text-template` = MimeType( + "application/vnd.oasis.opendocument.text-template", "ott") + + val `application/vnd.oasis.opendocument.text-web` = MimeType( + "application/vnd.oasis.opendocument.text-web", "oth") val `application/vnd.obn` = MimeType("application/vnd.obn") - val `application/vnd.olpc-sugar` = MimeType("application/vnd.olpc-sugar", "xo") - val `application/vnd.oma-scws-config` = MimeType("application/vnd.oma-scws-config") - val `application/vnd.oma-scws-http-request` = MimeType("application/vnd.oma-scws-http-request") - val `application/vnd.oma-scws-http-response` = MimeType("application/vnd.oma-scws-http-response") + val `application/vnd.olpc-sugar` = MimeType( + "application/vnd.olpc-sugar", "xo") + val `application/vnd.oma-scws-config` = MimeType( + "application/vnd.oma-scws-config") + val `application/vnd.oma-scws-http-request` = MimeType( + "application/vnd.oma-scws-http-request") + val `application/vnd.oma-scws-http-response` = MimeType( + "application/vnd.oma-scws-http-response") val `application/vnd.oma.bcast.associated-procedure-parameter+xml` = MimeType("application/vnd.oma.bcast.associated-procedure-parameter+xml") - - val `application/vnd.oma.bcast.drm-trigger+xml` = MimeType("application/vnd.oma.bcast.drm-trigger+xml") - val `application/vnd.oma.bcast.imd+xml` = MimeType("application/vnd.oma.bcast.imd+xml") - val `application/vnd.oma.bcast.ltkm` = MimeType("application/vnd.oma.bcast.ltkm") - val `application/vnd.oma.bcast.notification+xml` = MimeType("application/vnd.oma.bcast.notification+xml") - val `application/vnd.oma.bcast.provisioningtrigger` = MimeType("application/vnd.oma.bcast.provisioningtrigger") - val `application/vnd.oma.bcast.sgboot` = MimeType("application/vnd.oma.bcast.sgboot") - val `application/vnd.oma.bcast.sgdd+xml` = MimeType("application/vnd.oma.bcast.sgdd+xml") - val `application/vnd.oma.bcast.sgdu` = MimeType("application/vnd.oma.bcast.sgdu") - - val `application/vnd.oma.bcast.simple-symbol-container` = - MimeType("application/vnd.oma.bcast.simple-symbol-container") - - val `application/vnd.oma.bcast.smartcard-trigger+xml` = - MimeType("application/vnd.oma.bcast.smartcard-trigger+xml") - - val `application/vnd.oma.bcast.sprov+xml` = MimeType("application/vnd.oma.bcast.sprov+xml") - val `application/vnd.oma.bcast.stkm` = MimeType("application/vnd.oma.bcast.stkm") + + val `application/vnd.oma.bcast.drm-trigger+xml` = MimeType( + "application/vnd.oma.bcast.drm-trigger+xml") + val `application/vnd.oma.bcast.imd+xml` = MimeType( + "application/vnd.oma.bcast.imd+xml") + val `application/vnd.oma.bcast.ltkm` = MimeType( + "application/vnd.oma.bcast.ltkm") + val `application/vnd.oma.bcast.notification+xml` = MimeType( + "application/vnd.oma.bcast.notification+xml") + val `application/vnd.oma.bcast.provisioningtrigger` = MimeType( + "application/vnd.oma.bcast.provisioningtrigger") + val `application/vnd.oma.bcast.sgboot` = MimeType( + "application/vnd.oma.bcast.sgboot") + val `application/vnd.oma.bcast.sgdd+xml` = MimeType( + "application/vnd.oma.bcast.sgdd+xml") + val `application/vnd.oma.bcast.sgdu` = MimeType( + "application/vnd.oma.bcast.sgdu") + + val `application/vnd.oma.bcast.simple-symbol-container` = MimeType( + "application/vnd.oma.bcast.simple-symbol-container") + + val `application/vnd.oma.bcast.smartcard-trigger+xml` = MimeType( + "application/vnd.oma.bcast.smartcard-trigger+xml") + + val `application/vnd.oma.bcast.sprov+xml` = MimeType( + "application/vnd.oma.bcast.sprov+xml") + val `application/vnd.oma.bcast.stkm` = MimeType( + "application/vnd.oma.bcast.stkm") val `application/vnd.oma.dcd` = MimeType("application/vnd.oma.dcd") val `application/vnd.oma.dcdc` = MimeType("application/vnd.oma.dcdc") - val `application/vnd.oma.dd2+xml` = MimeType("application/vnd.oma.dd2+xml", "dd2") - val `application/vnd.oma.drm.risd+xml` = MimeType("application/vnd.oma.drm.risd+xml") - val `application/vnd.oma.group-usage-list+xml` = MimeType("application/vnd.oma.group-usage-list+xml") - - val `application/vnd.oma.poc.detailed-progress-report+xml` = - MimeType("application/vnd.oma.poc.detailed-progress-report+xml") - - val `application/vnd.oma.poc.final-report+xml` = MimeType("application/vnd.oma.poc.final-report+xml") - val `application/vnd.oma.poc.groups+xml` = MimeType("application/vnd.oma.poc.groups+xml") - - val `application/vnd.oma.poc.invocation-descriptor+xml` = - MimeType("application/vnd.oma.poc.invocation-descriptor+xml") - - val `application/vnd.oma.poc.optimized-progress-report+xml` = - MimeType("application/vnd.oma.poc.optimized-progress-report+xml") - - val `application/vnd.oma.xcap-directory+xml` = MimeType("application/vnd.oma.xcap-directory+xml") - val `application/vnd.omads-email+xml` = MimeType("application/vnd.omads-email+xml") - val `application/vnd.omads-file+xml` = MimeType("application/vnd.omads-file+xml") - val `application/vnd.omads-folder+xml` = MimeType("application/vnd.omads-folder+xml") - val `application/vnd.omaloc-supl-init` = MimeType("application/vnd.omaloc-supl-init") - val `application/vnd.openofficeorg.extension` = MimeType("application/vnd.openofficeorg.extension", "oxt") - + val `application/vnd.oma.dd2+xml` = MimeType( + "application/vnd.oma.dd2+xml", "dd2") + val `application/vnd.oma.drm.risd+xml` = MimeType( + "application/vnd.oma.drm.risd+xml") + val `application/vnd.oma.group-usage-list+xml` = MimeType( + "application/vnd.oma.group-usage-list+xml") + + val `application/vnd.oma.poc.detailed-progress-report+xml` = MimeType( + "application/vnd.oma.poc.detailed-progress-report+xml") + + val `application/vnd.oma.poc.final-report+xml` = MimeType( + "application/vnd.oma.poc.final-report+xml") + val `application/vnd.oma.poc.groups+xml` = MimeType( + "application/vnd.oma.poc.groups+xml") + + val `application/vnd.oma.poc.invocation-descriptor+xml` = MimeType( + "application/vnd.oma.poc.invocation-descriptor+xml") + + val `application/vnd.oma.poc.optimized-progress-report+xml` = MimeType( + "application/vnd.oma.poc.optimized-progress-report+xml") + + val `application/vnd.oma.xcap-directory+xml` = MimeType( + "application/vnd.oma.xcap-directory+xml") + val `application/vnd.omads-email+xml` = MimeType( + "application/vnd.omads-email+xml") + val `application/vnd.omads-file+xml` = MimeType( + "application/vnd.omads-file+xml") + val `application/vnd.omads-folder+xml` = MimeType( + "application/vnd.omads-folder+xml") + val `application/vnd.omaloc-supl-init` = MimeType( + "application/vnd.omaloc-supl-init") + val `application/vnd.openofficeorg.extension` = MimeType( + "application/vnd.openofficeorg.extension", "oxt") + val `application/vnd.openxmlformats-officedocument.presentationml.presentation` = - MimeType("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx") - + MimeType( + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "pptx") + val `application/vnd.openxmlformats-officedocument.presentationml.slide` = - MimeType("application/vnd.openxmlformats-officedocument.presentationml.slide", "sldx") - + MimeType( + "application/vnd.openxmlformats-officedocument.presentationml.slide", + "sldx") + val `application/vnd.openxmlformats-officedocument.presentationml.slideshow` = - MimeType("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx") - + MimeType( + "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + "ppsx") + val `application/vnd.openxmlformats-officedocument.presentationml.template` = - MimeType("application/vnd.openxmlformats-officedocument.presentationml.template", "potx") - + MimeType( + "application/vnd.openxmlformats-officedocument.presentationml.template", + "potx") + val `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` = - MimeType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx") - + MimeType( + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + "xlsx") + val `application/vnd.openxmlformats-officedocument.spreadsheetml.template` = - MimeType("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx") - + MimeType( + "application/vnd.openxmlformats-officedocument.spreadsheetml.template", + "xltx") + val `application/vnd.openxmlformats-officedocument.wordprocessingml.document` = - MimeType("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx") - + MimeType( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "docx") + val `application/vnd.openxmlformats-officedocument.wordprocessingml.template` = - MimeType("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx") - - val `application/vnd.osa.netdeploy` = MimeType("application/vnd.osa.netdeploy") + MimeType( + "application/vnd.openxmlformats-officedocument.wordprocessingml.template", + "dotx") + + val `application/vnd.osa.netdeploy` = MimeType( + "application/vnd.osa.netdeploy") val `application/vnd.osgi.bundle` = MimeType("application/vnd.osgi.bundle") val `application/vnd.osgi.dp` = MimeType("application/vnd.osgi.dp", "dp") - val `application/vnd.otps.ct-kip+xml` = MimeType("application/vnd.otps.ct-kip+xml") - val `application/vnd.palm` = MimeType("application/vnd.palm", "oprc", "pdb", "pqa") + val `application/vnd.otps.ct-kip+xml` = MimeType( + "application/vnd.otps.ct-kip+xml") + val `application/vnd.palm` = MimeType( + "application/vnd.palm", "oprc", "pdb", "pqa") val `application/vnd.paos.xml` = MimeType("application/vnd.paos.xml") - val `application/vnd.pg.format` = MimeType("application/vnd.pg.format", "str") - val `application/vnd.pg.osasli` = MimeType("application/vnd.pg.osasli", "ei6") - val `application/vnd.piaccess.application-licence` = MimeType("application/vnd.piaccess.application-licence") + val `application/vnd.pg.format` = MimeType( + "application/vnd.pg.format", "str") + val `application/vnd.pg.osasli` = MimeType( + "application/vnd.pg.osasli", "ei6") + val `application/vnd.piaccess.application-licence` = MimeType( + "application/vnd.piaccess.application-licence") val `application/vnd.picsel` = MimeType("application/vnd.picsel", "efif") - val `application/vnd.poc.group-advertisement+xml` = MimeType("application/vnd.poc.group-advertisement+xml") - val `application/vnd.pocketlearn` = MimeType("application/vnd.pocketlearn", "plf") - val `application/vnd.powerbuilder6` = MimeType("application/vnd.powerbuilder6", "pbd") - val `application/vnd.powerbuilder6-s` = MimeType("application/vnd.powerbuilder6-s") - val `application/vnd.powerbuilder7` = MimeType("application/vnd.powerbuilder7") - val `application/vnd.powerbuilder7-s` = MimeType("application/vnd.powerbuilder7-s") - val `application/vnd.powerbuilder75` = MimeType("application/vnd.powerbuilder75") - val `application/vnd.powerbuilder75-s` = MimeType("application/vnd.powerbuilder75-s") + val `application/vnd.poc.group-advertisement+xml` = MimeType( + "application/vnd.poc.group-advertisement+xml") + val `application/vnd.pocketlearn` = MimeType( + "application/vnd.pocketlearn", "plf") + val `application/vnd.powerbuilder6` = MimeType( + "application/vnd.powerbuilder6", "pbd") + val `application/vnd.powerbuilder6-s` = MimeType( + "application/vnd.powerbuilder6-s") + val `application/vnd.powerbuilder7` = MimeType( + "application/vnd.powerbuilder7") + val `application/vnd.powerbuilder7-s` = MimeType( + "application/vnd.powerbuilder7-s") + val `application/vnd.powerbuilder75` = MimeType( + "application/vnd.powerbuilder75") + val `application/vnd.powerbuilder75-s` = MimeType( + "application/vnd.powerbuilder75-s") val `application/vnd.preminet` = MimeType("application/vnd.preminet") - val `application/vnd.previewsystems.box` = MimeType("application/vnd.previewsystems.box", "box") - val `application/vnd.proteus.magazine` = MimeType("application/vnd.proteus.magazine", "mgz") - val `application/vnd.publishare-delta-tree` = MimeType("application/vnd.publishare-delta-tree", "qps") - val `application/vnd.pvi.ptid1` = MimeType("application/vnd.pvi.ptid1", "ptid") - val `application/vnd.pwg-multiplexed` = MimeType("application/vnd.pwg-multiplexed") - val `application/vnd.pwg-xhtml-print+xml` = MimeType("application/vnd.pwg-xhtml-print+xml") - val `application/vnd.qualcomm.brew-app-res` = MimeType("application/vnd.qualcomm.brew-app-res") - - val `application/vnd.quark.quarkxpress` = - MimeType("application/vnd.quark.quarkxpress", "qwd", "qwt", "qxb", "qxd", "qxl", "qxt") - + val `application/vnd.previewsystems.box` = MimeType( + "application/vnd.previewsystems.box", "box") + val `application/vnd.proteus.magazine` = MimeType( + "application/vnd.proteus.magazine", "mgz") + val `application/vnd.publishare-delta-tree` = MimeType( + "application/vnd.publishare-delta-tree", "qps") + val `application/vnd.pvi.ptid1` = MimeType( + "application/vnd.pvi.ptid1", "ptid") + val `application/vnd.pwg-multiplexed` = MimeType( + "application/vnd.pwg-multiplexed") + val `application/vnd.pwg-xhtml-print+xml` = MimeType( + "application/vnd.pwg-xhtml-print+xml") + val `application/vnd.qualcomm.brew-app-res` = MimeType( + "application/vnd.qualcomm.brew-app-res") + + val `application/vnd.quark.quarkxpress` = MimeType( + "application/vnd.quark.quarkxpress", + "qwd", + "qwt", + "qxb", + "qxd", + "qxl", + "qxt") + val `application/vnd.rapid` = MimeType("application/vnd.rapid") - val `application/vnd.recordare.musicxml` = MimeType("application/vnd.recordare.musicxml", "mxl") - val `application/vnd.recordare.musicxml+xml` = MimeType("application/vnd.recordare.musicxml+xml", "musicxml") - val `application/vnd.renlearn.rlprint` = MimeType("application/vnd.renlearn.rlprint") + val `application/vnd.recordare.musicxml` = MimeType( + "application/vnd.recordare.musicxml", "mxl") + val `application/vnd.recordare.musicxml+xml` = MimeType( + "application/vnd.recordare.musicxml+xml", "musicxml") + val `application/vnd.renlearn.rlprint` = MimeType( + "application/vnd.renlearn.rlprint") val `application/vnd.rim.cod` = MimeType("application/vnd.rim.cod", "cod") - val `application/vnd.rn-realmedia` = MimeType("application/vnd.rn-realmedia", "rm") - val `application/vnd.route66.link66+xml` = MimeType("application/vnd.route66.link66+xml", "link66") - val `application/vnd.ruckus.download` = MimeType("application/vnd.ruckus.download") + val `application/vnd.rn-realmedia` = MimeType( + "application/vnd.rn-realmedia", "rm") + val `application/vnd.route66.link66+xml` = MimeType( + "application/vnd.route66.link66+xml", "link66") + val `application/vnd.ruckus.download` = MimeType( + "application/vnd.ruckus.download") val `application/vnd.s3sms` = MimeType("application/vnd.s3sms") val `application/vnd.sbm.cid` = MimeType("application/vnd.sbm.cid") val `application/vnd.sbm.mid2` = MimeType("application/vnd.sbm.mid2") @@ -790,101 +1199,163 @@ object MimeTypes { val `application/vnd.sealed.ppt` = MimeType("application/vnd.sealed.ppt") val `application/vnd.sealed.tiff` = MimeType("application/vnd.sealed.tiff") val `application/vnd.sealed.xls` = MimeType("application/vnd.sealed.xls") - val `application/vnd.sealedmedia.softseal.html` = MimeType("application/vnd.sealedmedia.softseal.html") - val `application/vnd.sealedmedia.softseal.pdf` = MimeType("application/vnd.sealedmedia.softseal.pdf") + val `application/vnd.sealedmedia.softseal.html` = MimeType( + "application/vnd.sealedmedia.softseal.html") + val `application/vnd.sealedmedia.softseal.pdf` = MimeType( + "application/vnd.sealedmedia.softseal.pdf") val `application/vnd.seemail` = MimeType("application/vnd.seemail", "see") val `application/vnd.sema` = MimeType("application/vnd.sema", "sema") val `application/vnd.semd` = MimeType("application/vnd.semd", "semd") val `application/vnd.semf` = MimeType("application/vnd.semf", "semf") - val `application/vnd.shana.informed.formdata` = MimeType("application/vnd.shana.informed.formdata", "ifm") - val `application/vnd.shana.informed.formtemplate` = MimeType("application/vnd.shana.informed.formtemplate", "itp") - val `application/vnd.shana.informed.interchange` = MimeType("application/vnd.shana.informed.interchange", "iif") - val `application/vnd.shana.informed.package` = MimeType("application/vnd.shana.informed.package", "ipk") - val `application/vnd.simtech-mindmapper` = MimeType("application/vnd.simtech-mindmapper", "twd", "twds") + val `application/vnd.shana.informed.formdata` = MimeType( + "application/vnd.shana.informed.formdata", "ifm") + val `application/vnd.shana.informed.formtemplate` = MimeType( + "application/vnd.shana.informed.formtemplate", "itp") + val `application/vnd.shana.informed.interchange` = MimeType( + "application/vnd.shana.informed.interchange", "iif") + val `application/vnd.shana.informed.package` = MimeType( + "application/vnd.shana.informed.package", "ipk") + val `application/vnd.simtech-mindmapper` = MimeType( + "application/vnd.simtech-mindmapper", "twd", "twds") val `application/vnd.smaf` = MimeType("application/vnd.smaf", "mmf") - val `application/vnd.smart.teacher` = MimeType("application/vnd.smart.teacher", "teacher") - val `application/vnd.software602.filler.form+xml` = MimeType("application/vnd.software602.filler.form+xml") - - val `application/vnd.software602.filler.form-xml-zip` = - MimeType("application/vnd.software602.filler.form-xml-zip") - - val `application/vnd.solent.sdkm+xml` = MimeType("application/vnd.solent.sdkm+xml", "sdkd", "sdkm") - val `application/vnd.spotfire.dxp` = MimeType("application/vnd.spotfire.dxp", "dxp") - val `application/vnd.spotfire.sfs` = MimeType("application/vnd.spotfire.sfs", "sfs") + val `application/vnd.smart.teacher` = MimeType( + "application/vnd.smart.teacher", "teacher") + val `application/vnd.software602.filler.form+xml` = MimeType( + "application/vnd.software602.filler.form+xml") + + val `application/vnd.software602.filler.form-xml-zip` = MimeType( + "application/vnd.software602.filler.form-xml-zip") + + val `application/vnd.solent.sdkm+xml` = MimeType( + "application/vnd.solent.sdkm+xml", "sdkd", "sdkm") + val `application/vnd.spotfire.dxp` = MimeType( + "application/vnd.spotfire.dxp", "dxp") + val `application/vnd.spotfire.sfs` = MimeType( + "application/vnd.spotfire.sfs", "sfs") val `application/vnd.sss-cod` = MimeType("application/vnd.sss-cod") val `application/vnd.sss-dtf` = MimeType("application/vnd.sss-dtf") val `application/vnd.sss-ntf` = MimeType("application/vnd.sss-ntf") - val `application/vnd.stardivision.calc` = MimeType("application/vnd.stardivision.calc", "sdc") - val `application/vnd.stardivision.draw` = MimeType("application/vnd.stardivision.draw", "sda") - val `application/vnd.stardivision.impress` = MimeType("application/vnd.stardivision.impress", "sdd", "sdp") - val `application/vnd.stardivision.math` = MimeType("application/vnd.stardivision.math", "sdf", "smf") - val `application/vnd.stardivision.writer` = MimeType("application/vnd.stardivision.writer", "sdw", "vor") - val `application/vnd.stardivision.writer-global` = MimeType("application/vnd.stardivision.writer-global", "sgl") - val `application/vnd.street-stream` = MimeType("application/vnd.street-stream") + val `application/vnd.stardivision.calc` = MimeType( + "application/vnd.stardivision.calc", "sdc") + val `application/vnd.stardivision.draw` = MimeType( + "application/vnd.stardivision.draw", "sda") + val `application/vnd.stardivision.impress` = MimeType( + "application/vnd.stardivision.impress", "sdd", "sdp") + val `application/vnd.stardivision.math` = MimeType( + "application/vnd.stardivision.math", "sdf", "smf") + val `application/vnd.stardivision.writer` = MimeType( + "application/vnd.stardivision.writer", "sdw", "vor") + val `application/vnd.stardivision.writer-global` = MimeType( + "application/vnd.stardivision.writer-global", "sgl") + val `application/vnd.street-stream` = MimeType( + "application/vnd.street-stream") val `application/vnd.sun.wadl+xml` = MimeType("application/vnd.sun.wadl+xml") - val `application/vnd.sun.xml.calc` = MimeType("application/vnd.sun.xml.calc", "sxc") - val `application/vnd.sun.xml.calc.template` = MimeType("application/vnd.sun.xml.calc.template", "stc") - val `application/vnd.sun.xml.draw` = MimeType("application/vnd.sun.xml.draw", "sxd") - val `application/vnd.sun.xml.draw.template` = MimeType("application/vnd.sun.xml.draw.template", "std") - val `application/vnd.sun.xml.impress` = MimeType("application/vnd.sun.xml.impress", "sxi") - val `application/vnd.sun.xml.impress.template` = MimeType("application/vnd.sun.xml.impress.template", "sti") - val `application/vnd.sun.xml.math` = MimeType("application/vnd.sun.xml.math", "sxm") - val `application/vnd.sun.xml.writer` = MimeType("application/vnd.sun.xml.writer", "sxw") - val `application/vnd.sun.xml.writer.global` = MimeType("application/vnd.sun.xml.writer.global", "sxg") - val `application/vnd.sun.xml.writer.template` = MimeType("application/vnd.sun.xml.writer.template", "stw") - val `application/vnd.sus-calendar` = MimeType("application/vnd.sus-calendar", "sus", "susp") + val `application/vnd.sun.xml.calc` = MimeType( + "application/vnd.sun.xml.calc", "sxc") + val `application/vnd.sun.xml.calc.template` = MimeType( + "application/vnd.sun.xml.calc.template", "stc") + val `application/vnd.sun.xml.draw` = MimeType( + "application/vnd.sun.xml.draw", "sxd") + val `application/vnd.sun.xml.draw.template` = MimeType( + "application/vnd.sun.xml.draw.template", "std") + val `application/vnd.sun.xml.impress` = MimeType( + "application/vnd.sun.xml.impress", "sxi") + val `application/vnd.sun.xml.impress.template` = MimeType( + "application/vnd.sun.xml.impress.template", "sti") + val `application/vnd.sun.xml.math` = MimeType( + "application/vnd.sun.xml.math", "sxm") + val `application/vnd.sun.xml.writer` = MimeType( + "application/vnd.sun.xml.writer", "sxw") + val `application/vnd.sun.xml.writer.global` = MimeType( + "application/vnd.sun.xml.writer.global", "sxg") + val `application/vnd.sun.xml.writer.template` = MimeType( + "application/vnd.sun.xml.writer.template", "stw") + val `application/vnd.sus-calendar` = MimeType( + "application/vnd.sus-calendar", "sus", "susp") val `application/vnd.svd` = MimeType("application/vnd.svd", "svd") - val `application/vnd.swiftview-ics` = MimeType("application/vnd.swiftview-ics") - val `application/vnd.symbian.install` = MimeType("application/vnd.symbian.install", "sis", "sisx") - val `application/vnd.syncml+xml` = MimeType("application/vnd.syncml+xml", "xsm") - val `application/vnd.syncml.dm+wbxml` = MimeType("application/vnd.syncml.dm+wbxml", "bdm") - val `application/vnd.syncml.dm+xml` = MimeType("application/vnd.syncml.dm+xml", "xdm") - val `application/vnd.syncml.dm.notification` = MimeType("application/vnd.syncml.dm.notification") - val `application/vnd.syncml.ds.notification` = MimeType("application/vnd.syncml.ds.notification") - val `application/vnd.tao.intent-module-archive` = MimeType("application/vnd.tao.intent-module-archive", "tao") - val `application/vnd.tmobile-livetv` = MimeType("application/vnd.tmobile-livetv", "tmo") + val `application/vnd.swiftview-ics` = MimeType( + "application/vnd.swiftview-ics") + val `application/vnd.symbian.install` = MimeType( + "application/vnd.symbian.install", "sis", "sisx") + val `application/vnd.syncml+xml` = MimeType( + "application/vnd.syncml+xml", "xsm") + val `application/vnd.syncml.dm+wbxml` = MimeType( + "application/vnd.syncml.dm+wbxml", "bdm") + val `application/vnd.syncml.dm+xml` = MimeType( + "application/vnd.syncml.dm+xml", "xdm") + val `application/vnd.syncml.dm.notification` = MimeType( + "application/vnd.syncml.dm.notification") + val `application/vnd.syncml.ds.notification` = MimeType( + "application/vnd.syncml.ds.notification") + val `application/vnd.tao.intent-module-archive` = MimeType( + "application/vnd.tao.intent-module-archive", "tao") + val `application/vnd.tmobile-livetv` = MimeType( + "application/vnd.tmobile-livetv", "tmo") val `application/vnd.trid.tpt` = MimeType("application/vnd.trid.tpt", "tpt") - val `application/vnd.triscape.mxs` = MimeType("application/vnd.triscape.mxs", "mxs") + val `application/vnd.triscape.mxs` = MimeType( + "application/vnd.triscape.mxs", "mxs") val `application/vnd.trueapp` = MimeType("application/vnd.trueapp", "tra") val `application/vnd.truedoc` = MimeType("application/vnd.truedoc") val `application/vnd.ufdl` = MimeType("application/vnd.ufdl", "ufd", "ufdl") - val `application/vnd.uiq.theme` = MimeType("application/vnd.uiq.theme", "utz") + val `application/vnd.uiq.theme` = MimeType( + "application/vnd.uiq.theme", "utz") val `application/vnd.umajin` = MimeType("application/vnd.umajin", "umj") val `application/vnd.unity` = MimeType("application/vnd.unity", "unityweb") val `application/vnd.uoml+xml` = MimeType("application/vnd.uoml+xml", "uoml") - val `application/vnd.uplanet.alert` = MimeType("application/vnd.uplanet.alert") - val `application/vnd.uplanet.alert-wbxml` = MimeType("application/vnd.uplanet.alert-wbxml") - val `application/vnd.uplanet.bearer-choice` = MimeType("application/vnd.uplanet.bearer-choice") - val `application/vnd.uplanet.bearer-choice-wbxml` = MimeType("application/vnd.uplanet.bearer-choice-wbxml") - val `application/vnd.uplanet.cacheop` = MimeType("application/vnd.uplanet.cacheop") - val `application/vnd.uplanet.cacheop-wbxml` = MimeType("application/vnd.uplanet.cacheop-wbxml") - val `application/vnd.uplanet.channel` = MimeType("application/vnd.uplanet.channel") - val `application/vnd.uplanet.channel-wbxml` = MimeType("application/vnd.uplanet.channel-wbxml") + val `application/vnd.uplanet.alert` = MimeType( + "application/vnd.uplanet.alert") + val `application/vnd.uplanet.alert-wbxml` = MimeType( + "application/vnd.uplanet.alert-wbxml") + val `application/vnd.uplanet.bearer-choice` = MimeType( + "application/vnd.uplanet.bearer-choice") + val `application/vnd.uplanet.bearer-choice-wbxml` = MimeType( + "application/vnd.uplanet.bearer-choice-wbxml") + val `application/vnd.uplanet.cacheop` = MimeType( + "application/vnd.uplanet.cacheop") + val `application/vnd.uplanet.cacheop-wbxml` = MimeType( + "application/vnd.uplanet.cacheop-wbxml") + val `application/vnd.uplanet.channel` = MimeType( + "application/vnd.uplanet.channel") + val `application/vnd.uplanet.channel-wbxml` = MimeType( + "application/vnd.uplanet.channel-wbxml") val `application/vnd.uplanet.list` = MimeType("application/vnd.uplanet.list") - val `application/vnd.uplanet.list-wbxml` = MimeType("application/vnd.uplanet.list-wbxml") - val `application/vnd.uplanet.listcmd` = MimeType("application/vnd.uplanet.listcmd") - val `application/vnd.uplanet.listcmd-wbxml` = MimeType("application/vnd.uplanet.listcmd-wbxml") - val `application/vnd.uplanet.signal` = MimeType("application/vnd.uplanet.signal") + val `application/vnd.uplanet.list-wbxml` = MimeType( + "application/vnd.uplanet.list-wbxml") + val `application/vnd.uplanet.listcmd` = MimeType( + "application/vnd.uplanet.listcmd") + val `application/vnd.uplanet.listcmd-wbxml` = MimeType( + "application/vnd.uplanet.listcmd-wbxml") + val `application/vnd.uplanet.signal` = MimeType( + "application/vnd.uplanet.signal") val `application/vnd.vcx` = MimeType("application/vnd.vcx", "vcx") val `application/vnd.vd-study` = MimeType("application/vnd.vd-study") val `application/vnd.vectorworks` = MimeType("application/vnd.vectorworks") - val `application/vnd.vidsoft.vidconference` = MimeType("application/vnd.vidsoft.vidconference") - val `application/vnd.visio` = MimeType("application/vnd.visio", "vsd", "vss", "vst", "vsw") - val `application/vnd.visionary` = MimeType("application/vnd.visionary", "vis") - val `application/vnd.vividence.scriptfile` = MimeType("application/vnd.vividence.scriptfile") + val `application/vnd.vidsoft.vidconference` = MimeType( + "application/vnd.vidsoft.vidconference") + val `application/vnd.visio` = MimeType( + "application/vnd.visio", "vsd", "vss", "vst", "vsw") + val `application/vnd.visionary` = MimeType( + "application/vnd.visionary", "vis") + val `application/vnd.vividence.scriptfile` = MimeType( + "application/vnd.vividence.scriptfile") val `application/vnd.vsf` = MimeType("application/vnd.vsf", "vsf") val `application/vnd.wap.sic` = MimeType("application/vnd.wap.sic") val `application/vnd.wap.slc` = MimeType("application/vnd.wap.slc") - val `application/vnd.wap.wbxml` = MimeType("application/vnd.wap.wbxml", "wbxml") + val `application/vnd.wap.wbxml` = MimeType( + "application/vnd.wap.wbxml", "wbxml") val `application/vnd.wap.wmlc` = MimeType("application/vnd.wap.wmlc", "wmlc") - val `application/vnd.wap.wmlscriptc` = MimeType("application/vnd.wap.wmlscriptc", "wmlsc") + val `application/vnd.wap.wmlscriptc` = MimeType( + "application/vnd.wap.wmlscriptc", "wmlsc") val `application/vnd.webturbo` = MimeType("application/vnd.webturbo", "wtb") val `application/vnd.wfa.wsc` = MimeType("application/vnd.wfa.wsc") val `application/vnd.wmc` = MimeType("application/vnd.wmc") - val `application/vnd.wmf.bootstrap` = MimeType("application/vnd.wmf.bootstrap") - val `application/vnd.wordperfect` = MimeType("application/vnd.wordperfect", "wpd") + val `application/vnd.wmf.bootstrap` = MimeType( + "application/vnd.wmf.bootstrap") + val `application/vnd.wordperfect` = MimeType( + "application/vnd.wordperfect", "wpd") val `application/vnd.wqd` = MimeType("application/vnd.wqd", "wqd") - val `application/vnd.wrq-hp3000-labelled` = MimeType("application/vnd.wrq-hp3000-labelled") + val `application/vnd.wrq-hp3000-labelled` = MimeType( + "application/vnd.wrq-hp3000-labelled") val `application/vnd.wt.stf` = MimeType("application/vnd.wt.stf", "stf") val `application/vnd.wv.csp+wbxml` = MimeType("application/vnd.wv.csp+wbxml") val `application/vnd.wv.csp+xml` = MimeType("application/vnd.wv.csp+xml") @@ -898,19 +1369,27 @@ object MimeTypes { val `application/vnd.xmpie.plan` = MimeType("application/vnd.xmpie.plan") val `application/vnd.xmpie.ppkg` = MimeType("application/vnd.xmpie.ppkg") val `application/vnd.xmpie.xlim` = MimeType("application/vnd.xmpie.xlim") - val `application/vnd.yamaha.hv-dic` = MimeType("application/vnd.yamaha.hv-dic", "hvd") - val `application/vnd.yamaha.hv-script` = MimeType("application/vnd.yamaha.hv-script", "hvs") - val `application/vnd.yamaha.hv-voice` = MimeType("application/vnd.yamaha.hv-voice", "hvp") - val `application/vnd.yamaha.openscoreformat` = MimeType("application/vnd.yamaha.openscoreformat", "osf") - - val `application/vnd.yamaha.openscoreformat.osfpvg+xml` = - MimeType("application/vnd.yamaha.openscoreformat.osfpvg+xml", "osfpvg") - - val `application/vnd.yamaha.smaf-audio` = MimeType("application/vnd.yamaha.smaf-audio", "saf") - val `application/vnd.yamaha.smaf-phrase` = MimeType("application/vnd.yamaha.smaf-phrase", "spf") - val `application/vnd.yellowriver-custom-menu` = MimeType("application/vnd.yellowriver-custom-menu", "cmp") + val `application/vnd.yamaha.hv-dic` = MimeType( + "application/vnd.yamaha.hv-dic", "hvd") + val `application/vnd.yamaha.hv-script` = MimeType( + "application/vnd.yamaha.hv-script", "hvs") + val `application/vnd.yamaha.hv-voice` = MimeType( + "application/vnd.yamaha.hv-voice", "hvp") + val `application/vnd.yamaha.openscoreformat` = MimeType( + "application/vnd.yamaha.openscoreformat", "osf") + + val `application/vnd.yamaha.openscoreformat.osfpvg+xml` = MimeType( + "application/vnd.yamaha.openscoreformat.osfpvg+xml", "osfpvg") + + val `application/vnd.yamaha.smaf-audio` = MimeType( + "application/vnd.yamaha.smaf-audio", "saf") + val `application/vnd.yamaha.smaf-phrase` = MimeType( + "application/vnd.yamaha.smaf-phrase", "spf") + val `application/vnd.yellowriver-custom-menu` = MimeType( + "application/vnd.yellowriver-custom-menu", "cmp") val `application/vnd.zul` = MimeType("application/vnd.zul", "zir", "zirz") - val `application/vnd.zzazz.deck+xml` = MimeType("application/vnd.zzazz.deck+xml", "zaz") + val `application/vnd.zzazz.deck+xml` = MimeType( + "application/vnd.zzazz.deck+xml", "zaz") val `application/voicexml+xml` = MimeType("application/voicexml+xml", "vxml") val `application/watcherinfo+xml` = MimeType("application/watcherinfo+xml") val `application/whoispp-query` = MimeType("application/whoispp-query") @@ -918,18 +1397,26 @@ object MimeTypes { val `application/winhlp` = MimeType("application/winhlp", "hlp") val `application/wita` = MimeType("application/wita") val `application/wordperfect` = MimeType("application/wordperfect", "wpd") - val `application/wordperfect5.1` = MimeType("application/wordperfect5.1", "wp5") + val `application/wordperfect5.1` = MimeType( + "application/wordperfect5.1", "wp5") val `application/wsdl+xml` = MimeType("application/wsdl+xml", "wsdl") - val `application/wspolicy+xml` = MimeType("application/wspolicy+xml", "wspolicy") + val `application/wspolicy+xml` = MimeType( + "application/wspolicy+xml", "wspolicy") val `application/x-123` = MimeType("application/x-123", "wk") val `application/x-abiword` = MimeType("application/x-abiword", "abw") - val `application/x-ace-compressed` = MimeType("application/x-ace-compressed", "ace") - val `application/x-apple-diskimage` = MimeType("application/x-apple-diskimage", "dmg") - val `application/x-authorware-bin` = MimeType("application/x-authorware-bin", "aab", "u32", "vox", "x32") - val `application/x-authorware-map` = MimeType("application/x-authorware-map", "aam") - val `application/x-authorware-seg` = MimeType("application/x-authorware-seg", "aas") + val `application/x-ace-compressed` = MimeType( + "application/x-ace-compressed", "ace") + val `application/x-apple-diskimage` = MimeType( + "application/x-apple-diskimage", "dmg") + val `application/x-authorware-bin` = MimeType( + "application/x-authorware-bin", "aab", "u32", "vox", "x32") + val `application/x-authorware-map` = MimeType( + "application/x-authorware-map", "aam") + val `application/x-authorware-seg` = MimeType( + "application/x-authorware-seg", "aas") val `application/x-bcpio` = MimeType("application/x-bcpio", "bcpio") - val `application/x-bittorrent` = MimeType("application/x-bittorrent", "torrent") + val `application/x-bittorrent` = MimeType( + "application/x-bittorrent", "torrent") val `application/x-bzip` = MimeType("application/x-bzip", "bz") val `application/x-bzip2` = MimeType("application/x-bzip2", "boz", "bz2") val `application/x-cdf` = MimeType("application/x-cdf", "cdf") @@ -939,63 +1426,97 @@ object MimeTypes { val `application/x-compress` = MimeType("application/x-compress") val `application/x-cpio` = MimeType("application/x-cpio", "cpio") val `application/x-csh` = MimeType("application/x-csh", "csh") - val `application/x-debian-package` = MimeType("application/x-debian-package", "deb", "udeb") - - val `application/x-director` = - MimeType("application/x-director", "cct", "cst", "cxt", "dcr", "dir", "dxr", "fgd", "swa", - "w3d") - + val `application/x-debian-package` = MimeType( + "application/x-debian-package", "deb", "udeb") + + val `application/x-director` = MimeType("application/x-director", + "cct", + "cst", + "cxt", + "dcr", + "dir", + "dxr", + "fgd", + "swa", + "w3d") + val `application/x-dms` = MimeType("application/x-dms", "dms") val `application/x-doom` = MimeType("application/x-doom", "wad") val `application/x-dtbncx+xml` = MimeType("application/x-dtbncx+xml", "ncx") val `application/x-dtbook+xml` = MimeType("application/x-dtbook+xml", "dtb") - val `application/x-dtbresource+xml` = MimeType("application/x-dtbresource+xml", "res") + val `application/x-dtbresource+xml` = MimeType( + "application/x-dtbresource+xml", "res") val `application/x-dvi` = MimeType("application/x-dvi", "dvi") val `application/x-flac` = MimeType("application/x-flac", "flac") - val `application/x-font` = MimeType("application/x-font", "gsf", "pcf", "pcf", ".Z", "pfa", "pfb") + val `application/x-font` = MimeType( + "application/x-font", "gsf", "pcf", "pcf", ".Z", "pfa", "pfb") val `application/x-font-bdf` = MimeType("application/x-font-bdf", "bdf") val `application/x-font-dos` = MimeType("application/x-font-dos") - val `application/x-font-framemaker` = MimeType("application/x-font-framemaker") - val `application/x-font-ghostscript` = MimeType("application/x-font-ghostscript", "gsf") + val `application/x-font-framemaker` = MimeType( + "application/x-font-framemaker") + val `application/x-font-ghostscript` = MimeType( + "application/x-font-ghostscript", "gsf") val `application/x-font-libgrx` = MimeType("application/x-font-libgrx") - val `application/x-font-linux-psf` = MimeType("application/x-font-linux-psf", "psf") + val `application/x-font-linux-psf` = MimeType( + "application/x-font-linux-psf", "psf") val `application/x-font-otf` = MimeType("application/x-font-otf", "otf") val `application/x-font-pcf` = MimeType("application/x-font-pcf", "pcf") val `application/x-font-snf` = MimeType("application/x-font-snf", "snf") val `application/x-font-speedo` = MimeType("application/x-font-speedo") - val `application/x-font-sunos-news` = MimeType("application/x-font-sunos-news") - val `application/x-font-ttf` = MimeType("application/x-font-ttf", "ttc", "ttf") - val `application/x-font-type1` = MimeType("application/x-font-type1", "afm", "pfa", "pfb", "pfm") + val `application/x-font-sunos-news` = MimeType( + "application/x-font-sunos-news") + val `application/x-font-ttf` = MimeType( + "application/x-font-ttf", "ttc", "ttf") + val `application/x-font-type1` = MimeType( + "application/x-font-type1", "afm", "pfa", "pfb", "pfm") val `application/x-font-vfont` = MimeType("application/x-font-vfont") val `application/x-freemind` = MimeType("application/x-freemind", "mm") - val `application/x-futuresplash` = MimeType("application/x-futuresplash", "spl") + val `application/x-futuresplash` = MimeType( + "application/x-futuresplash", "spl") val `application/x-gnumeric` = MimeType("application/x-gnumeric", "gnumeric") val `application/x-go-sgf` = MimeType("application/x-go-sgf", "sgf") - val `application/x-graphing-calculator` = MimeType("application/x-graphing-calculator", "gcf") - val `application/x-gtar` = MimeType("application/x-gtar", "gtar", "taz", "tgz") + val `application/x-graphing-calculator` = MimeType( + "application/x-graphing-calculator", "gcf") + val `application/x-gtar` = MimeType( + "application/x-gtar", "gtar", "taz", "tgz") val `application/x-gzip` = MimeType("application/x-gzip") val `application/x-hdf` = MimeType("application/x-hdf", "hdf") val `application/x-ica` = MimeType("application/x-ica", "ica") - val `application/x-internet-signup` = MimeType("application/x-internet-signup", "ins", "isp") + val `application/x-internet-signup` = MimeType( + "application/x-internet-signup", "ins", "isp") val `application/x-iphone` = MimeType("application/x-iphone", "iii") - val `application/x-iso9660-image` = MimeType("application/x-iso9660-image", "iso") - val `application/x-java-jnlp-file` = MimeType("application/x-java-jnlp-file", "jnlp") + val `application/x-iso9660-image` = MimeType( + "application/x-iso9660-image", "iso") + val `application/x-java-jnlp-file` = MimeType( + "application/x-java-jnlp-file", "jnlp") val `application/x-javascript` = MimeType("application/x-javascript", "js") val `application/x-jmol` = MimeType("application/x-jmol", "jmz") val `application/x-kchart` = MimeType("application/x-kchart", "chrt") - val `application/x-killustrator` = MimeType("application/x-killustrator", "kil") - val `application/x-koan` = MimeType("application/x-koan", "skd", "skm", "skp", "skt") - val `application/x-kpresenter` = MimeType("application/x-kpresenter", "kpr", "kpt") + val `application/x-killustrator` = MimeType( + "application/x-killustrator", "kil") + val `application/x-koan` = MimeType( + "application/x-koan", "skd", "skm", "skp", "skt") + val `application/x-kpresenter` = MimeType( + "application/x-kpresenter", "kpr", "kpt") val `application/x-kspread` = MimeType("application/x-kspread", "ksp") val `application/x-kword` = MimeType("application/x-kword", "kwd", "kwt") val `application/x-latex` = MimeType("application/x-latex", "latex") val `application/x-lha` = MimeType("application/x-lha", "lha") val `application/x-lzh` = MimeType("application/x-lzh", "lzh") val `application/x-lzx` = MimeType("application/x-lzx", "lzx") - val `application/x-maker` = MimeType("application/x-maker", "book", "fb", "fbdoc", "fm", "frame", "frm", "maker") + val `application/x-maker` = MimeType("application/x-maker", + "book", + "fb", + "fbdoc", + "fm", + "frame", + "frm", + "maker") val `application/x-mif` = MimeType("application/x-mif", "mif") - val `application/x-mobipocket-ebook` = MimeType("application/x-mobipocket-ebook", "mobi", "prc") - val `application/x-ms-application` = MimeType("application/x-ms-application", "application") + val `application/x-mobipocket-ebook` = MimeType( + "application/x-mobipocket-ebook", "mobi", "prc") + val `application/x-ms-application` = MimeType( + "application/x-ms-application", "application") val `application/x-ms-wmd` = MimeType("application/x-ms-wmd", "wmd") val `application/x-ms-wmz` = MimeType("application/x-ms-wmz", "wmz") val `application/x-ms-xbap` = MimeType("application/x-ms-xbap", "xbap") @@ -1003,34 +1524,49 @@ object MimeTypes { val `application/x-msbinder` = MimeType("application/x-msbinder", "obd") val `application/x-mscardfile` = MimeType("application/x-mscardfile", "crd") val `application/x-msclip` = MimeType("application/x-msclip", "clp") - val `application/x-msdos-program` = MimeType("application/x-msdos-program", "bat", "com", "dll", "exe") - val `application/x-msdownload` = MimeType("application/x-msdownload", "bat", "com", "dll", "exe", "msi") + val `application/x-msdos-program` = MimeType( + "application/x-msdos-program", "bat", "com", "dll", "exe") + val `application/x-msdownload` = MimeType( + "application/x-msdownload", "bat", "com", "dll", "exe", "msi") val `application/x-msi` = MimeType("application/x-msi", "msi") - val `application/x-msmediaview` = MimeType("application/x-msmediaview", "m13", "m14", "mvb") + val `application/x-msmediaview` = MimeType( + "application/x-msmediaview", "m13", "m14", "mvb") val `application/x-msmetafile` = MimeType("application/x-msmetafile", "wmf") val `application/x-msmoney` = MimeType("application/x-msmoney", "mny") - val `application/x-mspublisher` = MimeType("application/x-mspublisher", "pub") + val `application/x-mspublisher` = MimeType( + "application/x-mspublisher", "pub") val `application/x-msschedule` = MimeType("application/x-msschedule", "scd") val `application/x-msterminal` = MimeType("application/x-msterminal", "trm") val `application/x-mswrite` = MimeType("application/x-mswrite", "wri") val `application/x-netcdf` = MimeType("application/x-netcdf", "cdf", "nc") - val `application/x-ns-proxy-autoconfig` = MimeType("application/x-ns-proxy-autoconfig", "pac") + val `application/x-ns-proxy-autoconfig` = MimeType( + "application/x-ns-proxy-autoconfig", "pac") val `application/x-nwc` = MimeType("application/x-nwc", "nwc") val `application/x-object` = MimeType("application/x-object", "o") - val `application/x-oz-application` = MimeType("application/x-oz-application", "oza") + val `application/x-oz-application` = MimeType( + "application/x-oz-application", "oza") val `application/x-pkcs12` = MimeType("application/x-pkcs12", "p12", "pfx") - val `application/x-pkcs7-certificates` = MimeType("application/x-pkcs7-certificates", "p7b", "spc") - val `application/x-pkcs7-certreqresp` = MimeType("application/x-pkcs7-certreqresp", "p7r") + val `application/x-pkcs7-certificates` = MimeType( + "application/x-pkcs7-certificates", "p7b", "spc") + val `application/x-pkcs7-certreqresp` = MimeType( + "application/x-pkcs7-certreqresp", "p7r") val `application/x-pkcs7-crl` = MimeType("application/x-pkcs7-crl", "crl") - val `application/x-python-code` = MimeType("application/x-python-code", "pyc", "pyo") - val `application/x-quicktimeplayer` = MimeType("application/x-quicktimeplayer", "qtl") - val `application/x-rar-compressed` = MimeType("application/x-rar-compressed", "rar") - val `application/x-redhat-package-manager` = MimeType("application/x-redhat-package-manager", "rpm") + val `application/x-python-code` = MimeType( + "application/x-python-code", "pyc", "pyo") + val `application/x-quicktimeplayer` = MimeType( + "application/x-quicktimeplayer", "qtl") + val `application/x-rar-compressed` = MimeType( + "application/x-rar-compressed", "rar") + val `application/x-redhat-package-manager` = MimeType( + "application/x-redhat-package-manager", "rpm") val `application/x-sh` = MimeType("application/x-sh", "sh") val `application/x-shar` = MimeType("application/x-shar", "shar") - val `application/x-shockwave-flash` = MimeType("application/x-shockwave-flash", "swf", "swfl") - val `application/x-silverlight-app` = MimeType("application/x-silverlight-app", "xap") - val `application/x-stuffit` = MimeType("application/x-stuffit", "sit", "sitx") + val `application/x-shockwave-flash` = MimeType( + "application/x-shockwave-flash", "swf", "swfl") + val `application/x-silverlight-app` = MimeType( + "application/x-silverlight-app", "xap") + val `application/x-stuffit` = MimeType( + "application/x-stuffit", "sit", "sitx") val `application/x-stuffitx` = MimeType("application/x-stuffitx", "sitx") val `application/x-sv4cpio` = MimeType("application/x-sv4cpio", "sv4cpio") val `application/x-sv4crc` = MimeType("application/x-sv4crc", "sv4crc") @@ -1040,16 +1576,21 @@ object MimeTypes { val `application/x-tex-gf` = MimeType("application/x-tex-gf", "gf") val `application/x-tex-pk` = MimeType("application/x-tex-pk", "pk") val `application/x-tex-tfm` = MimeType("application/x-tex-tfm", "tfm") - val `application/x-texinfo` = MimeType("application/x-texinfo", "texi", "texinfo") - val `application/x-trash` = MimeType("application/x-trash", "%", "bak", "old", "sik", "~") - val `application/x-troff` = MimeType("application/x-troff", "roff", "t", "tr") + val `application/x-texinfo` = MimeType( + "application/x-texinfo", "texi", "texinfo") + val `application/x-trash` = MimeType( + "application/x-trash", "%", "bak", "old", "sik", "~") + val `application/x-troff` = MimeType( + "application/x-troff", "roff", "t", "tr") val `application/x-troff-man` = MimeType("application/x-troff-man", "man") val `application/x-troff-me` = MimeType("application/x-troff-me", "me") val `application/x-troff-ms` = MimeType("application/x-troff-ms", "ms") val `application/x-ustar` = MimeType("application/x-ustar", "ustar") - val `application/x-wais-source` = MimeType("application/x-wais-source", "src") + val `application/x-wais-source` = MimeType( + "application/x-wais-source", "src") val `application/x-wingz` = MimeType("application/x-wingz", "wz") - val `application/x-x509-ca-cert` = MimeType("application/x-x509-ca-cert", "crt", "der") + val `application/x-x509-ca-cert` = MimeType( + "application/x-x509-ca-cert", "crt", "der") val `application/x-xcf` = MimeType("application/x-xcf", "xcf") val `application/x-xfig` = MimeType("application/x-xfig", "fig") val `application/x-xpinstall` = MimeType("application/x-xpinstall", "xpi") @@ -1059,19 +1600,24 @@ object MimeTypes { val `application/xcap-el+xml` = MimeType("application/xcap-el+xml") val `application/xcap-error+xml` = MimeType("application/xcap-error+xml") val `application/xcap-ns+xml` = MimeType("application/xcap-ns+xml") - val `application/xcon-conference-info+xml` = MimeType("application/xcon-conference-info+xml") - val `application/xcon-conference-info-diff+xml` = MimeType("application/xcon-conference-info-diff+xml") + val `application/xcon-conference-info+xml` = MimeType( + "application/xcon-conference-info+xml") + val `application/xcon-conference-info-diff+xml` = MimeType( + "application/xcon-conference-info-diff+xml") val `application/xenc+xml` = MimeType("application/xenc+xml", "xenc") - val `application/xhtml+xml` = MimeType("application/xhtml+xml", "xht", "xhtml") + val `application/xhtml+xml` = MimeType( + "application/xhtml+xml", "xht", "xhtml") val `application/xhtml-voice+xml` = MimeType("application/xhtml-voice+xml") val `application/xml` = MimeType("application/xml", "xml", "xsl") val `application/xml-dtd` = MimeType("application/xml-dtd", "dtd") - val `application/xml-external-parsed-entity` = MimeType("application/xml-external-parsed-entity") + val `application/xml-external-parsed-entity` = MimeType( + "application/xml-external-parsed-entity") val `application/xmpp+xml` = MimeType("application/xmpp+xml") val `application/xop+xml` = MimeType("application/xop+xml", "xop") val `application/xslt+xml` = MimeType("application/xslt+xml", "xslt") val `application/xspf+xml` = MimeType("application/xspf+xml", "xspf") - val `application/xv+xml` = MimeType("application/xv+xml", "mxml", "xhvml", "xvm", "xvml") + val `application/xv+xml` = MimeType( + "application/xv+xml", "mxml", "xhvml", "xvm", "xvml") val `application/zip` = MimeType("application/zip", "zip") val `audio/32kadpcm` = MimeType("audio/32kadpcm") val `audio/3gpp` = MimeType("audio/3gpp") @@ -1133,7 +1679,8 @@ object MimeTypes { val `audio/mp4a-latm` = MimeType("audio/mp4a-latm") val `audio/mpa` = MimeType("audio/mpa") val `audio/mpa-robust` = MimeType("audio/mpa-robust") - val `audio/mpeg` = MimeType("audio/mpeg", "m2a", "m3a", "m4a", "mp2", "mp2a", "mp3", "mpega", "mpga") + val `audio/mpeg` = MimeType( + "audio/mpeg", "m2a", "m3a", "m4a", "mp2", "mp2a", "mp3", "mpega", "mpga") val `audio/mpeg4-generic` = MimeType("audio/mpeg4-generic") val `audio/mpegurl` = MimeType("audio/mpegurl", "m3u") val `audio/ogg` = MimeType("audio/ogg", "oga", "ogg", "spx") @@ -1181,16 +1728,21 @@ object MimeTypes { val `audio/vnd.everad.plj` = MimeType("audio/vnd.everad.plj") val `audio/vnd.hns.audio` = MimeType("audio/vnd.hns.audio") val `audio/vnd.lucent.voice` = MimeType("audio/vnd.lucent.voice", "lvp") - val `audio/vnd.ms-playready.media.pya` = MimeType("audio/vnd.ms-playready.media.pya", "pya") + val `audio/vnd.ms-playready.media.pya` = MimeType( + "audio/vnd.ms-playready.media.pya", "pya") val `audio/vnd.nokia.mobile-xmf` = MimeType("audio/vnd.nokia.mobile-xmf") val `audio/vnd.nortel.vbk` = MimeType("audio/vnd.nortel.vbk") - val `audio/vnd.nuera.ecelp4800` = MimeType("audio/vnd.nuera.ecelp4800", "ecelp4800") - val `audio/vnd.nuera.ecelp7470` = MimeType("audio/vnd.nuera.ecelp7470", "ecelp7470") - val `audio/vnd.nuera.ecelp9600` = MimeType("audio/vnd.nuera.ecelp9600", "ecelp9600") + val `audio/vnd.nuera.ecelp4800` = MimeType( + "audio/vnd.nuera.ecelp4800", "ecelp4800") + val `audio/vnd.nuera.ecelp7470` = MimeType( + "audio/vnd.nuera.ecelp7470", "ecelp7470") + val `audio/vnd.nuera.ecelp9600` = MimeType( + "audio/vnd.nuera.ecelp9600", "ecelp9600") val `audio/vnd.octel.sbc` = MimeType("audio/vnd.octel.sbc") val `audio/vnd.qcelp` = MimeType("audio/vnd.qcelp") val `audio/vnd.rhetorex.32kadpcm` = MimeType("audio/vnd.rhetorex.32kadpcm") - val `audio/vnd.sealedmedia.softseal.mpeg` = MimeType("audio/vnd.sealedmedia.softseal.mpeg") + val `audio/vnd.sealedmedia.softseal.mpeg` = MimeType( + "audio/vnd.sealedmedia.softseal.mpeg") val `audio/vnd.vmx.cvsd` = MimeType("audio/vnd.vmx.cvsd") val `audio/vorbis` = MimeType("audio/vorbis") val `audio/vorbis-config` = MimeType("audio/vorbis-config") @@ -1200,8 +1752,10 @@ object MimeTypes { val `audio/x-mpegurl` = MimeType("audio/x-mpegurl", "m3u") val `audio/x-ms-wax` = MimeType("audio/x-ms-wax", "wax") val `audio/x-ms-wma` = MimeType("audio/x-ms-wma", "wma") - val `audio/x-pn-realaudio` = MimeType("audio/x-pn-realaudio", "ra", "ram", "rm") - val `audio/x-pn-realaudio-plugin` = MimeType("audio/x-pn-realaudio-plugin", "rmp") + val `audio/x-pn-realaudio` = MimeType( + "audio/x-pn-realaudio", "ra", "ram", "rm") + val `audio/x-pn-realaudio-plugin` = MimeType( + "audio/x-pn-realaudio-plugin", "rmp") val `audio/x-realaudio` = MimeType("audio/x-realaudio", "ra") val `audio/x-scpls` = MimeType("audio/x-scpls", "pls") val `audio/x-sd2` = MimeType("audio/x-sd2", "sd2") @@ -1209,7 +1763,8 @@ object MimeTypes { val `chemical/x-alchemy` = MimeType("chemical/x-alchemy", "alc") val `chemical/x-cache` = MimeType("chemical/x-cache", "cac", "cache") val `chemical/x-cache-csf` = MimeType("chemical/x-cache-csf", "csf") - val `chemical/x-cactvs-binary` = MimeType("chemical/x-cactvs-binary", "cascii", "cbin", "ctab") + val `chemical/x-cactvs-binary` = MimeType( + "chemical/x-cactvs-binary", "cascii", "cbin", "ctab") val `chemical/x-cdx` = MimeType("chemical/x-cdx", "cdx") val `chemical/x-cerius` = MimeType("chemical/x-cerius", "cer") val `chemical/x-chem3d` = MimeType("chemical/x-chem3d", "c3d") @@ -1222,12 +1777,16 @@ object MimeTypes { val `chemical/x-csml` = MimeType("chemical/x-csml", "csm", "csml") val `chemical/x-ctx` = MimeType("chemical/x-ctx", "ctx") val `chemical/x-cxf` = MimeType("chemical/x-cxf", "cef", "cxf") - val `chemical/x-embl-dl-nucleotide` = MimeType("chemical/x-embl-dl-nucleotide", "emb", "embl") + val `chemical/x-embl-dl-nucleotide` = MimeType( + "chemical/x-embl-dl-nucleotide", "emb", "embl") val `chemical/x-galactic-spc` = MimeType("chemical/x-galactic-spc", "spc") - val `chemical/x-gamess-input` = MimeType("chemical/x-gamess-input", "gam", "gamin", "inp") - val `chemical/x-gaussian-checkpoint` = MimeType("chemical/x-gaussian-checkpoint", "fch", "fchk") + val `chemical/x-gamess-input` = MimeType( + "chemical/x-gamess-input", "gam", "gamin", "inp") + val `chemical/x-gaussian-checkpoint` = MimeType( + "chemical/x-gaussian-checkpoint", "fch", "fchk") val `chemical/x-gaussian-cube` = MimeType("chemical/x-gaussian-cube", "cub") - val `chemical/x-gaussian-input` = MimeType("chemical/x-gaussian-input", "gau", "gjc", "gjf") + val `chemical/x-gaussian-input` = MimeType( + "chemical/x-gaussian-input", "gau", "gjc", "gjf") val `chemical/x-gaussian-log` = MimeType("chemical/x-gaussian-log", "gal") val `chemical/x-gcg8-sequence` = MimeType("chemical/x-gcg8-sequence", "gcg") val `chemical/x-genbank` = MimeType("chemical/x-genbank", "gen") @@ -1236,7 +1795,8 @@ object MimeTypes { val `chemical/x-jcamp-dx` = MimeType("chemical/x-jcamp-dx", "dx", "jdx") val `chemical/x-kinemage` = MimeType("chemical/x-kinemage", "kin") val `chemical/x-macmolecule` = MimeType("chemical/x-macmolecule", "mcm") - val `chemical/x-macromodel-input` = MimeType("chemical/x-macromodel-input", "mmd", "mmod") + val `chemical/x-macromodel-input` = MimeType( + "chemical/x-macromodel-input", "mmd", "mmod") val `chemical/x-mdl-molfile` = MimeType("chemical/x-mdl-molfile", "mol") val `chemical/x-mdl-rdfile` = MimeType("chemical/x-mdl-rdfile", "rd") val `chemical/x-mdl-rxnfile` = MimeType("chemical/x-mdl-rxnfile", "rxn") @@ -1246,17 +1806,22 @@ object MimeTypes { val `chemical/x-mol2` = MimeType("chemical/x-mol2", "mol2") val `chemical/x-molconn-Z` = MimeType("chemical/x-molconn-Z", "b") val `chemical/x-mopac-graph` = MimeType("chemical/x-mopac-graph", "gpt") - val `chemical/x-mopac-input` = MimeType("chemical/x-mopac-input", "dat", "mop", "mopcrt", "mpc", "zmt") + val `chemical/x-mopac-input` = MimeType( + "chemical/x-mopac-input", "dat", "mop", "mopcrt", "mpc", "zmt") val `chemical/x-mopac-out` = MimeType("chemical/x-mopac-out", "moo") val `chemical/x-mopac-vib` = MimeType("chemical/x-mopac-vib", "mvb") val `chemical/x-ncbi-asn1` = MimeType("chemical/x-ncbi-asn1", "asn") - val `chemical/x-ncbi-asn1-ascii` = MimeType("chemical/x-ncbi-asn1-ascii", "ent", "prt") - val `chemical/x-ncbi-asn1-binary` = MimeType("chemical/x-ncbi-asn1-binary", "aso", "val") - val `chemical/x-ncbi-asn1-spec` = MimeType("chemical/x-ncbi-asn1-spec", "asn") + val `chemical/x-ncbi-asn1-ascii` = MimeType( + "chemical/x-ncbi-asn1-ascii", "ent", "prt") + val `chemical/x-ncbi-asn1-binary` = MimeType( + "chemical/x-ncbi-asn1-binary", "aso", "val") + val `chemical/x-ncbi-asn1-spec` = MimeType( + "chemical/x-ncbi-asn1-spec", "asn") val `chemical/x-pdb` = MimeType("chemical/x-pdb", "ent", "pdb") val `chemical/x-rosdal` = MimeType("chemical/x-rosdal", "ros") val `chemical/x-swissprot` = MimeType("chemical/x-swissprot", "sw") - val `chemical/x-vamas-iso14976` = MimeType("chemical/x-vamas-iso14976", "vms") + val `chemical/x-vamas-iso14976` = MimeType( + "chemical/x-vamas-iso14976", "vms") val `chemical/x-vmd` = MimeType("chemical/x-vmd", "vmd") val `chemical/x-xtel` = MimeType("chemical/x-xtel", "xtel") val `chemical/x-xyz` = MimeType("chemical/x-xyz", "xyz") @@ -1280,7 +1845,8 @@ object MimeTypes { val `image/t38` = MimeType("image/t38") val `image/tiff` = MimeType("image/tiff", "tif", "tiff") val `image/tiff-fx` = MimeType("image/tiff-fx") - val `image/vnd.adobe.photoshop` = MimeType("image/vnd.adobe.photoshop", "psd") + val `image/vnd.adobe.photoshop` = MimeType( + "image/vnd.adobe.photoshop", "psd") val `image/vnd.cns.inf2` = MimeType("image/vnd.cns.inf2") val `image/vnd.djvu` = MimeType("image/vnd.djvu", "djv", "djvu") val `image/vnd.dwg` = MimeType("image/vnd.dwg", "dwg") @@ -1288,8 +1854,10 @@ object MimeTypes { val `image/vnd.fastbidsheet` = MimeType("image/vnd.fastbidsheet", "fbs") val `image/vnd.fpx` = MimeType("image/vnd.fpx", "fpx") val `image/vnd.fst` = MimeType("image/vnd.fst", "fst") - val `image/vnd.fujixerox.edmics-mmr` = MimeType("image/vnd.fujixerox.edmics-mmr", "mmr") - val `image/vnd.fujixerox.edmics-rlc` = MimeType("image/vnd.fujixerox.edmics-rlc", "rlc") + val `image/vnd.fujixerox.edmics-mmr` = MimeType( + "image/vnd.fujixerox.edmics-mmr", "mmr") + val `image/vnd.fujixerox.edmics-rlc` = MimeType( + "image/vnd.fujixerox.edmics-rlc", "rlc") val `image/vnd.globalgraphics.pgb` = MimeType("image/vnd.globalgraphics.pgb") val `image/vnd.microsoft.icon` = MimeType("image/vnd.microsoft.icon") val `image/vnd.mix` = MimeType("image/vnd.mix") @@ -1297,8 +1865,10 @@ object MimeTypes { val `image/vnd.net-fpx` = MimeType("image/vnd.net-fpx", "npx") val `image/vnd.radiance` = MimeType("image/vnd.radiance") val `image/vnd.sealed.png` = MimeType("image/vnd.sealed.png") - val `image/vnd.sealedmedia.softseal.gif` = MimeType("image/vnd.sealedmedia.softseal.gif") - val `image/vnd.sealedmedia.softseal.jpg` = MimeType("image/vnd.sealedmedia.softseal.jpg") + val `image/vnd.sealedmedia.softseal.gif` = MimeType( + "image/vnd.sealedmedia.softseal.gif") + val `image/vnd.sealedmedia.softseal.jpg` = MimeType( + "image/vnd.sealedmedia.softseal.jpg") val `image/vnd.svf` = MimeType("image/vnd.svf") val `image/vnd.wap.wbmp` = MimeType("image/vnd.wap.wbmp", "wbmp") val `image/vnd.xiff` = MimeType("image/vnd.xiff", "xif") @@ -1306,9 +1876,11 @@ object MimeTypes { val `image/x-cmx` = MimeType("image/x-cmx", "cmx") val `image/x-coreldraw` = MimeType("image/x-coreldraw", "cdr") val `image/x-coreldrawpattern` = MimeType("image/x-coreldrawpattern", "pat") - val `image/x-coreldrawtemplate` = MimeType("image/x-coreldrawtemplate", "cdt") + val `image/x-coreldrawtemplate` = MimeType( + "image/x-coreldrawtemplate", "cdt") val `image/x-corelphotopaint` = MimeType("image/x-corelphotopaint", "cpt") - val `image/x-freehand` = MimeType("image/x-freehand", "fh", "fh4", "fh5", "fh7", "fhc") + val `image/x-freehand` = MimeType( + "image/x-freehand", "fh", "fh4", "fh5", "fh7", "fhc") val `image/x-icon` = MimeType("image/x-icon", "ico") val `image/x-jg` = MimeType("image/x-jg", "art") val `image/x-jng` = MimeType("image/x-jng", "jng") @@ -1326,12 +1898,15 @@ object MimeTypes { val `image/x-xwindowdump` = MimeType("image/x-xwindowdump", "xwd") val `message/cpim` = MimeType("message/cpim") val `message/delivery-status` = MimeType("message/delivery-status") - val `message/disposition-notification` = MimeType("message/disposition-notification") + val `message/disposition-notification` = MimeType( + "message/disposition-notification") val `message/example` = MimeType("message/example") val `message/external-body` = MimeType("message/external-body") val `message/global` = MimeType("message/global") - val `message/global-delivery-status` = MimeType("message/global-delivery-status") - val `message/global-disposition-notification` = MimeType("message/global-disposition-notification") + val `message/global-delivery-status` = MimeType( + "message/global-delivery-status") + val `message/global-disposition-notification` = MimeType( + "message/global-disposition-notification") val `message/global-headers` = MimeType("message/global-headers") val `message/http` = MimeType("message/http") val `message/imdn+xml` = MimeType("message/imdn+xml") @@ -1354,8 +1929,10 @@ object MimeTypes { val `model/vnd.gtw` = MimeType("model/vnd.gtw", "gtw") val `model/vnd.moml+xml` = MimeType("model/vnd.moml+xml") val `model/vnd.mts` = MimeType("model/vnd.mts", "mts") - val `model/vnd.parasolid.transmit.binary` = MimeType("model/vnd.parasolid.transmit.binary") - val `model/vnd.parasolid.transmit.text` = MimeType("model/vnd.parasolid.transmit.text") + val `model/vnd.parasolid.transmit.binary` = MimeType( + "model/vnd.parasolid.transmit.binary") + val `model/vnd.parasolid.transmit.text` = MimeType( + "model/vnd.parasolid.transmit.text") val `model/vnd.vtu` = MimeType("model/vnd.vtu", "vtu") val `model/vrml` = MimeType("model/vrml", "vrml", "wrl") val `multipart/alternative` = MimeType("multipart/alternative") @@ -1373,7 +1950,8 @@ object MimeTypes { val `multipart/signed` = MimeType("multipart/signed") val `multipart/voice-message` = MimeType("multipart/voice-message") val `text/calendar` = MimeType("text/calendar", "ics", "icz", "ifb") - val `text/comma-separated-values` = MimeType("text/comma-separated-values", "csv") + val `text/comma-separated-values` = MimeType( + "text/comma-separated-values", "csv") val `text/css` = MimeType("text/css", "css") val `text/csv` = MimeType("text/csv", "csv") val `text/directory` = MimeType("text/directory") @@ -1398,9 +1976,11 @@ object MimeTypes { val `text/scriptlet` = MimeType("text/scriptlet", "sct", "wsc") val `text/sgml` = MimeType("text/sgml", "sgm", "sgml") val `text/t140` = MimeType("text/t140") - val `text/tab-separated-values` = MimeType("text/tab-separated-values", "tsv") + val `text/tab-separated-values` = MimeType( + "text/tab-separated-values", "tsv") val `text/texmacs` = MimeType("text/texmacs", "tm", "ts") - val `text/troff` = MimeType("text/troff", "man", "me", "ms", "roff", "t", "tr") + val `text/troff` = MimeType( + "text/troff", "man", "me", "ms", "roff", "t", "tr") val `text/ulpfec` = MimeType("text/ulpfec") val `text/uri-list` = MimeType("text/uri-list", "uri", "uris", "urls") val `text/vnd.abc` = MimeType("text/vnd.abc") @@ -1409,7 +1989,8 @@ object MimeTypes { val `text/vnd.curl.mcurl` = MimeType("text/vnd.curl.mcurl", "mcurl") val `text/vnd.curl.scurl` = MimeType("text/vnd.curl.scurl", "scurl") val `text/vnd.dmclientscript` = MimeType("text/vnd.dmclientscript") - val `text/vnd.esmertec.theme-descriptor` = MimeType("text/vnd.esmertec.theme-descriptor") + val `text/vnd.esmertec.theme-descriptor` = MimeType( + "text/vnd.esmertec.theme-descriptor") val `text/vnd.fly` = MimeType("text/vnd.fly", "fly") val `text/vnd.fmi.flexstor` = MimeType("text/vnd.fmi.flexstor", "flx") val `text/vnd.graphviz` = MimeType("text/vnd.graphviz", "gv") @@ -1420,9 +2001,11 @@ object MimeTypes { val `text/vnd.latex-z` = MimeType("text/vnd.latex-z") val `text/vnd.motorola.reflex` = MimeType("text/vnd.motorola.reflex") val `text/vnd.ms-mediapackage` = MimeType("text/vnd.ms-mediapackage") - val `text/vnd.net2phone.commcenter.command` = MimeType("text/vnd.net2phone.commcenter.command") + val `text/vnd.net2phone.commcenter.command` = MimeType( + "text/vnd.net2phone.commcenter.command") val `text/vnd.si.uricatalogue` = MimeType("text/vnd.si.uricatalogue") - val `text/vnd.sun.j2me.app-descriptor` = MimeType("text/vnd.sun.j2me.app-descriptor", "jad") + val `text/vnd.sun.j2me.app-descriptor` = MimeType( + "text/vnd.sun.j2me.app-descriptor", "jad") val `text/vnd.trolltech.linguist` = MimeType("text/vnd.trolltech.linguist") val `text/vnd.wap.si` = MimeType("text/vnd.wap.si") val `text/vnd.wap.sl` = MimeType("text/vnd.wap.sl") @@ -1430,9 +2013,12 @@ object MimeTypes { val `text/vnd.wap.wmlscript` = MimeType("text/vnd.wap.wmlscript", "wmls") val `text/x-asm` = MimeType("text/x-asm", "asm", "s") val `text/x-bibtex` = MimeType("text/x-bibtex", "bib") - val `text/x-c` = MimeType("text/x-c", "c", "cc", "cpp", "cxx", "dic", "h", "hh") - val `text/x-c++hdr` = MimeType("text/x-c++hdr", "h", "++", "hh", "hpp", "hxx") - val `text/x-c++src` = MimeType("text/x-c++src", "c", "++", "cc", "cpp", "cxx") + val `text/x-c` = MimeType( + "text/x-c", "c", "cc", "cpp", "cxx", "dic", "h", "hh") + val `text/x-c++hdr` = MimeType( + "text/x-c++hdr", "h", "++", "hh", "hpp", "hxx") + val `text/x-c++src` = MimeType( + "text/x-c++src", "c", "++", "cc", "cpp", "cxx") val `text/x-chdr` = MimeType("text/x-chdr", "h") val `text/x-csh` = MimeType("text/x-csh", "csh") val `text/x-csrc` = MimeType("text/x-csrc", "c") @@ -1455,7 +2041,8 @@ object MimeTypes { val `text/x-vcalendar` = MimeType("text/x-vcalendar", "vcs") val `text/x-vcard` = MimeType("text/x-vcard", "vcf") val `text/xml` = MimeType("text/xml") - val `text/xml-external-parsed-entity` = MimeType("text/xml-external-parsed-entity") + val `text/xml-external-parsed-entity` = MimeType( + "text/xml-external-parsed-entity") val `video/3gpp` = MimeType("video/3gpp", "3gp") val `video/3gpp-tt` = MimeType("video/3gpp-tt") val `video/3gpp2` = MimeType("video/3gpp2", "3g2") @@ -1499,23 +2086,30 @@ object MimeTypes { val `video/vnd.dlna.mpeg-tts` = MimeType("video/vnd.dlna.mpeg-tts") val `video/vnd.fvt` = MimeType("video/vnd.fvt", "fvt") val `video/vnd.hns.video` = MimeType("video/vnd.hns.video") - val `video/vnd.iptvforum.1dparityfec-1010` = MimeType("video/vnd.iptvforum.1dparityfec-1010") - val `video/vnd.iptvforum.1dparityfec-2005` = MimeType("video/vnd.iptvforum.1dparityfec-2005") - val `video/vnd.iptvforum.2dparityfec-1010` = MimeType("video/vnd.iptvforum.2dparityfec-1010") - val `video/vnd.iptvforum.2dparityfec-2005` = MimeType("video/vnd.iptvforum.2dparityfec-2005") + val `video/vnd.iptvforum.1dparityfec-1010` = MimeType( + "video/vnd.iptvforum.1dparityfec-1010") + val `video/vnd.iptvforum.1dparityfec-2005` = MimeType( + "video/vnd.iptvforum.1dparityfec-2005") + val `video/vnd.iptvforum.2dparityfec-1010` = MimeType( + "video/vnd.iptvforum.2dparityfec-1010") + val `video/vnd.iptvforum.2dparityfec-2005` = MimeType( + "video/vnd.iptvforum.2dparityfec-2005") val `video/vnd.iptvforum.ttsavc` = MimeType("video/vnd.iptvforum.ttsavc") val `video/vnd.iptvforum.ttsmpeg2` = MimeType("video/vnd.iptvforum.ttsmpeg2") val `video/vnd.motorola.video` = MimeType("video/vnd.motorola.video") val `video/vnd.motorola.videop` = MimeType("video/vnd.motorola.videop") val `video/vnd.mpegurl` = MimeType("video/vnd.mpegurl", "m4u", "mxu") - val `video/vnd.ms-playready.media.pyv` = MimeType("video/vnd.ms-playready.media.pyv", "pyv") - val `video/vnd.nokia.interleaved-multimedia` = MimeType("video/vnd.nokia.interleaved-multimedia") + val `video/vnd.ms-playready.media.pyv` = MimeType( + "video/vnd.ms-playready.media.pyv", "pyv") + val `video/vnd.nokia.interleaved-multimedia` = MimeType( + "video/vnd.nokia.interleaved-multimedia") val `video/vnd.nokia.videovoip` = MimeType("video/vnd.nokia.videovoip") val `video/vnd.objectvideo` = MimeType("video/vnd.objectvideo") val `video/vnd.sealed.mpeg1` = MimeType("video/vnd.sealed.mpeg1") val `video/vnd.sealed.mpeg4` = MimeType("video/vnd.sealed.mpeg4") val `video/vnd.sealed.swf` = MimeType("video/vnd.sealed.swf") - val `video/vnd.sealedmedia.softseal.mov` = MimeType("video/vnd.sealedmedia.softseal.mov") + val `video/vnd.sealedmedia.softseal.mov` = MimeType( + "video/vnd.sealedmedia.softseal.mov") val `video/vnd.vivo` = MimeType("video/vnd.vivo", "viv") val `video/x-f4v` = MimeType("video/x-f4v", "f4v") val `video/x-fli` = MimeType("video/x-fli", "fli") @@ -1533,10 +2127,9 @@ object MimeTypes { val `x-conference/x-cooltalk` = MimeType("x-conference/x-cooltalk", "ice") val `x-world/x-vrml` = MimeType("x-world/x-vrml", "vrm", "vrml", "wrl") - val mimeTypesMap = new javax.activation.MimetypesFileTypeMap() - + types.values foreach { t => - mimeTypesMap.addMimeTypes(t.name+" "+t.extensions.mkString(" ")) + mimeTypesMap.addMimeTypes(t.name + " " + t.extensions.mkString(" ")) } } diff --git a/net/shared/src/main/scala/rapture/net/browser.scala b/net/shared/src/main/scala/rapture/net/browser.scala index 298d62c..f0e9c41 100644 --- a/net/shared/src/main/scala/rapture/net/browser.scala +++ b/net/shared/src/main/scala/rapture/net/browser.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net import rapture.core._ @@ -24,12 +24,16 @@ import scala.collection.mutable.HashMap import java.text.SimpleDateFormat import java.util.Locale -case class Cookie[I, D](domain: String, name: String, value: String, - path: RootedPath, expiry: Option[I], secure: Boolean)(implicit ts: TimeSystem[I, D]) { +case class Cookie[I, D](domain: String, + name: String, + value: String, + path: RootedPath, + expiry: Option[I], + secure: Boolean)(implicit ts: TimeSystem[I, D]) { lazy val pathString = path.toString } -class Browser[I: TimeSystem.ByInstant]() { +class Browser[I : TimeSystem.ByInstant]() { val browserString = "Rapture Browser 2.0.0" private val Rfc1036Pattern = "EEE, dd-MMM-yyyy HH:mm:ss zzz" @@ -39,31 +43,45 @@ class Browser[I: TimeSystem.ByInstant]() { new HashMap[(String, String, RootedPath), Cookie[I, _]] def parseCookie(s: String, domain: String): Cookie[I, _] = { - val ps = s.split(";").map(_.trim.split("=")) map { a => - a(0) -> (if(a.length > 1) a(1).urlDecode else "") - } + val ps = + s.split(";").map(_.trim.split("=")) map { a => + a(0) -> (if (a.length > 1) a(1).urlDecode else "") + } val details = ps.tail.toMap - Cookie(details.get("domain").getOrElse(domain), ps.head._1, ps.head._2, - RootedPath.parse(details.get("path").getOrElse("")).getOrElse(RootedPath(Vector())), - details.get("expires") map { exp => - ts.instant(new SimpleDateFormat(Rfc1036Pattern, Locale.US).parse(exp).getTime) - }, details.contains("secure")) + Cookie(details.get("domain").getOrElse(domain), + ps.head._1, + ps.head._2, + RootedPath + .parse(details.get("path").getOrElse("")) + .getOrElse(RootedPath(Vector())), + details.get("expires") map { exp => + ts.instant(new SimpleDateFormat(Rfc1036Pattern, Locale.US) + .parse(exp) + .getTime) + }, + details.contains("secure")) } def domainCookies(domain: String, secure: Boolean, path: String): String = { val now = System.currentTimeMillis cookies foreach { c => - if(c._2.expiry.map(e => ts.fromInstant(e) < now).getOrElse(false)) + if (c._2.expiry.map(e => ts.fromInstant(e) < now).getOrElse(false)) cookies.remove((c._2.domain, c._2.name, c._2.path)) } - cookies.toList.filter(secure || !_._2.secure).filter(domain endsWith - _._2.domain).filter(path startsWith _._2.pathString).map(_._2).groupBy(_.name) map { c => - c._1+"="+c._2.maxBy(_.pathString.length).value.urlEncode } mkString "; " + cookies.toList + .filter(secure || !_._2.secure) + .filter(domain endsWith _._2.domain) + .filter(path startsWith _._2.pathString) + .map(_._2) + .groupBy(_.name) map { c => + c._1 + "=" + c._2.maxBy(_.pathString.length).value.urlEncode + } mkString "; " } - def accept[I2, D](c: Cookie[I2, D]): Boolean = c.domain.split("\\.").length > 1 + def accept[I2, D](c: Cookie[I2, D]): Boolean = + c.domain.split("\\.").length > 1 /*class BrowserUrl(url: HttpUrl) { @@ -108,4 +126,3 @@ class Browser[I: TimeSystem.ByInstant]() { def apply(url: HttpUrl): BrowserUrl = new BrowserUrl(url)*/ } - diff --git a/net/shared/src/main/scala/rapture/net/exceptions.scala b/net/shared/src/main/scala/rapture/net/exceptions.scala index 48d697c..20b9278 100644 --- a/net/shared/src/main/scala/rapture/net/exceptions.scala +++ b/net/shared/src/main/scala/rapture/net/exceptions.scala @@ -13,12 +13,10 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net sealed trait HttpExceptions extends Exception case class TooManyRedirects() extends HttpExceptions case class BadHttpResponse() extends HttpExceptions - - diff --git a/net/shared/src/main/scala/rapture/net/http.scala b/net/shared/src/main/scala/rapture/net/http.scala index bf7e24b..5df8c22 100644 --- a/net/shared/src/main/scala/rapture/net/http.scala +++ b/net/shared/src/main/scala/rapture/net/http.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net @@ -25,141 +25,151 @@ import java.io._ import java.net._ import javax.net.ssl._ - object HttpSupport { class Capability[Res](res: Res) { - def httpPut[C: PostType]( - content: C, - headers: Map[String, String] = Map() + def httpPut[C : PostType]( + content: C, + headers: Map[String, String] = Map() )( - implicit httpSupport: HttpSupport[Res], - mode: Mode[`NetUrl#httpPut`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication + implicit httpSupport: HttpSupport[Res], + mode: Mode[`NetUrl#httpPut`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = mode.wrap(httpSupport.doHttp(res, content, headers, "PUT")) - + def httpHead( - headers: Map[String, String] = Map() + headers: Map[String, String] = Map() )( - implicit httpSupport: HttpSupport[Res], - mode: Mode[`NetUrl#httpHead`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication + implicit httpSupport: HttpSupport[Res], + mode: Mode[`NetUrl#httpHead`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = mode.wrap(httpSupport.doHttp(res, None, headers, "HEAD")) - + def httpGet( - headers: Map[String, String] = Map() + headers: Map[String, String] = Map() )( - implicit httpSupport: HttpSupport[Res], - mode: Mode[`NetUrl#httpHead`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication + implicit httpSupport: HttpSupport[Res], + mode: Mode[`NetUrl#httpHead`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = mode.wrap(httpSupport.doHttp(res, None, headers, "GET")) - - def httpPost[C: PostType]( - content: C, - headers: Map[String, String] = Map() + + def httpPost[C : PostType]( + content: C, + headers: Map[String, String] = Map() )( - implicit httpSupport: HttpSupport[Res], - mode: Mode[`NetUrl#httpPut`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication + implicit httpSupport: HttpSupport[Res], + mode: Mode[`NetUrl#httpPut`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = mode.wrap(httpSupport.doHttp(res, content, headers, "POST")) } - implicit def basicHttpSupport[H: UriCapable]: HttpSupport[H] = new HttpSupport[H] { - - def doHttp[C: PostType, T]( - res: H, - content: C, - headers: Map[String, String], - method: String - )( - implicit mode: Mode[`NetUrl#httpPost`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication - ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = - mode wrap { - // FIXME: This will produce a race condition if creating multiple URL connections with - // different values for followRedirects in parallel - HttpURLConnection.setFollowRedirects(httpRedirectConfig.follow) - val conn: URLConnection = new URL(implicitly[UriCapable[H]].uri(res).toString).openConnection() - conn.setConnectTimeout(httpTimeout.duration) - conn match { - case c: HttpsURLConnection => - if(httpCertificateConfig.ignoreIfInvalid) { - c.setSSLSocketFactory(NetUrl.sslContext.getSocketFactory) - c.setHostnameVerifier(NetUrl.allHostsValid) + implicit def basicHttpSupport[H : UriCapable]: HttpSupport[H] = + new HttpSupport[H] { + + def doHttp[C : PostType, T]( + res: H, + content: C, + headers: Map[String, String], + method: String + )( + implicit mode: Mode[`NetUrl#httpPost`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication + ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] = + mode wrap { + // FIXME: This will produce a race condition if creating multiple URL connections with + // different values for followRedirects in parallel + HttpURLConnection.setFollowRedirects(httpRedirectConfig.follow) + val conn: URLConnection = new URL( + implicitly[UriCapable[H]].uri(res).toString).openConnection() + conn.setConnectTimeout(httpTimeout.duration) + conn match { + case c: HttpsURLConnection => + if (httpCertificateConfig.ignoreIfInvalid) { + c.setSSLSocketFactory(NetUrl.sslContext.getSocketFactory) + c.setHostnameVerifier(NetUrl.allHostsValid) + } + c.setRequestMethod(method) + if (content != None) c.setDoOutput(true) + c.setUseCaches(false) + case c: HttpURLConnection => + c.setRequestMethod(method) + if (content != None) c.setDoOutput(true) + c.setUseCaches(false) + } + + // FIXME: What an ugly way of writing this. + httpBasicAuthentication.credentials foreach { + case (username, password) => + conn.setRequestProperty( + "Authorization", + "Basic " + NetUrl.base64 + .encode(s"$username:$password".getBytes("UTF-8")) + .mkString) + } + + ?[PostType[C]].contentType map { ct => + conn.setRequestProperty("Content-Type", ct.name) + } + for ((k, v) <- headers) conn.setRequestProperty(k, v) + + if (content != None) + ensuring(OutputStreamBuilder.output(conn.getOutputStream)) { out => + ?[PostType[C]].sender(content) > out } - c.setRequestMethod(method) - if(content != None) c.setDoOutput(true) - c.setUseCaches(false) - case c: HttpURLConnection => - c.setRequestMethod(method) - if(content != None) c.setDoOutput(true) - c.setUseCaches(false) - } - - // FIXME: What an ugly way of writing this. - httpBasicAuthentication.credentials foreach { case (username, password) => - conn.setRequestProperty("Authorization", - "Basic "+NetUrl.base64.encode(s"$username:$password".getBytes("UTF-8")).mkString) - } - - ?[PostType[C]].contentType map { ct => conn.setRequestProperty("Content-Type", ct.name) } - for((k, v) <- headers) conn.setRequestProperty(k, v) - - if(content != None) - ensuring(OutputStreamBuilder.output(conn.getOutputStream)) { out => - ?[PostType[C]].sender(content) > out + + import scala.collection.JavaConversions._ + + val statusCode = conn match { + case c: HttpsURLConnection => c.getResponseCode() + case c: HttpURLConnection => c.getResponseCode() } - - import scala.collection.JavaConversions._ - - val statusCode = conn match { - case c: HttpsURLConnection => c.getResponseCode() - case c: HttpURLConnection => c.getResponseCode() - } - - val is = try conn.getInputStream() catch { - case e: IOException => conn match { - case c: HttpsURLConnection => c.getErrorStream() - case c: HttpURLConnection => c.getErrorStream() + + val is = try conn.getInputStream() catch { + case e: IOException => + conn match { + case c: HttpsURLConnection => c.getErrorStream() + case c: HttpURLConnection => c.getErrorStream() + } } + + new HttpResponse(mapAsScalaMap(conn.getHeaderFields()).toMap + .mapValues(_.to[List]), + statusCode, + is) } - - new HttpResponse(mapAsScalaMap(conn.getHeaderFields()).toMap.mapValues(_.to[List]), - statusCode, is) - } - } + } } trait HttpSupport[Res] { - def doHttp[C: PostType, T]( - res: Res, - content: C, - headers: Map[String, String], - method: String + def doHttp[C : PostType, T]( + res: Res, + content: C, + headers: Map[String, String], + method: String )( - implicit mode: Mode[`NetUrl#httpPost`], - httpTimeout: HttpTimeout, - httpRedirectConfig: HttpRedirectConfig, - httpCertificateConfig: HttpCertificateConfig, - httpBasicAuthentication: HttpBasicAuthentication + implicit mode: Mode[`NetUrl#httpPost`], + httpTimeout: HttpTimeout, + httpRedirectConfig: HttpRedirectConfig, + httpCertificateConfig: HttpCertificateConfig, + httpBasicAuthentication: HttpBasicAuthentication ): mode.Wrap[HttpResponse, HttpExceptions with httpTimeout.Throws] } diff --git a/net/shared/src/main/scala/rapture/net/ip.scala b/net/shared/src/main/scala/rapture/net/ip.scala index ebdf89d..d01bc8a 100644 --- a/net/shared/src/main/scala/rapture/net/ip.scala +++ b/net/shared/src/main/scala/rapture/net/ip.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net @@ -21,19 +21,22 @@ import rapture.core._ import rapture.codec._ object Ipv6 { - def parse(s: String)(implicit mode: Mode[`Ipv6.parse`]): mode.Wrap[Ipv6, Exception] = + def parse(s: String)( + implicit mode: Mode[`Ipv6.parse`]): mode.Wrap[Ipv6, Exception] = mode.wrap { val groups: Array[String] = s.split("::").map(_.split(":")) match { case Array() => Array.fill(8)("") case Array(xs) => xs.padTo(8, "") case Array(Array(""), xs) => Array.fill(8 - xs.length)("") ++ xs - case Array(xs, ys) => xs ++ Array.fill(8 - xs.length - ys.length)("") ++ ys - } - val gs = groups map (decode[Hex](_).bytes) map { - case Array() => 0 - case Array(le) => le - case Array(be, le) => (be << 8) + le + case Array(xs, ys) => + xs ++ Array.fill(8 - xs.length - ys.length)("") ++ ys } + val gs = + groups map (decode[Hex](_).bytes) map { + case Array() => 0 + case Array(le) => le + case Array(be, le) => (be << 8) + le + } Ipv6(gs(0), gs(1), gs(2), gs(3), gs(4), gs(5), gs(6), gs(7)) } @@ -45,43 +48,55 @@ object Ipv4 { val vs = s.split("\\.").map(_.toInt) Ipv4(vs(0), vs(1), vs(2), vs(3)) } - + def fromLong(lng: Long) = - Ipv4((lng>>24 & 255L).toInt, (lng>>16 & 255L).toInt, (lng>>8 & 255L).toInt, - (lng & 255L).toInt) - - lazy val privateSubnets = List(Ipv4(10, 0, 0, 0)/8, Ipv4(192, 168, 0, 0)/16, - Ipv4(172, 16, 0, 0)/12, Ipv4(127, 0, 0, 0)/8) + Ipv4((lng >> 24 & 255L).toInt, + (lng >> 16 & 255L).toInt, + (lng >> 8 & 255L).toInt, + (lng & 255L).toInt) + + lazy val privateSubnets = List(Ipv4(10, 0, 0, 0) / 8, + Ipv4(192, 168, 0, 0) / 16, + Ipv4(172, 16, 0, 0) / 12, + Ipv4(127, 0, 0, 0) / 8) } -case class Ipv6(s1: Int, s2: Int, s3: Int, s4: Int, s5: Int, s6: Int, s7: Int, s8: Int) { +case class Ipv6( + s1: Int, s2: Int, s3: Int, s4: Int, s5: Int, s6: Int, s7: Int, s8: Int) { def groups = Vector(s1, s2, s3, s4, s5, s6, s7, s8) - def expanded = groups map { s => - Bytes(Array(((s >> 8) & 0xff).toByte, (s & 0xff).toByte)).encode[Hex] - } mkString ":" + def expanded = + groups map { s => + Bytes(Array(((s >> 8) & 0xff).toByte, (s & 0xff).toByte)).encode[Hex] + } mkString ":" - override def toString = expanded.replaceAll("^0+", "").replaceAll(":0+", ":").replaceAll("::+", "::") + override def toString = + expanded + .replaceAll("^0+", "") + .replaceAll(":0+", ":") + .replaceAll("::+", "::") } case class Ipv4(b1: Int, b2: Int, b3: Int, b4: Int) { - - if(b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255 || b1 < 0 || b2 < 0 || b3 < 0 || b4 < 0) + + if (b1 > 255 || b2 > 255 || b3 > 255 || b4 > 255 || b1 < 0 || b2 < 0 || + b3 < 0 || b4 < 0) throw new InstantiationException( "The components of the IP address must be in the range 0-255") - def asLong = (b1.toLong<<24) + (b2<<16) + (b3<<8) + b4 + def asLong = (b1.toLong << 24) + (b2 << 16) + (b3 << 8) + b4 def /(i: Int): Subnet = new Subnet(this, i) def in(subnet: Subnet) = subnet contains this - override def toString() = b1+"."+b2+"."+b3+"."+b4 + override def toString() = b1 + "." + b2 + "." + b3 + "." + b4 def isPrivate = Ipv4.privateSubnets.exists(in) override def equals(that: Any): Boolean = that match { - case that: Ipv4 => b1 == that.b1 && b2 == that.b2 && b3 == that.b3 && b4 == that.b4 + case that: Ipv4 => + b1 == that.b1 && b2 == that.b2 && b3 == that.b3 && b4 == that.b4 case _ => false } - override def hashCode = b1<<24 | b2<<16 | b3<<8 | b4 + override def hashCode = b1 << 24 | b2 << 16 | b3 << 8 | b4 } object Subnet { @@ -92,8 +107,9 @@ object Subnet { } class Subnet(baseIp: Ipv4, val bits: Int) extends Iterable[Ipv4] { - if(bits < 0 || bits > 32) - throw new InstantiationException("The subnet size must be in the range 0-32") + if (bits < 0 || bits > 32) + throw new InstantiationException( + "The subnet size must be in the range 0-32") def iterator: Iterator[Ipv4] = new Iterator[Ipv4] { private var current = baseIp.asLong - 1 @@ -104,11 +120,13 @@ class Subnet(baseIp: Ipv4, val bits: Int) extends Iterable[Ipv4] { } } - def maximum = Ipv4.fromLong((((baseIp.asLong>>(32 - bits)) + 1)<<(32 - bits)) - 1) - val ip = Ipv4.fromLong((baseIp.asLong>>(32 - bits))<<(32 - bits)) + def maximum = + Ipv4.fromLong((((baseIp.asLong >> (32 - bits)) + 1) << (32 - bits)) - 1) + val ip = Ipv4.fromLong((baseIp.asLong >> (32 - bits)) << (32 - bits)) override def size = 1 << (32 - bits) - override def toString() = ip.toString+"/"+bits - def contains(ip2: Ipv4) = Ipv4.fromLong((ip2.asLong>>(32 - bits))<<(32 - bits)) == ip + override def toString() = ip.toString + "/" + bits + def contains(ip2: Ipv4) = + Ipv4.fromLong((ip2.asLong >> (32 - bits)) << (32 - bits)) == ip override def equals(that: Any) = that match { case that: Subnet => ip == that.ip && bits == that.bits diff --git a/net/shared/src/main/scala/rapture/net/net.scala b/net/shared/src/main/scala/rapture/net/net.scala index e8bfb70..b73ff4a 100644 --- a/net/shared/src/main/scala/rapture/net/net.scala +++ b/net/shared/src/main/scala/rapture/net/net.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net @@ -30,13 +30,17 @@ case class TimeoutException() extends Exception("Timeout") case class InvalidCertificateException() extends Exception("Timeout") object HttpTimeout { - implicit val defaultHttpTimeout: HttpTimeout { type Throws = TimeoutException } = - new HttpTimeout(10000) { - type Throws = TimeoutException - } + implicit val defaultHttpTimeout: HttpTimeout { + type Throws = TimeoutException + } = new HttpTimeout(10000) { + type Throws = TimeoutException + } - def apply[T: TimeSystem.ByDuration](timeout: T) = - new HttpTimeout(Math.min(Int.MaxValue, ?[TimeSystem.ByDuration[T]].fromDuration(timeout)).toInt) { + def apply[T : TimeSystem.ByDuration](timeout: T) = + new HttpTimeout( + Math + .min(Int.MaxValue, ?[TimeSystem.ByDuration[T]].fromDuration(timeout)) + .toInt) { type Throws = TimeoutException } } @@ -49,16 +53,21 @@ class HttpCertificateConfig(val ignoreIfInvalid: Boolean) { } object HttpCertificateConfig { - implicit val defaultHttpCertificateConfig: HttpCertificateConfig { type Throws = InvalidCertificateException } = - new HttpCertificateConfig(true) { type Throws = InvalidCertificateException } + implicit val defaultHttpCertificateConfig: HttpCertificateConfig { + type Throws = InvalidCertificateException + } = new HttpCertificateConfig(true) { + type Throws = InvalidCertificateException + } } object HttpRedirectConfig { - implicit val defaultHttpRedirectConfig: HttpRedirectConfig = new HttpRedirectConfig(true) + implicit val defaultHttpRedirectConfig: HttpRedirectConfig = + new HttpRedirectConfig(true) } class HttpRedirectConfig(val follow: Boolean) object HttpBasicAuthentication { - implicit val defaultHttpBasicAuthentication: HttpBasicAuthentication = new HttpBasicAuthentication(None) + implicit val defaultHttpBasicAuthentication: HttpBasicAuthentication = + new HttpBasicAuthentication(None) } class HttpBasicAuthentication(val credentials: Option[(String, String)]) { type Throws @@ -66,29 +75,32 @@ class HttpBasicAuthentication(val credentials: Option[(String, String)]) { object httpOptions { object noTimeout { - implicit val implicitHttpTimeout: HttpTimeout { type Throws = Nothing } = new HttpTimeout(-1) { - type Throws = Nothing - } + implicit val implicitHttpTimeout: HttpTimeout { type Throws = Nothing } = + new HttpTimeout(-1) { + type Throws = Nothing + } } - + object ignoreInvalidCertificates { - implicit val implicitCertificateConfig: HttpCertificateConfig = new HttpCertificateConfig(true) + implicit val implicitCertificateConfig: HttpCertificateConfig = + new HttpCertificateConfig(true) } - + object doNotFollowRedirects { - implicit val implicitFollowRedirects: HttpRedirectConfig = new HttpRedirectConfig(false) + implicit val implicitFollowRedirects: HttpRedirectConfig = + new HttpRedirectConfig(false) } } object HttpMethods { - + private val methods = new scala.collection.mutable.HashMap[String, Method] - + sealed class Method(val string: String) { - + def unapply(r: String) = r == string override def toString = string - + methods += string -> this } @@ -105,12 +117,13 @@ object HttpMethods { val Head = new Method("HEAD") val Connect = new Method("CONNECT") val Patch = new Method("PATCH") - } -class HttpResponse(val headers: Map[String, List[String]], val status: Int, is: InputStream) { - def input[Data](implicit ib: InputBuilder[InputStream, Data], mode: Mode[`HttpResponse#input`]): - mode.Wrap[Input[Data], Exception]= +class HttpResponse( + val headers: Map[String, List[String]], val status: Int, is: InputStream) { + def input[Data]( + implicit ib: InputBuilder[InputStream, Data], + mode: Mode[`HttpResponse#input`]): mode.Wrap[Input[Data], Exception] = mode.wrap(ib.input(is)) } @@ -119,17 +132,24 @@ object PostType { def contentType = Some(MimeTypes.`application/x-www-form-urlencoded`) def sender(content: None.type) = ByteArrayInput(Array[Byte](0)) } - - implicit def formPostType: PostType[Map[Symbol, String]] = new PostType[Map[Symbol, String]] { - def contentType = Some(MimeTypes.`application/x-www-form-urlencoded`) - def sender(content: Map[Symbol, String]) = ByteArrayInput((content map { case (k, v) => - java.net.URLEncoder.encode(k.name, "UTF-8")+"="+java.net.URLEncoder.encode(v, "UTF-8") - } mkString "&").getBytes("UTF-8")) - } - - implicit def stringPostType[S: StringSerializer](implicit enc: Encoding): PostType[S] = new PostType[S] { + + implicit def formPostType: PostType[Map[Symbol, String]] = + new PostType[Map[Symbol, String]] { + def contentType = Some(MimeTypes.`application/x-www-form-urlencoded`) + def sender(content: Map[Symbol, String]) = + ByteArrayInput( + (content map { + case (k, v) => + java.net.URLEncoder.encode(k.name, "UTF-8") + "=" + + java.net.URLEncoder.encode(v, "UTF-8") + } mkString "&").getBytes("UTF-8")) + } + + implicit def stringPostType[S : StringSerializer]( + implicit enc: Encoding): PostType[S] = new PostType[S] { def contentType = Some(MimeTypes.`text/plain`) - def sender(content: S) = implicitly[StringSerializer[S]].serialize(content).input[Byte] + def sender(content: S) = + implicitly[StringSerializer[S]].serialize(content).input[Byte] } } trait PostType[-C] { @@ -144,25 +164,27 @@ object NetUrl { } trait Base64Padded extends CodecType - implicit val base64: ByteCodec[Base64Padded] = new Base64Codec[Base64Padded](endPadding = true) - + implicit val base64: ByteCodec[Base64Padded] = + new Base64Codec[Base64Padded](endPadding = true) } trait NetUrl { - + private val trustAllCertificates = { Array[TrustManager](new X509TrustManager { - override def getAcceptedIssuers(): Array[java.security.cert.X509Certificate] = null - - def checkClientTrusted(certs: Array[java.security.cert.X509Certificate], authType: String): - Unit = () - - def checkServerTrusted(certs: Array[java.security.cert.X509Certificate], authType: String): - Unit = () + override def getAcceptedIssuers( + ): Array[java.security.cert.X509Certificate] = null + + def checkClientTrusted(certs: Array[java.security.cert.X509Certificate], + authType: String): Unit = () + + def checkServerTrusted(certs: Array[java.security.cert.X509Certificate], + authType: String): Unit = () }) } - - NetUrl.sslContext.init(null, trustAllCertificates, new java.security.SecureRandom()) + + NetUrl.sslContext.init( + null, trustAllCertificates, new java.security.SecureRandom()) def hostname: String def port: Int @@ -173,59 +195,73 @@ trait NetUrl { object HttpUrl { implicit val parser: StringParser[HttpUrl] = new StringParser[HttpUrl] { type Throws = ParseException - def parse(s: String, mode: Mode[_ <: MethodConstraint]): mode.Wrap[HttpUrl, Throws] = mode.wrap(Http.parse(s)) + def parse(s: String, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[HttpUrl, Throws] = + mode.wrap(Http.parse(s)) } - implicit val serializer: StringSerializer[HttpUrl] = new StringSerializer[HttpUrl] { - def serialize(h: HttpUrl): String = h.toString - } - + implicit val serializer: StringSerializer[HttpUrl] = + new StringSerializer[HttpUrl] { + def serialize(h: HttpUrl): String = h.toString + } + implicit def uriCapable: UriCapable[HttpUrl] = new UriCapable[HttpUrl] { def uri(cp: HttpUrl) = { - val portString = if(cp.ssl && cp.port == 443 || !cp.ssl && cp.port == 80) "" else s":${cp.port}" - Uri(if(cp.ssl) "https" else "http", s"//${cp.hostname}${portString}/${cp.elements.mkString("/")}") + val portString = + if (cp.ssl && cp.port == 443 || !cp.ssl && cp.port == 80) "" + else s":${cp.port}" + Uri(if (cp.ssl) "https" else "http", + s"//${cp.hostname}${portString}/${cp.elements.mkString("/")}") } } - implicit def urlSlashRootedPath[RP <: RootedPath]: Dereferenceable[HttpUrl, RP, HttpUrl] = + implicit def urlSlashRootedPath[RP <: RootedPath]: Dereferenceable[ + HttpUrl, RP, HttpUrl] = new Dereferenceable[HttpUrl, RP, HttpUrl] { def dereference(p1: HttpUrl, p2: RP) = { - val start = if(p1.elements.lastOption == Some("")) p1.elements.init else p1.elements - HttpUrl(p1.root, start ++ p2.elements) + val start = + if (p1.elements.lastOption == Some("")) p1.elements.init + else p1.elements + HttpUrl(p1.root, start ++ p2.elements) } } - implicit def urlSlashRelativePath[RP <: RelativePath]: Dereferenceable[HttpUrl, RP, HttpUrl] = + implicit def urlSlashRelativePath[RP <: RelativePath]: Dereferenceable[ + HttpUrl, RP, HttpUrl] = new Dereferenceable[HttpUrl, RP, HttpUrl] { def dereference(p1: HttpUrl, p2: RP) = - HttpUrl(p1.root, p1.elements.dropRight(p2.ascent) ++ p2.elements) + HttpUrl(p1.root, p1.elements.dropRight(p2.ascent) ++ p2.elements) } implicit def urlSlashString: Dereferenceable[HttpUrl, String, HttpUrl] = new Dereferenceable[HttpUrl, String, HttpUrl] { def dereference(p1: HttpUrl, p2: String) = { - val start = if(p1.elements.lastOption == Some("")) p1.elements.init else p1.elements + val start = + if (p1.elements.lastOption == Some("")) p1.elements.init + else p1.elements HttpUrl(p1.root, start :+ p2) } } - implicit def urlParentable: Parentable[HttpUrl, HttpUrl] = new Parentable[HttpUrl, HttpUrl] { - def parent(httpUrl: HttpUrl): HttpUrl = HttpUrl(httpUrl.root, httpUrl.elements.dropRight(1)) - } + implicit def urlParentable: Parentable[HttpUrl, HttpUrl] = + new Parentable[HttpUrl, HttpUrl] { + def parent(httpUrl: HttpUrl): HttpUrl = + HttpUrl(httpUrl.root, httpUrl.elements.dropRight(1)) + } } /** Represets a URL with the http scheme */ case class HttpUrl(root: HttpDomain, elements: Vector[String]) extends NetUrl { - + override def toString = HttpUrl.uriCapable.uri(this).toString def hostname = root.hostname def port = root.port - def canonicalPort = if(root.ssl) 443 else 80 + def canonicalPort = if (root.ssl) 443 else 80 def ssl = root.ssl - def query[Q: Query](q: Q): HttpQuery = HttpQuery(this, ?[Query[Q]].queryString(q)) - + def query[Q : Query](q: Q): HttpQuery = + HttpQuery(this, ?[Query[Q]].queryString(q)) } trait Query[-T] { @@ -233,27 +269,31 @@ trait Query[-T] { } object Query { - implicit def mapQuery[K: StringSerializer, V: StringSerializer]: Query[Map[K, V]] = new Query[Map[K, V]] { - def queryString(m: Map[K, V]): String = m.map { - case (k, v) => - val key = java.net.URLEncoder.encode(?[StringSerializer[K]].serialize(k), "UTF-8") - val value = java.net.URLEncoder.encode(?[StringSerializer[V]].serialize(v), "UTF-8") - s"$key=$value" - }.mkString("&") + implicit def mapQuery[K : StringSerializer, V : StringSerializer]: Query[Map[ + K, V]] = new Query[Map[K, V]] { + def queryString(m: Map[K, V]): String = + m.map { + case (k, v) => + val key = java.net.URLEncoder.encode( + ?[StringSerializer[K]].serialize(k), "UTF-8") + val value = java.net.URLEncoder.encode( + ?[StringSerializer[V]].serialize(v), "UTF-8") + s"$key=$value" + }.mkString("&") } } - - object HttpQuery { - implicit val serializer: StringSerializer[HttpQuery] = new StringSerializer[HttpQuery] { - def serialize(h: HttpQuery): String = h.toString - } - + implicit val serializer: StringSerializer[HttpQuery] = + new StringSerializer[HttpQuery] { + def serialize(h: HttpQuery): String = h.toString + } + implicit def uriCapable: UriCapable[HttpQuery] = new UriCapable[HttpQuery] { def uri(hq: HttpQuery) = { val httpUrlUri = HttpUrl.uriCapable.uri(hq.httpUrl) - Uri(httpUrlUri.scheme, s"${httpUrlUri.schemeSpecificPart}?${hq.queryString}") + Uri(httpUrlUri.scheme, + s"${httpUrlUri.schemeSpecificPart}?${hq.queryString}") } } } @@ -271,23 +311,27 @@ object HttpDomain { def dereference(p1: HttpDomain, p2: String) = HttpUrl(p1, Vector(p2)) } - implicit def cpSlashRelativePath[RP <: RelativePath]: Dereferenceable[HttpDomain, RP, HttpUrl] = + implicit def cpSlashRelativePath[RP <: RelativePath]: Dereferenceable[ + HttpDomain, RP, HttpUrl] = new Dereferenceable[HttpDomain, RP, HttpUrl] { def dereference(p1: HttpDomain, p2: RP) = HttpUrl(p1, p2.elements) } - implicit def cpSlashRootedPath[RRP <: RootedPath]: Dereferenceable[HttpDomain, RRP, HttpUrl] = + implicit def cpSlashRootedPath[RRP <: RootedPath]: Dereferenceable[ + HttpDomain, RRP, HttpUrl] = new Dereferenceable[HttpDomain, RRP, HttpUrl] { def dereference(p1: HttpDomain, p2: RRP) = HttpUrl(p1, p2.elements) } - implicit def uriCapable: UriCapable[HttpDomain] = new UriCapable[HttpDomain] { - def uri(cp: HttpDomain) = { - val portString = if(cp.ssl && cp.port == 443 || !cp.ssl && cp.port == 80) "" else s":${cp.port}" - Uri(if(cp.ssl) "https" else "http", s"//${cp.hostname}$portString") + implicit def uriCapable: UriCapable[HttpDomain] = + new UriCapable[HttpDomain] { + def uri(cp: HttpDomain) = { + val portString = + if (cp.ssl && cp.port == 443 || !cp.ssl && cp.port == 80) "" + else s":${cp.port}" + Uri(if (cp.ssl) "https" else "http", s"//${cp.hostname}$portString") + } } - } - } case class HttpDomain(hostname: String, port: Int, ssl: Boolean) { @@ -304,17 +348,16 @@ object Http { def parse(s: String): HttpUrl = s match { case UrlRegex(scheme, server, port, _, path, _, after) => - val rp = RootedPath(path.split("/").to[Vector]) - + scheme match { case "http" => - Http(server, if(port == null) 80 else port.substring(1).toInt) / rp + Http(server, if (port == null) 80 else port.substring(1).toInt) / rp case "https" => - Https(server, if(port == null) 443 else port.substring(1).toInt) / rp + Https(server, if (port == null) 443 else port.substring(1).toInt) / rp case _ => throw new Exception(s) } - + case _ => throw new Exception(s) } } @@ -323,6 +366,6 @@ object Https { def apply(hostname: String, port: Int = services.tcp.https.portNo) = HttpDomain(hostname, port, true) - + def parse(s: String): HttpUrl = Http.parse(s) } diff --git a/net/shared/src/main/scala/rapture/net/package.scala b/net/shared/src/main/scala/rapture/net/package.scala index 6f574fd..1a041f7 100644 --- a/net/shared/src/main/scala/rapture/net/package.scala +++ b/net/shared/src/main/scala/rapture/net/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net import rapture.io._ @@ -37,42 +37,55 @@ object `package` { implicit class EnrichedHttpUriContext(uc: UriContext.type) { def http(constants: List[String])(variables: List[String]) = - Http.parse("http:"+constants.zip(variables :+ "").map { case (a, b) => a+b }.mkString) - + Http.parse("http:" + + constants.zip(variables :+ "").map { case (a, b) => a + b }.mkString) + def https(constants: List[String])(variables: List[String]) = - Https.parse("https:"+constants.zip(variables :+ "").map { case (a, b) => a+b }.mkString) + Https.parse("https:" + + constants.zip(variables :+ "").map { case (a, b) => a + b }.mkString) } - implicit def httpUrlSizable(implicit httpTimeout: HttpTimeout, toUri: UriCapable[HttpUrl]): Sizable[HttpUrl, Byte] = new Sizable[HttpUrl, Byte] { - type ExceptionType = HttpExceptions - HttpSupport.basicHttpSupport - def size(url: HttpUrl): Long = url.httpHead().headers.get("Content-Length").get.head.toLong - } + implicit def httpUrlSizable( + implicit httpTimeout: HttpTimeout, + toUri: UriCapable[HttpUrl]): Sizable[HttpUrl, Byte] = + new Sizable[HttpUrl, Byte] { + type ExceptionType = HttpExceptions + HttpSupport.basicHttpSupport + def size(url: HttpUrl): Long = + url.httpHead().headers.get("Content-Length").get.head.toLong + } - implicit def httpCapable[Res: HttpSupport](res: Res): HttpSupport.Capability[Res] = new HttpSupport.Capability[Res](res) + implicit def httpCapable[Res : HttpSupport]( + res: Res): HttpSupport.Capability[Res] = + new HttpSupport.Capability[Res](res) implicit val httpStreamByteReader: JavaInputStreamReader[HttpUrl] = new JavaInputStreamReader[HttpUrl]({ u => - new java.net.URL(u.uri.toString).openConnection.asInstanceOf[java.net.HttpURLConnection].getInputStream + new java.net.URL(u.uri.toString).openConnection + .asInstanceOf[java.net.HttpURLConnection] + .getInputStream }) - + implicit val httpQueryStreamByteReader: JavaInputStreamReader[HttpQuery] = new JavaInputStreamReader[HttpQuery]({ u => - new java.net.URL(u.uri.toString).openConnection.asInstanceOf[java.net.HttpURLConnection].getInputStream + new java.net.URL(u.uri.toString).openConnection + .asInstanceOf[java.net.HttpURLConnection] + .getInputStream }) - + implicit val httpResponseCharReader: Reader[HttpResponse, Char] = - new Reader[HttpResponse, Char] { - def input(response: HttpResponse): Input[Char] = { - import encodings.`UTF-8`._ - response.input[Char] + new Reader[HttpResponse, Char] { + def input(response: HttpResponse): Input[Char] = { + import encodings.`UTF-8`._ + response.input[Char] + } } - } implicit val httpResponseByteReader: Reader[HttpResponse, Byte] = new Reader[HttpResponse, Byte] { def input(response: HttpResponse): Input[Byte] = - response.input[Byte](?[InputBuilder[InputStream, Byte]], modes.throwExceptions()) + response.input[Byte]( + ?[InputBuilder[InputStream, Byte]], modes.throwExceptions()) } implicit val socketStreamByteReader: JavaInputStreamReader[SocketUri] = @@ -80,8 +93,7 @@ object `package` { implicit val socketStreamByteWriter: JavaOutputStreamWriter[SocketUri] = new JavaOutputStreamWriter[SocketUri](_.javaSocket.getOutputStream) - + implicit val socketStreamByteAppender: JavaOutputAppender[SocketUri] = new JavaOutputAppender[SocketUri](_.javaSocket.getOutputStream) } - diff --git a/net/shared/src/main/scala/rapture/net/services.scala b/net/shared/src/main/scala/rapture/net/services.scala index 5a715c9..c283c34 100644 --- a/net/shared/src/main/scala/rapture/net/services.scala +++ b/net/shared/src/main/scala/rapture/net/services.scala @@ -13,11 +13,11 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net import rapture.core._ - + /** Provides a typesafe list of network services mapping from port number to service name. This * is based on [http://www.iana.org/assignments/port-numbers] and * [http://www.freebsd.org/cgi/cvsweb.cgi/src/etc/services] */ @@ -25,12 +25,16 @@ object services { object tcp { private lazy val serviceNames: Map[String, Port] = - enumerateMembers[Port](this).map { p => p.name -> p }.toMap + enumerateMembers[Port](this).map { p => + p.name -> p + }.toMap def apply(name: String) = serviceNames(name) - case class Port(portNo: Int)(implicit assigned: AssignedName) { def name = assigned.name } - + case class Port(portNo: Int)(implicit assigned: AssignedName) { + def name = assigned.name + } + val tcpmux = Port(1) val compressnet = Port(2) val compressnet2 = Port(3) diff --git a/net/shared/src/main/scala/rapture/net/sockets.scala b/net/shared/src/main/scala/rapture/net/sockets.scala index 1724f18..196d6aa 100644 --- a/net/shared/src/main/scala/rapture/net/sockets.scala +++ b/net/shared/src/main/scala/rapture/net/sockets.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.net import rapture.core._ @@ -23,29 +23,34 @@ import rapture.uri._ import java.io._ object Tcp { + /** Listens for incoming connections on the specified port * * @usecase def listen(port: Int): Input[Byte] * @param port the port to listen to */ - def listen[K](port: Int)(implicit ib: InputBuilder[InputStream, K], - ob: OutputBuilder[OutputStream, K], mode: Mode[`Tcp.listen`]): - mode.Wrap[(Input[K], Output[K]), Exception] = mode.wrap { - val sock = new java.net.ServerSocket(port) - val sock2 = sock.accept() - (ib.input(sock2.getInputStream), ob.output(sock2.getOutputStream)) - } + def listen[K](port: Int)( + implicit ib: InputBuilder[InputStream, K], + ob: OutputBuilder[OutputStream, K], + mode: Mode[`Tcp.listen`]): mode.Wrap[(Input[K], Output[K]), Exception] = + mode.wrap { + val sock = new java.net.ServerSocket(port) + val sock2 = sock.accept() + (ib.input(sock2.getInputStream), ob.output(sock2.getOutputStream)) + } - def handle[K](port: Int)(action: (Input[K], Output[K]) => Unit) - (implicit ib: InputBuilder[InputStream, K], ob: OutputBuilder[OutputStream, K]): Unit = { + def handle[K](port: Int)(action: (Input[K], Output[K]) => Unit)( + implicit ib: InputBuilder[InputStream, K], + ob: OutputBuilder[OutputStream, K]): Unit = { val sock = new java.net.ServerSocket(port) - while(true) { + while (true) { val sock2 = sock.accept() Thread.fork(s"rapture-port$port") { - action(ib.input(sock2.getInputStream), ob.output(sock2.getOutputStream)) + action( + ib.input(sock2.getInputStream), ob.output(sock2.getOutputStream)) } } } - + /*def listen(port: Int, local: Boolean = true, timeout: Int = 2000) = { val socket = new ServerSocket() socket.setSoTimeout(timeout) @@ -54,7 +59,6 @@ object Tcp { }*/ } - object SocketUri { implicit val socketUri = new UriCapable[SocketUri] { def uri(su: SocketUri): Uri = Uri("socket", s"//${su.hostname}:${su.port}") @@ -62,18 +66,19 @@ object SocketUri { } case class SocketUri(val hostname: String, val port: Int) { - + lazy val javaSocket: java.net.Socket = new java.net.Socket(hostname, port) - - def schemeSpecificPart = "//"+hostname+":"+port - - def absolute = true + def schemeSpecificPart = "//" + hostname + ":" + port + + def absolute = true } object Socket { - def apply(hostname: String, port: Int): SocketUri = new SocketUri(hostname, port) - def apply(hostname: String, svc: services.tcp.Port): SocketUri = new SocketUri(hostname, svc.portNo) + def apply(hostname: String, port: Int): SocketUri = + new SocketUri(hostname, port) + def apply(hostname: String, svc: services.tcp.Port): SocketUri = + new SocketUri(hostname, svc.portNo) private val UriMatcher = """socket://([a-z0-9\.]+):([1-9][0-9]*)""".r @@ -81,5 +86,3 @@ object Socket { case UriMatcher(host, port) => new SocketUri(host, port.toInt) } } - - diff --git a/test/shared/src/main/scala/rapture/test/macros.scala b/test/shared/src/main/scala/rapture/test/macros.scala index 62386a1..ced309a 100644 --- a/test/shared/src/main/scala/rapture/test/macros.scala +++ b/test/shared/src/main/scala/rapture/test/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.test @@ -33,11 +33,12 @@ object typeMismatch { import c.universe._ val found = fn.tree.exists { - case Select(_, name) => name.decodedName.toString match { - case "deferTypeErrorsConvertAnyToAny" => true - case "deferTypeErrorsResolveAnyImplicit" => true - case _ => false - } + case Select(_, name) => + name.decodedName.toString match { + case "deferTypeErrorsConvertAnyToAny" => true + case "deferTypeErrorsResolveAnyImplicit" => true + case _ => false + } case _ => false } diff --git a/test/shared/src/main/scala/rapture/test/report.scala b/test/shared/src/main/scala/rapture/test/report.scala index 208414b..7890c34 100644 --- a/test/shared/src/main/scala/rapture/test/report.scala +++ b/test/shared/src/main/scala/rapture/test/report.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.test @@ -28,16 +28,16 @@ trait Reporter { def title(text: String)(implicit tty: ansi.Tty) def startTask(text: String)(implicit tty: ansi.Tty): Tag def completeTask(tag: Tag, result: TestResult)(implicit tty: ansi.Tty): Unit - def report(text: String, inset: Boolean = false)(implicit tty: ansi.Tty): Unit + def report(text: String, inset: Boolean = false)( + implicit tty: ansi.Tty): Unit def summary(status: Int, text: String)(implicit tty: ansi.Tty): Unit - } class BasicReporter(width: Int, out: PrintStream) extends Reporter { - + private var spaceAbove = false def mkSpace() = { - if(!spaceAbove) out.println() + if (!spaceAbove) out.println() spaceAbove = true } def output(text: String) { @@ -60,23 +60,25 @@ class BasicReporter(width: Int, out: PrintStream) extends Reporter { tag } - def completeTask(tag: Tag, result: TestResult)(implicit tty: ansi.Tty): Unit = synchronized { + def completeTask(tag: Tag, result: TestResult)( + implicit tty: ansi.Tty): Unit = synchronized { val t = System.currentTimeMillis - tag.t0 - out.print(" "*(width - tag.text.length - 20)) - val pad = " "*(5 - t.toString.length) + out.print(" " * (width - tag.text.length - 20)) + val pad = " " * (5 - t.toString.length) val colorText = result match { case Success => s"${ansi.green}SUCCESS" case Failure(msg) => s"${ansi.yellow}FAILURE" case Error(e) => s"${ansi.red} ERROR " } - output(s"${ansi.boldBlue}[ ${colorText}${ansi.boldBlue} ]${pad}${t} ms${ansi.normal}") + output( + s"${ansi.boldBlue}[ ${colorText}${ansi.boldBlue} ]${pad}${t} ms${ansi.normal}") activeTags -= tag } def report(text: String, inset: Boolean = false)(implicit tty: ansi.Tty) = { - val indent = if(inset) s" ${ansi.boldBlue}" else ansi.normal - text split "\n" flatMap (_.grouped(width - 25)) map (indent+_) foreach output + val indent = if (inset) s" ${ansi.boldBlue}" else ansi.normal + text split "\n" flatMap (_.grouped(width - 25)) map (indent + _) foreach output } def summary(status: Int, text: String)(implicit tty: ansi.Tty) = { @@ -85,9 +87,13 @@ class BasicReporter(width: Int, out: PrintStream) extends Reporter { case 0 => ansi.yellow case _ => ansi.red } - text grouped (width - 4) foreach { ln => output(s" ${color}* ${ansi.normal}${ln}") } + text grouped (width - 4) foreach { ln => + output(s" ${color}* ${ansi.normal}${ln}") + } } def title(text: String)(implicit tty: ansi.Tty) = - text grouped (width - 4) foreach { ln => output(s" ${ansi.green}* ${ansi.normal}${ln}") } + text grouped (width - 4) foreach { ln => + output(s" ${ansi.green}* ${ansi.normal}${ln}") + } } diff --git a/test/shared/src/main/scala/rapture/test/scalatest.scala b/test/shared/src/main/scala/rapture/test/scalatest.scala index 26ac11a..977ef91 100644 --- a/test/shared/src/main/scala/rapture/test/scalatest.scala +++ b/test/shared/src/main/scala/rapture/test/scalatest.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.test @@ -21,15 +21,16 @@ import language.experimental.macros class Programme extends org.scalatest.FunSuite { - def include[TS <: TestSuite](suite: TS): Unit = - macro rapture.test.run.includeMacro[TS] + def include[TS <: TestSuite](suite: TS): Unit = macro rapture.test.run + .includeMacro[TS] def includeAll(tests: List[(String, TestSuite#Test)]): Unit = { - tests.foreach { case (n, t) => - test(n) { - val result = t.runCheck() - assert(result == Success) - } + tests.foreach { + case (n, t) => + test(n) { + val result = t.runCheck() + assert(result == Success) + } } } } diff --git a/test/shared/src/main/scala/rapture/test/test.scala b/test/shared/src/main/scala/rapture/test/test.scala index 8b8c132..80aec1b 100644 --- a/test/shared/src/main/scala/rapture/test/test.scala +++ b/test/shared/src/main/scala/rapture/test/test.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.test @@ -36,13 +36,25 @@ object Util { import java.util.zip._ import scala.collection.JavaConversions._ val zf = new ZipFile(f.javaFile) - entries.getOrElseUpdate(f, zf.entries.to[List].filter(_.getName - endsWith ".class").filter(!_.getName.contains("$")).map(_.getName.dropRight(6))) + entries.getOrElseUpdate(f, + zf.entries + .to[List] + .filter(_.getName endsWith ".class") + .filter(!_.getName.contains("$")) + .map(_.getName.dropRight(6))) } def getAllZipfiles(): List[FsUrl] = { - val urls: Array[java.net.URL] = java.lang.Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs - urls.to[List].map { u => File.parse("file://"+u.getFile) }.filter(_.writable) + val urls: Array[java.net.URL] = + java.lang.Thread.currentThread.getContextClassLoader + .asInstanceOf[URLClassLoader] + .getURLs + urls + .to[List] + .map { u => + File.parse("file://" + u.getFile) + } + .filter(_.writable) } } @@ -93,11 +105,14 @@ sealed trait TestResult { def message: Option[String] } case object Success extends TestResult { def message = None } case class Failure(msg: String) extends TestResult { def message = Some(msg) } case class Error(error: Throwable) extends TestResult { - private val stack = error.getStackTrace.map(_.toString).takeWhile(!_.startsWith("rapture.test")) + private val stack = error.getStackTrace + .map(_.toString) + .takeWhile(!_.startsWith("rapture.test")) private val stackString = stack.mkString(" ", "\n ", "") - def message = Some(s"Exception thrown during test: ${error.toString}\n${stackString}") + def message = + Some(s"Exception thrown during test: ${error.toString}\n${stackString}") } trait TestCase @@ -105,18 +120,21 @@ trait TestCase trait TestSuite { abstract class Test extends TestCase { thisTest => - + type Return def dependencies = Set[Test]() def action(): Return def check(run: () => Return): TestResult def name: String - def runCheck(): TestResult = try check(action) catch { case e: Throwable => Error(e) } + def runCheck(): TestResult = + try check(action) catch { case e: Throwable => Error(e) } - protected def compare[T](x: T, y: T): TestResult = if(x == y) Success else { - Failure(s"Found $x, but expected $y") - } + protected def compare[T](x: T, y: T): TestResult = + if (x == y) Success + else { + Failure(s"Found $x, but expected $y") + } def returns(chk: => Return)(implicit assigned: AssignedName) = new Test { type Return = thisTest.Return @@ -125,46 +143,55 @@ trait TestSuite { def check(run: () => Return): TestResult = { val result = run() val y = chk - if(result == y) Success else Failure(s"Found $result but expected $y") + if (result == y) Success else Failure(s"Found $result but expected $y") } } - - def satisfies(chk: Return => Boolean)(implicit assigned: AssignedName) = new Test { - type Return = thisTest.Return - def name = assigned.name - def action(): Return = thisTest.action() - def check(run: () => Return): TestResult = { - val result = run() - if(chk(result)) Success else Failure(s"Result $result did not satisfy predicate.") + + def satisfies(chk: Return => Boolean)(implicit assigned: AssignedName) = + new Test { + type Return = thisTest.Return + def name = assigned.name + def action(): Return = thisTest.action() + def check(run: () => Return): TestResult = { + val result = run() + if (chk(result)) Success + else Failure(s"Result $result did not satisfy predicate.") + } } - } - def throws[E <: Throwable: ClassTag](cls: Class[E])(implicit assigned: AssignedName): Test = new Test { + def throws[E <: Throwable : ClassTag](cls: Class[E])( + implicit assigned: AssignedName): Test = new Test { type Return = thisTest.Return def name = assigned.name def action(): Return = thisTest.action() - def check(run: () => Return): TestResult = try { - run() - Failure("Expected exception not thrown.") - } catch { - case e: E => Success - case e: Throwable => Failure(s"Expected exception of type `${classTag[E]}', but found exception `${e}'.") - } + def check(run: () => Return): TestResult = + try { + run() + Failure("Expected exception not thrown.") + } catch { + case e: E => Success + case e: Throwable => + Failure( + s"Expected exception of type `${classTag[E]}', but found exception `${e}'.") + } } - - def throws[E <: Throwable](exp: E)(implicit assigned: AssignedName): Test = new Test { - type Return = thisTest.Return - def name = assigned.name - def action(): Return = thisTest.action() - def check(run: () => Return): TestResult = try { - run() - Failure("Expected exception not thrown.") - } catch { - case e if e == exp => Success - case e: Throwable => Failure(s"Expected exception `$exp`, but found exception `$e`.") + + def throws[E <: Throwable](exp: E)(implicit assigned: AssignedName): Test = + new Test { + type Return = thisTest.Return + def name = assigned.name + def action(): Return = thisTest.action() + def check(run: () => Return): TestResult = + try { + run() + Failure("Expected exception not thrown.") + } catch { + case e if e == exp => Success + case e: Throwable => + Failure(s"Expected exception `$exp`, but found exception `$e`.") + } } - } - + /*def apply(done: Set[Test] = Set())(implicit reporter: Reporter): TestSummary = { val (_, (success, count)) = dependencies.foldLeft((done, (0, 0))) { case ((d, (s0, n0)), t) => @@ -183,14 +210,13 @@ trait TestSuite { } def test[T](act: => T): Test { type Return = T } = new Test { - + type Return = T - + def name = "Unnamed test" def action(): Return = act def check(run: () => Return): TestResult = Success } - } trait `run` extends MethodConstraint @@ -198,71 +224,99 @@ trait `run` extends MethodConstraint case class TestSummary(successes: Int, failures: Int, errors: Int) class BadTestResult(msg: String) extends Exception(msg) -case class TestFailure(name: String, error: String) extends BadTestResult(s"Test `$name` failed with error `$error`") +case class TestFailure(name: String, error: String) + extends BadTestResult(s"Test `$name` failed with error `$error`") -case class TestError(name: String, exception: Throwable) extends - BadTestResult(s"Test `$name` failed with exception `$exception`") +case class TestError(name: String, exception: Throwable) + extends BadTestResult(s"Test `$name` failed with exception `$exception`") object run { - def apply[TS <: TestSuite](ts: TS)(implicit mode: Mode[`run`]): Any = - macro run.runMacro[TS] - - def doTests(ts: List[TestSuite#Test], mode: Mode[`run`]): mode.Wrap[TestSummary, BadTestResult] = mode.wrap { - implicit val reporter: Reporter = new BasicReporter(116, System.out) - ansi { implicit tty => - val (successes, failures, errors) = ts.foldLeft((0, 0, 0)) { case ((s, f, e), t) => - val task = reporter.startTask(t.name) - val result = t.runCheck() - reporter.completeTask(task, result) - result.message foreach { msg => reporter.report(msg, inset = true) } - result match { - case Success => - (s + 1, f, e) - case Failure(msg) => - mode.exception(TestFailure(t.name, msg)) - (s, f + 1, e) - case Error(msg) => - mode.exception(TestError(t.name, msg)) - (s, f, e + 1) + def apply[TS <: TestSuite](ts: TS)(implicit mode: Mode[`run`]): Any = macro run + .runMacro[TS] + + def doTests(ts: List[TestSuite#Test], + mode: Mode[`run`]): mode.Wrap[TestSummary, BadTestResult] = + mode.wrap { + implicit val reporter: Reporter = new BasicReporter(116, System.out) + ansi { implicit tty => + val (successes, failures, errors) = ts.foldLeft((0, 0, 0)) { + case ((s, f, e), t) => + val task = reporter.startTask(t.name) + val result = t.runCheck() + reporter.completeTask(task, result) + result.message foreach { msg => + reporter.report(msg, inset = true) + } + result match { + case Success => + (s + 1, f, e) + case Failure(msg) => + mode.exception(TestFailure(t.name, msg)) + (s, f + 1, e) + case Error(msg) => + mode.exception(TestError(t.name, msg)) + (s, f, e + 1) + } } - } - if(successes + failures + errors == 0) reporter.summary(0, "No tests found.") - else if(failures + errors == 0) reporter.summary(1, "All tests passed.") - else if(successes == 0) reporter.summary(-1, "All tests failed.") - else reporter.summary(0, s"${successes} out of ${successes + failures + errors} tests passed.") - - TestSummary(successes, failures, errors) + if (successes + failures + errors == 0) + reporter.summary(0, "No tests found.") + else if (failures + errors == 0) + reporter.summary(1, "All tests passed.") + else if (successes == 0) reporter.summary(-1, "All tests failed.") + else + reporter.summary( + 0, + s"${successes} out of ${successes + failures + errors} tests passed.") + + TestSummary(successes, failures, errors) + } } - } - def runMacro[TS <: TestSuite: c.WeakTypeTag](c: WhiteboxContext)(ts: c.Expr[TS])(mode: c.Expr[Mode[`run`]]): c.Expr[Any] = { + def runMacro[TS <: TestSuite : c.WeakTypeTag](c: WhiteboxContext)( + ts: c.Expr[TS])(mode: c.Expr[Mode[`run`]]): c.Expr[Any] = { import c.universe._ import compatibility._ val cls = weakTypeOf[TS] - val allMethods = weakTypeOf[TS].members.to[List].filter(_.isMethod).map(_.asMethod) - val matchingMethods = allMethods filter { m => paramLists(c)(m).isEmpty && m.returnType.weak_<:<(weakTypeOf[TestSuite#Test]) } - val methodNames = matchingMethods map { m => Select(ts.tree, termName(c, m.name.toString)) } + val allMethods = + weakTypeOf[TS].members.to[List].filter(_.isMethod).map(_.asMethod) + val matchingMethods = + allMethods filter { m => + paramLists(c)(m).isEmpty && + m.returnType.weak_<:<(weakTypeOf[TestSuite#Test]) + } + val methodNames = + matchingMethods map { m => + Select(ts.tree, termName(c, m.name.toString)) + } val listApply = Select(reify(List).tree, termName(c, "apply")) - - c.Expr(q"""_root_.rapture.test.run.doTests(_root_.scala.List(..$methodNames), $mode)""") - } - - def includeMacro[TS <: TestSuite: c.WeakTypeTag](c: WhiteboxContext)(suite: c.Expr[TS]): c.Expr[Unit] = { + + c.Expr( + q"""_root_.rapture.test.run.doTests(_root_.scala.List(..$methodNames), $mode)""") + } + + def includeMacro[TS <: TestSuite : c.WeakTypeTag](c: WhiteboxContext)( + suite: c.Expr[TS]): c.Expr[Unit] = { import c.universe._ import compatibility._ val cls = weakTypeOf[TS] - val allMethods = weakTypeOf[TS].members.to[List].filter(_.isMethod).map(_.asMethod) - val matchingMethods = allMethods filter { m => paramLists(c)(m).isEmpty && m.returnType.weak_<:<(weakTypeOf[TestSuite#Test]) } - val methodNames = matchingMethods map { m => - val sel = Select(suite.tree, termName(c, m.name.toString)) - val suiteName = cls.toString.replaceAll(".type$", "").split("\\.").last - q"""($suiteName+" / "+$sel.name, $sel)""" - } + val allMethods = + weakTypeOf[TS].members.to[List].filter(_.isMethod).map(_.asMethod) + val matchingMethods = + allMethods filter { m => + paramLists(c)(m).isEmpty && + m.returnType.weak_<:<(weakTypeOf[TestSuite#Test]) + } + val methodNames = + matchingMethods map { m => + val sel = Select(suite.tree, termName(c, m.name.toString)) + val suiteName = cls.toString.replaceAll(".type$", "").split("\\.").last + q"""($suiteName+" / "+$sel.name, $sel)""" + } val listApply = Select(reify(List).tree, termName(c, "apply")) - + c.Expr[Unit](q"""includeAll(_root_.scala.List(..$methodNames))""") - } + } } diff --git a/text/shared/src/main/scala/rapture/text/ansi.scala b/text/shared/src/main/scala/rapture/text/ansi.scala index 9aad9ad..f1cdd31 100644 --- a/text/shared/src/main/scala/rapture/text/ansi.scala +++ b/text/shared/src/main/scala/rapture/text/ansi.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.text @@ -29,7 +29,7 @@ object ansi { throw e } finally print(normal(tty)) } - + def esc(implicit tty: Tty) = 27.toChar def normal(implicit tty: Tty) = s"$esc[0m" def bold(implicit tty: Tty) = s"$esc[1m" @@ -54,11 +54,11 @@ object ansi { def boldCyan(implicit tty: Tty) = s"$esc[1;36m" def boldWhite(implicit tty: Tty) = s"$esc[1;37m" - def cursor(row : Int, col : Int)(implicit tty: Tty) = s"$esc[${row};${col}H" - def up(n : Int = 1)(implicit tty: Tty) = s"$esc[${n}A" - def down(n : Int = 1)(implicit tty: Tty) = s"$esc[${n}B" - def right(n : Int = 1)(implicit tty: Tty) = s"$esc[${n}C" - def left(n : Int = 1)(implicit tty: Tty) = s"$esc[${n}D" + def cursor(row: Int, col: Int)(implicit tty: Tty) = s"$esc[${row};${col}H" + def up(n: Int = 1)(implicit tty: Tty) = s"$esc[${n}A" + def down(n: Int = 1)(implicit tty: Tty) = s"$esc[${n}B" + def right(n: Int = 1)(implicit tty: Tty) = s"$esc[${n}C" + def left(n: Int = 1)(implicit tty: Tty) = s"$esc[${n}D" def readPassword(prompt: String)(implicit tty: Tty): String = { print(s"${prompt}$nondisplayed") @@ -69,4 +69,3 @@ object ansi { class Tty private[text]() } - diff --git a/text/shared/src/main/scala/rapture/text/text.scala b/text/shared/src/main/scala/rapture/text/text.scala index abbb678..2d2b463 100644 --- a/text/shared/src/main/scala/rapture/text/text.scala +++ b/text/shared/src/main/scala/rapture/text/text.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.text @@ -30,7 +30,10 @@ object unindent { def apply(s: String): String = { val lines = s.split("\n").dropWhile(_.isEmpty) val indent = lines.headOption.getOrElse("").indexWhere(_ != ' ') - lines.map { ln => if(ln.take(indent).forall(_ == ' ')) ln.drop(indent) else ln.dropWhile(_ == ' ') }.mkString("\n") + lines.map { ln => + if (ln.take(indent).forall(_ == ' ')) ln.drop(indent) + else ln.dropWhile(_ == ' ') + }.mkString("\n") } } } diff --git a/time/shared/src/main/scala/rapture/time/time.scala b/time/shared/src/main/scala/rapture/time/time.scala index 9c6e6fa..dc67873 100644 --- a/time/shared/src/main/scala/rapture/time/time.scala +++ b/time/shared/src/main/scala/rapture/time/time.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.time @@ -24,9 +24,15 @@ import java.text.SimpleDateFormat object dateFormats { object shortUs { implicit val implicitDateFormat = DateFormat("MM/dd/yy") } - object shortEuropean { implicit val implicitDateFormat = DateFormat("dd/MM/yy") } - object longUs { implicit val implicitDateFormat = DateFormat("MMMM d, yyyy") } - object longEuropean { implicit val implicitDateFormat = DateFormat("d MMMM yyyy") } + object shortEuropean { + implicit val implicitDateFormat = DateFormat("dd/MM/yy") + } + object longUs { + implicit val implicitDateFormat = DateFormat("MMMM d, yyyy") + } + object longEuropean { + implicit val implicitDateFormat = DateFormat("d MMMM yyyy") + } } object timeFormats { @@ -41,7 +47,7 @@ case class DateFormat(pattern: String) { c.setTimeInMillis(d.toLong) new SimpleDateFormat(pattern).format(c.getTime) } - + def format(dt: DateTime): String = { val c = Calendar.getInstance c.setTimeInMillis(dt.toLong) @@ -57,36 +63,52 @@ case class TimeFormat(pattern: String) { } } - object Date { def unapply(n: Long) = { val c = Calendar.getInstance c.setTimeInMillis(n) - Some(Date(c.get(Calendar.YEAR), c.get(Calendar.MONTH) + 1, c.get(Calendar.DATE))) + Some( + Date(c.get(Calendar.YEAR), + c.get(Calendar.MONTH) + 1, + c.get(Calendar.DATE))) } } object DateTime { def unapply(n: Long) = { - val Date(date) = n + val Date(date) = n val c = Calendar.getInstance c.setTimeInMillis(n) - - Some(DateTime(date, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), - c.get(Calendar.SECOND))) + + Some( + DateTime(date, + c.get(Calendar.HOUR_OF_DAY), + c.get(Calendar.MINUTE), + c.get(Calendar.SECOND))) } } - + object Time { def apply(hours: Int): Time = Time(hours, 0, 0) def apply(hours: Int, minutes: Int): Time = Time(hours, minutes, 0) } object `package` { - - def monthString(n: Int) = List("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", - "Oct", "Nov", "Dec")(n - 1) - + + def monthString(n: Int) = + List("Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec")(n - 1) + val Jan = Month(1) val Feb = Month(2) val Mar = Month(3) @@ -110,18 +132,20 @@ object `package` { } implicit val dateOrder = new Ordering[Date] { - def compare(d1: Date, d2: Date) = if(d1 < d2) -1 else if(d2 == d1) 0 else 1 + def compare(d1: Date, d2: Date) = + if (d1 < d2) -1 else if (d2 == d1) 0 else 1 } implicit val dateTimeOrder = new Ordering[DateTime] { - def compare(d1: DateTime, d2: DateTime) = if(d1 < d2) -1 else if(d2 == d1) 0 else 1 + def compare(d1: DateTime, d2: DateTime) = + if (d1 < d2) -1 else if (d2 == d1) 0 else 1 } def now() = DateTime.unapply(System.currentTimeMillis).get implicit class IntoMonth(d: Int) { def -(m: Month) = new IntoDay(m) - + class IntoDay(m: Month) { def -(y: Int) = Date(y, m.no, d) } @@ -132,7 +156,7 @@ case class Time(hours: Int, minutes: Int, seconds: Int) case class Date(year: Int, month: Int, day: Int) { date => override def toString() = - day+"-"+monthString(month)+"-"+year + day + "-" + monthString(month) + "-" + year def +(n: Int) = Date.unapply(n + toLong).get def -(n: Int) = Date.unapply(toLong - n).get @@ -150,7 +174,7 @@ case class Date(year: Int, month: Int, day: Int) { date => c.set(Calendar.DATE, day) c.getTimeInMillis } - + def at(time: Time) = DateTime(date, time.hours, time.minutes, time.seconds) def at(hours: Int) = new { @@ -158,7 +182,7 @@ case class Date(year: Int, month: Int, day: Int) { date => def m(seconds: Int) = DateTime(date, hours, minutes, seconds) } } - + def >(that: Date): Boolean = toLong > that.toLong def <(that: Date): Boolean = toLong < that.toLong def >=(that: Date): Boolean = toLong >= that.toLong @@ -168,15 +192,15 @@ case class Date(year: Int, month: Int, day: Int) { date => } case class DateTime(date: Date, hour: Int, minute: Int, second: Int) { - - def pad(n: Int) = if(n < 10) "0"+n else n + + def pad(n: Int) = if (n < 10) "0" + n else n def +(n: Int) = DateTime.unapply(n + toLong).get def -(n: Int) = DateTime.unapply(toLong - n).get def -(d: DateTime): Long = toLong - d.toLong override def toString() = - date.toString+" "+pad(hour)+":"+pad(minute)+":"+pad(second) + date.toString + " " + pad(hour) + ":" + pad(minute) + ":" + pad(second) override def equals(that: Any): Boolean = that match { case that: Date => toLong == that.toLong @@ -200,10 +224,9 @@ case class DateTime(date: Date, hour: Int, minute: Int, second: Int) { c.set(Calendar.SECOND, second) c.getTimeInMillis } - + def format(implicit dateFormat: DateFormat, timeFormat: TimeFormat) = - dateFormat.format(this)+" "+timeFormat.format(this) + dateFormat.format(this) + " " + timeFormat.format(this) } case class Month(no: Int) - diff --git a/uri/shared/src/main/scala/rapture/uri/classpath.scala b/uri/shared/src/main/scala/rapture/uri/classpath.scala index 026873f..123946a 100644 --- a/uri/shared/src/main/scala/rapture/uri/classpath.scala +++ b/uri/shared/src/main/scala/rapture/uri/classpath.scala @@ -13,27 +13,31 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri import rapture.core._ object ClasspathUrl { - implicit def cpSlashString: Dereferenceable[ClasspathUrl, String, ClasspathUrl] = + implicit def cpSlashString: Dereferenceable[ + ClasspathUrl, String, ClasspathUrl] = new Dereferenceable[ClasspathUrl, String, ClasspathUrl] { - def dereference(p1: ClasspathUrl, p2: String) = ClasspathUrl(p1.elements :+ p2) + def dereference(p1: ClasspathUrl, p2: String) = + ClasspathUrl(p1.elements :+ p2) } - - implicit def cpSlashRelativePath[RP <: RelativePath]: Dereferenceable[ClasspathUrl, RP, ClasspathUrl] = + + implicit def cpSlashRelativePath[RP <: RelativePath]: Dereferenceable[ + ClasspathUrl, RP, ClasspathUrl] = new Dereferenceable[ClasspathUrl, RP, ClasspathUrl] { - def dereference(p1: ClasspathUrl, p2: RP) = ClasspathUrl(p1.elements.dropRight(p2.ascent) ++ p2.elements) + def dereference(p1: ClasspathUrl, p2: RP) = + ClasspathUrl(p1.elements.dropRight(p2.ascent) ++ p2.elements) } - implicit def uriCapable: UriCapable[ClasspathUrl] = new UriCapable[ClasspathUrl] { - def uri(cp: ClasspathUrl) = Uri("classpath", cp.elements.mkString("/")) - } + implicit def uriCapable: UriCapable[ClasspathUrl] = + new UriCapable[ClasspathUrl] { + def uri(cp: ClasspathUrl) = Uri("classpath", cp.elements.mkString("/")) + } } case class ClasspathUrl(elements: Vector[String]) { diff --git a/uri/shared/src/main/scala/rapture/uri/macros.scala b/uri/shared/src/main/scala/rapture/uri/macros.scala index 42539ca..5cc848d 100644 --- a/uri/shared/src/main/scala/rapture/uri/macros.scala +++ b/uri/shared/src/main/scala/rapture/uri/macros.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri @@ -22,9 +21,15 @@ import rapture.base._ import rapture.core._ object Paramable { - implicit val stringParamable = new Paramable[String] { def paramize(s: String): String = s } - implicit val intParamable = new Paramable[Int] { def paramize(s: Int): String = s.toString } - implicit val doubleParamable = new Paramable[Double] { def paramize(s: Double): String = s.toString } + implicit val stringParamable = new Paramable[String] { + def paramize(s: String): String = s + } + implicit val intParamable = new Paramable[Int] { + def paramize(s: Int): String = s.toString + } + implicit val doubleParamable = new Paramable[Double] { + def paramize(s: Double): String = s.toString + } } trait Paramable[T] { @@ -32,27 +37,31 @@ trait Paramable[T] { } object UriMacros { - + def uriMacro(c: WhiteboxContext)(content: c.Expr[String]*): c.Expr[Any] = { import c.universe._ import compatibility._ c.prefix.tree match { - case Apply(_, List(Apply(_, rawParts))) => rawParts.head match { - case Literal(Constant(part: String)) => - val scheme = part.split(":", 2) match { - case Array(s, _) => s - case _ => c.abort(c.enclosingPosition, "Could not find a valid scheme for this URI.") - } - - val constants = rawParts.to[List] match { - case Literal(Constant(h: String)) :: t => - Literal(Constant(h.substring(scheme.length + 1))) :: t - } - - val variables = content.map(_.tree).to[List] - c.Expr(q"_root_.rapture.uri.UriContext.${termName(c, scheme)}(List(..$constants))(List(..$variables))") - } + case Apply(_, List(Apply(_, rawParts))) => + rawParts.head match { + case Literal(Constant(part: String)) => + val scheme = part.split(":", 2) match { + case Array(s, _) => s + case _ => + c.abort(c.enclosingPosition, + "Could not find a valid scheme for this URI.") + } + + val constants = rawParts.to[List] match { + case Literal(Constant(h: String)) :: t => + Literal(Constant(h.substring(scheme.length + 1))) :: t + } + + val variables = content.map(_.tree).to[List] + c.Expr( + q"_root_.rapture.uri.UriContext.${termName(c, scheme)}(List(..$constants))(List(..$variables))") + } } } } diff --git a/uri/shared/src/main/scala/rapture/uri/nav.scala b/uri/shared/src/main/scala/rapture/uri/nav.scala index 8f2c79d..f98296a 100644 --- a/uri/shared/src/main/scala/rapture/uri/nav.scala +++ b/uri/shared/src/main/scala/rapture/uri/nav.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri import rapture.core._ @@ -25,42 +24,47 @@ trait `Navigable#isDirectory` extends MethodConstraint trait `Navigable#walkFilter` extends MethodConstraint trait Navigable[UrlType] { - - def children(url: UrlType)(implicit mode: Mode[`Navigable#children`]): mode.Wrap[Seq[UrlType], Exception] - + + def children(url: UrlType)(implicit mode: Mode[`Navigable#children`] + ): mode.Wrap[Seq[UrlType], Exception] + /** Returns false if the filesystem object represented by this FsUrl is a file, and true if * it is a directory. */ - def isDirectory(url: UrlType)(implicit mode: Mode[`Navigable#isDirectory`]): mode.Wrap[Boolean, Exception] - + def isDirectory(url: UrlType)(implicit mode: Mode[`Navigable#isDirectory`] + ): mode.Wrap[Boolean, Exception] + /** If this represents a directory, returns an iterator over all its descendants, * otherwise returns the empty iterator. */ - def descendants(url: UrlType)(implicit mode: Mode[`Navigable#descendants`]): - mode.Wrap[Iterator[UrlType], Exception] = + def descendants(url: UrlType)(implicit mode: Mode[`Navigable#descendants`] + ): mode.Wrap[Iterator[UrlType], Exception] = mode wrap { children(url)(modes.throwExceptions()).iterator.flatMap { c => - if(isDirectory(c)(modes.throwExceptions())) + if (isDirectory(c)(modes.throwExceptions())) Iterator(c) ++ descendants(c)(modes.throwExceptions()) else Iterator(c) } } } -class NavigableExtras[UrlType: Navigable](url: UrlType) { - +class NavigableExtras[UrlType : Navigable](url: UrlType) { + /** Return a sequence of children of this URL */ def children(implicit mode: Mode[`Navigable#children`]) = mode flatWrap ?[Navigable[UrlType]].children(url) - + /** Return true if this URL node is a directory (i.e. it can contain other URLs). */ - def isDirectory(implicit mode: Mode[`Navigable#isDirectory`]): mode.Wrap[Boolean, Exception] = + def isDirectory(implicit mode: Mode[`Navigable#isDirectory`] + ): mode.Wrap[Boolean, Exception] = mode flatWrap ?[Navigable[UrlType]].isDirectory(url) /** Return an iterator of all descendants of this URL. */ - def descendants(implicit mode: Mode[`Navigable#descendants`]): mode.Wrap[Iterator[UrlType], Exception] = + def descendants(implicit mode: Mode[`Navigable#descendants`] + ): mode.Wrap[Iterator[UrlType], Exception] = mode flatWrap ?[Navigable[UrlType]].descendants(url) - def walkFilter(cond: UrlType => Boolean)(implicit mode: Mode[`Navigable#walkFilter`]): - mode.Wrap[Seq[UrlType], Exception] = mode wrap { + def walkFilter(cond: UrlType => Boolean)( + implicit mode: Mode[`Navigable#walkFilter`] + ): mode.Wrap[Seq[UrlType], Exception] = mode wrap { children(modes.throwExceptions()) filter cond flatMap { f => new NavigableExtras(f).walkFilter(cond)(modes.throwExceptions()) } diff --git a/uri/shared/src/main/scala/rapture/uri/package.scala b/uri/shared/src/main/scala/rapture/uri/package.scala index 9abf4de..1e07c02 100644 --- a/uri/shared/src/main/scala/rapture/uri/package.scala +++ b/uri/shared/src/main/scala/rapture/uri/package.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri @@ -32,7 +31,13 @@ object `package` { implicit class EnrichedUriContext(uc: UriContext.type) { def classpath(constants: List[String])(variables: List[String]) = - new ClasspathUrl(constants.zip(variables :+ "").map { case (a, b) => a+b }.mkString.split("/").to[Vector]) + new ClasspathUrl( + constants + .zip(variables :+ "") + .map { case (a, b) => a + b } + .mkString + .split("/") + .to[Vector]) } val $ : String = "" @@ -41,11 +46,15 @@ object `package` { object ^ extends RootedPath(Vector()) - implicit def dereferenceable[Res](res: Res): Dereferenceable.Capability[Res] = alloc(res) - implicit def uriCapable[Res: UriCapable](res: Res): UriCapable.Capability[Res] = alloc(res) - implicit def linkCapable[Res: Linkable](res: Res): Linkable.Capability[Res] = alloc(res) - implicit def parentable[Res](res: Res): Parentable.Capability[Res] = alloc(res) - implicit def navigableExtras[Res: Navigable](url: Res): NavigableExtras[Res] = + implicit def dereferenceable[Res]( + res: Res): Dereferenceable.Capability[Res] = alloc(res) + implicit def uriCapable[Res : UriCapable]( + res: Res): UriCapable.Capability[Res] = alloc(res) + implicit def linkCapable[Res : Linkable]( + res: Res): Linkable.Capability[Res] = alloc(res) + implicit def parentable[Res](res: Res): Parentable.Capability[Res] = + alloc(res) + implicit def navigableExtras[Res : Navigable]( + url: Res): NavigableExtras[Res] = new NavigableExtras(url) - } diff --git a/uri/shared/src/main/scala/rapture/uri/paths.scala b/uri/shared/src/main/scala/rapture/uri/paths.scala index b7b04d6..fb937fb 100644 --- a/uri/shared/src/main/scala/rapture/uri/paths.scala +++ b/uri/shared/src/main/scala/rapture/uri/paths.scala @@ -13,8 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri @@ -23,8 +22,10 @@ import language.implicitConversions import scala.annotation.implicitNotFound case class RelativePath(ascent: Int, elements: Vector[String]) { - override def toString = if(ascent == 0 && elements.isEmpty) "." else "../"*ascent+elements.mkString("/") - + override def toString = + if (ascent == 0 && elements.isEmpty) "." + else "../" * ascent + elements.mkString("/") + override def equals(that: Any) = that match { case RelativePath(a, es) => a == ascent && es == elements case _ => false @@ -35,7 +36,7 @@ case class RelativePath(ascent: Int, elements: Vector[String]) { object RootedPath { def parse(s: String): Option[RootedPath] = { - if(s.head == '/') Some(RootedPath(s.tail.split("/").to[Vector])) + if (s.head == '/') Some(RootedPath(s.tail.split("/").to[Vector])) else None } @@ -46,13 +47,13 @@ object RootedPath { object / { def unapply(p: RootedPath): Option[(RootedPath, String)] = - if(p.elements.isEmpty) None + if (p.elements.isEmpty) None else Some((RootedPath(p.elements.init), p.elements.last)) } case class RootedPath(elements: Vector[String]) { override def toString = elements.mkString("/", "/", "") - + override def equals(that: Any) = that match { case RootedPath(es) => es == elements case _ => false @@ -62,42 +63,58 @@ case class RootedPath(elements: Vector[String]) { } object Dereferenceable { - implicit def stringSlashString: Dereferenceable[String, String, RelativePath] = new Dereferenceable[String, String, RelativePath] { - def dereference(p1: String, p2: String): RelativePath = RelativePath(0, Vector(p1, p2)) - } - - implicit def relativePathSlashString[RP <: RelativePath]: Dereferenceable[RP, String, RelativePath] = new Dereferenceable[RP, String, RelativePath] { - def dereference(p1: RP, p2: String): RelativePath = RelativePath(p1.ascent, p1.elements :+ p2) - } - - implicit def rootSlashString[RRP <: RootedPath]: Dereferenceable[RRP, String, RootedPath] = new Dereferenceable[RRP, String, RootedPath] { - def dereference(p1: RRP, p2: String): RootedPath = RootedPath(p1.elements :+ p2) + implicit def stringSlashString: Dereferenceable[String, String, RelativePath] = + new Dereferenceable[String, String, RelativePath] { + def dereference(p1: String, p2: String): RelativePath = + RelativePath(0, Vector(p1, p2)) + } + + implicit def relativePathSlashString[RP <: RelativePath]: Dereferenceable[ + RP, String, RelativePath] = + new Dereferenceable[RP, String, RelativePath] { + def dereference(p1: RP, p2: String): RelativePath = + RelativePath(p1.ascent, p1.elements :+ p2) + } + + implicit def rootSlashString[RRP <: RootedPath]: Dereferenceable[ + RRP, String, RootedPath] = new Dereferenceable[RRP, String, RootedPath] { + def dereference(p1: RRP, p2: String): RootedPath = + RootedPath(p1.elements :+ p2) } - - implicit def rootSlashRelative[RRP <: RootedPath, RP <: RelativePath]: Dereferenceable[RRP, RP, RootedPath] = new Dereferenceable[RRP, RP, RootedPath] { - def dereference(p1: RRP, p2: RP): RootedPath = RootedPath(p2.elements ++ p1.elements.drop(p2.ascent)) + + implicit def rootSlashRelative[ + RRP <: RootedPath, RP <: RelativePath]: Dereferenceable[ + RRP, RP, RootedPath] = new Dereferenceable[RRP, RP, RootedPath] { + def dereference(p1: RRP, p2: RP): RootedPath = + RootedPath(p2.elements ++ p1.elements.drop(p2.ascent)) } - + class Capability[Path](val path: Path) { - def /[Elem, Return](elem: Elem)(implicit deref: Dereferenceable[Path, Elem, Return]): Return = + def /[Elem, Return](elem: Elem)( + implicit deref: Dereferenceable[Path, Elem, Return]): Return = deref.dereference(path, elem) } } -@implicitNotFound("it is not possible to dereference a value of type ${P1} by a value of type ${P2}.") +@implicitNotFound( + "it is not possible to dereference a value of type ${P1} by a value of type ${P2}.") trait Dereferenceable[-P1, -P2, +Return] { def dereference(p1: P1, p2: P2): Return } object Parentable { - implicit def relativePathParent[RP <: RelativePath]: Parentable[RP, RelativePath] = new Parentable[RP, RelativePath] { - def parent(p: RP): RelativePath = RelativePath(if(p.elements.length == 0) p.ascent + 1 else p.ascent, p.elements.dropRight(1)) + implicit def relativePathParent[RP <: RelativePath]: Parentable[ + RP, RelativePath] = new Parentable[RP, RelativePath] { + def parent(p: RP): RelativePath = + RelativePath(if (p.elements.length == 0) p.ascent + 1 else p.ascent, + p.elements.dropRight(1)) } - - implicit def rootRelativePathParent[RRP <: RootedPath]: Parentable[RRP, RootedPath] = new Parentable[RRP, RootedPath] { + + implicit def rootRelativePathParent[RRP <: RootedPath]: Parentable[ + RRP, RootedPath] = new Parentable[RRP, RootedPath] { def parent(p1: RRP): RootedPath = RootedPath(p1.elements.dropRight(1)) } - + class Capability[Path](val path: Path) { def parent[Return](implicit parentable: Parentable[Path, Return]): Return = parentable.parent(path) diff --git a/uri/shared/src/main/scala/rapture/uri/uri.scala b/uri/shared/src/main/scala/rapture/uri/uri.scala index f6fc0d9..ffd8321 100644 --- a/uri/shared/src/main/scala/rapture/uri/uri.scala +++ b/uri/shared/src/main/scala/rapture/uri/uri.scala @@ -13,13 +13,12 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ - + */ package rapture.uri object UriCapable { - class Capability[Res: UriCapable](res: Res) { + class Capability[Res : UriCapable](res: Res) { def uri: Uri = implicitly[UriCapable[Res]].uri(res) } } @@ -33,13 +32,15 @@ trait UriCapable[-Res] { } object Linkable { - class Capability[Res: Linkable](res: Res) { + class Capability[Res : Linkable](res: Res) { def link: PathLink = implicitly[Linkable[Res]].link(res) } - implicit def linkableUri[Res: UriCapable]: Linkable[Res] = new Linkable[Res] { - def link(res: Res): PathLink = PathLink(implicitly[UriCapable[Res]].uri(res).toString) - } + implicit def linkableUri[Res : UriCapable]: Linkable[Res] = + new Linkable[Res] { + def link(res: Res): PathLink = + PathLink(implicitly[UriCapable[Res]].uri(res).toString) + } } object PathLink { diff --git a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/ast.scala b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/ast.scala index 4676a85..43fed52 100644 --- a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/ast.scala +++ b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.xmlBackends.stdlib @@ -26,13 +26,14 @@ import rapture.data.MissingValueException import scala.xml._ private[stdlib] object StdlibAst extends XmlBufferAst { - + override def dereferenceObject(obj: Any, element: String): Any = obj match { case n: Node if n.child.exists(_.label == element) => n \ element - case ns: NodeSeq if ns.exists(_.child.exists(_.label == element)) => ns \ element + case ns: NodeSeq if ns.exists(_.child.exists(_.label == element)) => + ns \ element case _ => throw MissingValueException() } - + override def getChildren(obj: Any): Seq[Any] = obj match { case n: Node => n.child.to[List] case n: NodeSeq => n.flatMap(_.child).to[List] @@ -48,13 +49,20 @@ private[stdlib] object StdlibAst extends XmlBufferAst { case ns: NodeSeq => ns.text case _ => throw TypeMismatchException(getType(string), DataTypes.String) } - + def getObject(obj: Any): Map[String, Any] = obj match { - case n: Node => n.child.map { e => e.label -> e.child }.toMap - case n: NodeSeq => n.flatMap(_.child.map { e => e.label -> e.child }).toMap + case n: Node => + n.child.map { e => + e.label -> e.child + }.toMap + case n: NodeSeq => + n.flatMap(_.child.map { e => + e.label -> e.child + }) + .toMap case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def getLabel(obj: Any): String = obj match { case n: Node => n.label case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) @@ -67,35 +75,36 @@ private[stdlib] object StdlibAst extends XmlBufferAst { def setObjectValue(obj: Any, name: String, value: Any): Any = fromObject(getObject(obj).updated(name, value)) - + def removeObjectValue(obj: Any, name: String): Any = obj match { - case obj: Map[_, _] => obj.asInstanceOf[Map[String, Any]] - name + case obj: Map [_, _] => obj.asInstanceOf[Map[String, Any]] - name case _ => throw TypeMismatchException(getType(obj), DataTypes.Object) } - + def addArrayValue(array: Any, value: Any): Any = array match { case array: NodeSeq => array :+ value case _ => throw TypeMismatchException(getType(array), DataTypes.Array) } def setArrayValue(array: Any, index: Int, value: Any): Any = array match { - case array: NodeSeq => + case array: NodeSeq => new NodeSeq { - def theSeq = array.patch(index, List(value.asInstanceOf[Node]), 1).to[List] - } + def theSeq = + array.patch(index, List(value.asInstanceOf[Node]), 1).to[List] + } case _ => throw TypeMismatchException(getType(array), DataTypes.Array) - } + } def isPi(any: Any): Boolean = any match { case ProcInstr(_, _) => true case _ => false - } + } def getPiText(any: Any): String = any match { case ProcInstr(_, text) => text case _ => throw TypeMismatchException(getType(any), DataTypes.Object) - } - + } + def isComment(any: Any): Boolean = any match { case Comment(_) => true case _ => false @@ -105,12 +114,12 @@ private[stdlib] object StdlibAst extends XmlBufferAst { case Comment(text) => text case _ => throw TypeMismatchException(getType(any), DataTypes.Object) } - + def getPiTarget(any: Any): String = any match { case ProcInstr(target, _) => target case _ => throw TypeMismatchException(getType(any), DataTypes.Object) } - + def isArray(array: Any): Boolean = array match { case n: Node => false case ns: NodeSeq => true @@ -121,25 +130,30 @@ private[stdlib] object StdlibAst extends XmlBufferAst { case Text(_) => true case _ => false } - + def isObject(obj: Any): Boolean = obj match { case _: Node => true case _: NodeSeq => true case _ => false } - + def isNull(obj: Any): Boolean = false - - def fromArray(array: Seq[Any]): Any = array.collect { case e: NodeSeq => e }.foldLeft(NodeSeq.Empty)(_ ++ _) - - def fromObject(obj: Map[String,Any]): Any = obj.to[List].collect { case (k, v: NodeSeq) => - Elem(null, k, Null, TopScope, true, v: _*): NodeSeq - }.foldLeft(NodeSeq.Empty)(_ ++ _) - + + def fromArray(array: Seq[Any]): Any = + array.collect { case e: NodeSeq => e }.foldLeft(NodeSeq.Empty)(_ ++ _) + + def fromObject(obj: Map[String, Any]): Any = + obj + .to[List] + .collect { + case (k, v: NodeSeq) => + Elem(null, k, Null, TopScope, true, v: _*): NodeSeq + } + .foldLeft(NodeSeq.Empty)(_ ++ _) + def fromString(string: String): Any = Text(string) override val nullValue = "" override def toString = "" - } diff --git a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/extractors.scala b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/extractors.scala index a61ce0d..f34fbe5 100644 --- a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/extractors.scala +++ b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/extractors.scala @@ -13,9 +13,8 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.xmlBackends.stdlib -private[stdlib] trait Extractors { -} +private[stdlib] trait Extractors {} diff --git a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/package.scala b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/package.scala index 193df0d..f8c6b6f 100644 --- a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/package.scala +++ b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.xmlBackends.stdlib @@ -21,5 +21,6 @@ import rapture.xml._ object `package` extends Extractors with Serializers { implicit val implicitXmlAst: XmlBufferAst = StdlibAst - implicit val implicitXmlStringParser: StdlibStringParser.type = StdlibStringParser + implicit val implicitXmlStringParser: StdlibStringParser.type = + StdlibStringParser } diff --git a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/parse.scala b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/parse.scala index 8ef8727..3a94db2 100644 --- a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/parse.scala +++ b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/parse.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.xmlBackends.stdlib @@ -23,10 +23,12 @@ import rapture.xml._ import scala.xml._ -private[stdlib] object StdlibStringParser extends Parser[String, XmlBufferAst] { - +private[stdlib] object StdlibStringParser + extends Parser[String, XmlBufferAst] { + override def toString = "" - + val ast = StdlibAst - def parse(s: String): Option[Any] = try Some(XML.loadString(s)) catch { case e: Exception => None } + def parse(s: String): Option[Any] = + try Some(XML.loadString(s)) catch { case e: Exception => None } } diff --git a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/serializers.scala b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/serializers.scala index af03c7c..3c91514 100644 --- a/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/serializers.scala +++ b/xml-stdlib/shared/src/main/scala/rapture/xml-stdlib/serializers.scala @@ -13,9 +13,8 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.xmlBackends.stdlib -private[stdlib] trait Serializers { -} +private[stdlib] trait Serializers {} diff --git a/xml-test/shared/src/main/scala/rapture/xml-test/tests.scala b/xml-test/shared/src/main/scala/rapture/xml-test/tests.scala index c63aec9..a46cbac 100644 --- a/xml-test/shared/src/main/scala/rapture/xml-test/tests.scala +++ b/xml-test/shared/src/main/scala/rapture/xml-test/tests.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml.test @@ -41,11 +41,15 @@ private[test] case class E(e: F) private[test] case class F(f: Int) import xmlBackends._ -class StdlibTests() extends XmlTests(stdlib.implicitXmlAst, stdlib.implicitXmlStringParser) +class StdlibTests() + extends XmlTests(stdlib.implicitXmlAst, stdlib.implicitXmlStringParser) -class MutableStdlibTests() extends MutableXmlTests(stdlib.implicitXmlAst, stdlib.implicitXmlStringParser) +class MutableStdlibTests() + extends MutableXmlTests( + stdlib.implicitXmlAst, stdlib.implicitXmlStringParser) -abstract class XmlTests(ast: XmlAst, parser: Parser[String, XmlAst]) extends TestSuite { +abstract class XmlTests(ast: XmlAst, parser: Parser[String, XmlAst]) + extends TestSuite { implicit def implicitAst: XmlAst = ast implicit def implicitParser: Parser[String, XmlAst] = parser @@ -81,103 +85,127 @@ abstract class XmlTests(ast: XmlAst, parser: Parser[String, XmlAst]) extends Tes 0 """ - val `Extract Int` = test { - source1.int.as[Int] - } returns 42 - - val `Extract Option[Int]` = test { - source1.int.as[Option[Int]] - } returns Some(42) - - val `Extract Option[Int], wrong type` = test { - source1.string.as[Option[Int]] - } returns None - - val `Extract Double` = test { - source1.double.as[Double] - } returns 3.14159 - - val `Extract Boolean` = test { - source1.boolean.as[Boolean] - } returns true - - val `Extract String` = test { - source1.string.as[String] - } returns "Hello" - - val `Extract List[Int]` = test { - source1.list.item.as[List[Int]] - } returns List(1, 2, 3) - - val `Extract Vector[Int]` = test { - source1.list.item.as[Vector[Int]] - } returns Vector(1, 2, 3) - - val `Extract case class` = test { - source1.foo.as[Foo] - } returns Foo("test", 1) - - val `Extract case class with missing optional value` = test { - source1.baz.as[Baz] - } returns Baz("test", None) - - val `Extract case class with missing tried value` = test { - source1.baz.as[Baz2] - } returns Baz2("test", util.Failure(MissingValueException())) - - val `Extract case class with present optional value` = test { - source1.baz2.as[Baz] - } returns Baz("test", Some(7)) - - val `Extract case class with present tried value` = test { - source1.baz2.as[Baz2] - } returns Baz2("test", util.Success(7)) - - val `Extract nested case class` = test { - source1.bar.as[Bar] - } returns Bar(Foo("test2", 2), 2.7) - - val `Extract deeply-nested case class` = test { - xml"""1""".as[A] - } returns A(B(C(D(E(F(1)))))) - - val `Extract List element` = test { - source1.list.item(1).as[Int] - } returns 2 - - val `Extract object element` = test { - source1.bar.foo.alpha.as[String] - } returns "test2" - - val `Extract missing value with case class default` = test { - xml"""0""".as[HasDefault] - } returns HasDefault("yes", 0) - - val `Extract missing value with case class default 2` = test { - xml"""no""".as[HasDefault2] - } returns HasDefault2("no", 1) - - val `Extract case class ignoring default value` = test { - xml"""0no""".as[HasDefault2] - } returns HasDefault2("no", 0) - - val `Check type failure` = test { - source1.string.as[Int] - } throws InvalidNumber("Hello", "integer") - - val `Check missing value failure` = test { - source1.nothing.as[Int] - } throws MissingValueException() + val `Extract Int` = + test { + source1.int.as[Int] + } returns 42 + + val `Extract Option[Int]` = + test { + source1.int.as[Option[Int]] + } returns Some(42) + + val `Extract Option[Int], wrong type` = + test { + source1.string.as[Option[Int]] + } returns None + + val `Extract Double` = + test { + source1.double.as[Double] + } returns 3.14159 + + val `Extract Boolean` = + test { + source1.boolean.as[Boolean] + } returns true + + val `Extract String` = + test { + source1.string.as[String] + } returns "Hello" + + val `Extract List[Int]` = + test { + source1.list.item.as[List[Int]] + } returns List(1, 2, 3) + + val `Extract Vector[Int]` = + test { + source1.list.item.as[Vector[Int]] + } returns Vector(1, 2, 3) + + val `Extract case class` = + test { + source1.foo.as[Foo] + } returns Foo("test", 1) + + val `Extract case class with missing optional value` = + test { + source1.baz.as[Baz] + } returns Baz("test", None) + + val `Extract case class with missing tried value` = + test { + source1.baz.as[Baz2] + } returns Baz2("test", util.Failure(MissingValueException())) + + val `Extract case class with present optional value` = + test { + source1.baz2.as[Baz] + } returns Baz("test", Some(7)) + + val `Extract case class with present tried value` = + test { + source1.baz2.as[Baz2] + } returns Baz2("test", util.Success(7)) + + val `Extract nested case class` = + test { + source1.bar.as[Bar] + } returns Bar(Foo("test2", 2), 2.7) + + val `Extract deeply-nested case class` = + test { + xml"""1""".as[A] + } returns A(B(C(D(E(F(1)))))) + + val `Extract List element` = + test { + source1.list.item(1).as[Int] + } returns 2 + + val `Extract object element` = + test { + source1.bar.foo.alpha.as[String] + } returns "test2" + + val `Extract missing value with case class default` = + test { + xml"""0""".as[HasDefault] + } returns HasDefault("yes", 0) + + val `Extract missing value with case class default 2` = + test { + xml"""no""".as[HasDefault2] + } returns HasDefault2("no", 1) + + val `Extract case class ignoring default value` = + test { + xml"""0no""".as[HasDefault2] + } returns HasDefault2("no", 0) + + val `Check type failure` = + test { + source1.string.as[Int] + } throws InvalidNumber("Hello", "integer") + + val `Check missing value failure` = + test { + source1.nothing.as[Int] + } throws MissingValueException() // FIXME: Add pattern-matching tests - val `Serialize string` = test { - Xml("Hello World!").toString - } returns "Hello World!" + val `Serialize string` = + test { + Xml("Hello World!").toString + } returns "Hello World!" - val `Serialize int` = test { - Xml(1648).toString - } returns "1648" + val `Serialize int` = + test { + Xml(1648).toString + } returns "1648" /*val `Serialize array` = test { Json(List(1, 2, 3)).toString @@ -202,18 +230,18 @@ abstract class XmlTests(ast: XmlAst, parser: Parser[String, XmlAst]) extends Tes val x = xml"""{"foo":"bar"}""" j.as[Option[String]] } returns None*/ - - } -abstract class MutableXmlTests(ast: XmlBufferAst, parser: Parser[String, XmlBufferAst]) extends TestSuite { - +abstract class MutableXmlTests( + ast: XmlBufferAst, parser: Parser[String, XmlBufferAst]) + extends TestSuite { + implicit def implicitAst: XmlBufferAst = ast implicit def implicitParser: Parser[String, XmlBufferAst] = parser case class Foo(alpha: String, beta: Int) case class Bar(foo: Foo, gamma: Double) - + val source1 = xmlBuffer""" Hello 42 diff --git a/xml/shared/src/main/scala/rapture/xml/ast.scala b/xml/shared/src/main/scala/rapture/xml/ast.scala index a9ee007..157d21f 100644 --- a/xml/shared/src/main/scala/rapture/xml/ast.scala +++ b/xml/shared/src/main/scala/rapture/xml/ast.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -26,7 +26,8 @@ trait XmlAst extends DataAst { def isScalar(any: Any) = isString(any) - def getScala(any: Any) = Try(getString(any)) getOrElse { throw new Exception } + def getScala(any: Any) = + Try(getString(any)) getOrElse { throw new Exception } def getString(string: Any): String @@ -44,26 +45,28 @@ trait XmlAst extends DataAst { /** Tests if the element represents a `String` */ def isString(any: Any): Boolean - + /** Returns the DataType instance for the particular type. */ def getType(any: Any): DataTypes.DataType = - if(isString(any)) DataTypes.String - else if(isObject(any)) DataTypes.Object - else if(isArray(any)) DataTypes.Array + if (isString(any)) DataTypes.String + else if (isObject(any)) DataTypes.Object + else if (isArray(any)) DataTypes.Array else throw MissingValueException() def convert(v: Any, ast: DataAst): Any = { val oldAst = ast.asInstanceOf[XmlAst] - if(oldAst.isString(v)) fromString(oldAst.getString(v)) - else if(oldAst.isArray(v)) fromArray(oldAst.getArray(v).map(convert(_, oldAst))) - else if(oldAst.isObject(v)) fromObject(oldAst.getObject(v).mapValues(convert(_, oldAst))) + if (oldAst.isString(v)) fromString(oldAst.getString(v)) + else if (oldAst.isArray(v)) + fromArray(oldAst.getArray(v).map(convert(_, oldAst))) + else if (oldAst.isObject(v)) + fromObject(oldAst.getObject(v).mapValues(convert(_, oldAst))) else nullValue } val nullValue = "" - protected def typeTest(pf: PartialFunction[Any, Unit])(v: Any) = pf.isDefinedAt(v) + protected def typeTest(pf: PartialFunction[Any, Unit])(v: Any) = + pf.isDefinedAt(v) } trait XmlBufferAst extends XmlAst with MutableDataAst - diff --git a/xml/shared/src/main/scala/rapture/xml/context.scala b/xml/shared/src/main/scala/rapture/xml/context.scala index 9970cfb..3355285 100644 --- a/xml/shared/src/main/scala/rapture/xml/context.scala +++ b/xml/shared/src/main/scala/rapture/xml/context.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -24,43 +24,54 @@ import rapture.data._ import language.experimental.macros private[xml] object XmlDataMacros extends DataContextMacros[Xml, XmlAst] { - - def companion(c: BlackboxContext): c.Expr[DataCompanion[Xml, XmlAst]] = c.universe.reify(Xml) - - def parseSource(s: List[String], stringsUsed: List[Boolean]) = try { - XmlValidator.validate(s) - None - } catch { - case XmlValidator.ValidationException(strNo, pos, expected, found) => - val f = if(found == '\u0000') "end of input" else s"'$found'" - Some((strNo, pos, s"failed to parse Xml literal: expected $expected, but found $f")) - case XmlValidator.DuplicateKeyException(strNo, pos, key) => - Some((strNo, pos, s"""duplicate key found in Xml literal: "$key"""")) - } - - override def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[Xml]]*) - (parser: c.Expr[Parser[String, XmlAst]]): c.Expr[Xml] = - super.contextMacro(c)(exprs: _*)(parser) + def companion(c: BlackboxContext): c.Expr[DataCompanion[Xml, XmlAst]] = + c.universe.reify(Xml) + + def parseSource(s: List[String], stringsUsed: List[Boolean]) = + try { + XmlValidator.validate(s) + None + } catch { + case XmlValidator.ValidationException(strNo, pos, expected, found) => + val f = if (found == '\u0000') "end of input" else s"'$found'" + Some( + (strNo, + pos, + s"failed to parse Xml literal: expected $expected, but found $f")) + case XmlValidator.DuplicateKeyException(strNo, pos, key) => + Some((strNo, pos, s"""duplicate key found in Xml literal: "$key"""")) + } + + override def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[Xml]]*)( + parser: c.Expr[Parser[String, XmlAst]]): c.Expr[Xml] = + super.contextMacro(c)(exprs: _*)(parser) } -private[xml] object XmlBufferDataMacros extends DataContextMacros[XmlBuffer, XmlBufferAst] { - - def companion(c: BlackboxContext): c.Expr[DataCompanion[XmlBuffer, XmlBufferAst]] = +private[xml] object XmlBufferDataMacros + extends DataContextMacros[XmlBuffer, XmlBufferAst] { + + def companion( + c: BlackboxContext): c.Expr[DataCompanion[XmlBuffer, XmlBufferAst]] = c.universe.reify(XmlBuffer) - def parseSource(s: List[String], stringsUsed: List[Boolean]) = try { - XmlValidator.validate(s) - None - } catch { - case XmlValidator.ValidationException(strNo, pos, expected, found) => - val f = if(found == '\u0000') "end of input" else s"'$found'" - Some((strNo, pos, - s"Failed to parse XmlBuffer literal: Expected $expected, but found $f.")) - } - - override def contextMacro(c: BlackboxContext)(exprs: c.Expr[ForcedConversion[XmlBuffer]]*) - (parser: c.Expr[Parser[String, XmlBufferAst]]): c.Expr[XmlBuffer] = + def parseSource(s: List[String], stringsUsed: List[Boolean]) = + try { + XmlValidator.validate(s) + None + } catch { + case XmlValidator.ValidationException(strNo, pos, expected, found) => + val f = if (found == '\u0000') "end of input" else s"'$found'" + Some( + (strNo, + pos, + s"Failed to parse XmlBuffer literal: Expected $expected, but found $f.")) + } + + override def contextMacro(c: BlackboxContext)( + exprs: c.Expr[ForcedConversion[XmlBuffer]]*)( + parser: c.Expr[Parser[String, XmlBufferAst]]): c.Expr[XmlBuffer] = super.contextMacro(c)(exprs: _*)(parser) } @@ -69,17 +80,16 @@ private[xml] object XmlBufferDataMacros extends DataContextMacros[XmlBuffer, Xml * from a XML string. */ private[xml] class XmlStrings(sc: StringContext) { class XmlContext() extends DataContext(Xml, sc) { - def apply(exprs: ForcedConversion[Xml]*)(implicit parser: Parser[String, XmlAst]): Xml = - macro XmlDataMacros.contextMacro + def apply(exprs: ForcedConversion[Xml]*)( + implicit parser: Parser[String, XmlAst]): Xml = macro XmlDataMacros.contextMacro } val xml = new XmlContext() } private[xml] class XmlBufferStrings(sc: StringContext) { class XmlBufferContext() extends DataContext(XmlBuffer, sc) { - def apply(exprs: ForcedConversion[XmlBuffer]*)(implicit parser: Parser[String, - XmlBufferAst]): XmlBuffer = - macro XmlBufferDataMacros.contextMacro + def apply(exprs: ForcedConversion[XmlBuffer]*)( + implicit parser: Parser[String, XmlBufferAst]): XmlBuffer = macro XmlBufferDataMacros.contextMacro } val xmlBuffer = new XmlBufferContext() } diff --git a/xml/shared/src/main/scala/rapture/xml/extractors.scala b/xml/shared/src/main/scala/rapture/xml/extractors.scala index a0e756f..74edd8f 100644 --- a/xml/shared/src/main/scala/rapture/xml/extractors.scala +++ b/xml/shared/src/main/scala/rapture/xml/extractors.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -24,56 +24,83 @@ import scala.util._ import language.higherKinds -private[xml] case class XmlCastExtractor[T](ast: XmlAst, dataType: DataTypes.DataType) +private[xml] case class XmlCastExtractor[T]( + ast: XmlAst, dataType: DataTypes.DataType) private[xml] trait Extractors extends Extractors_1 { - implicit def optionExtractor[T](implicit ext: Extractor[T, Xml]): Extractor[Option[T], Xml] { type Throws = - Nothing } = GeneralExtractors.optionExtractor[Xml, T] + implicit def optionExtractor[T](implicit ext: Extractor[T, Xml] + ): Extractor[Option[T], Xml] { type Throws = Nothing } = + GeneralExtractors.optionExtractor[Xml, T] - implicit def tryExtractor[T](implicit ext: Extractor[T, Xml]): Extractor[Try[T], Xml] { type Throws = - Nothing } = GeneralExtractors.tryExtractor[Xml, T] + implicit def tryExtractor[T](implicit ext: Extractor[T, Xml] + ): Extractor[Try[T], Xml] { type Throws = Nothing } = + GeneralExtractors.tryExtractor[Xml, T] + + implicit def genSeqExtractor[T, Coll[_]]( + implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], + ext: Extractor[T, Xml] + ): Extractor[Coll[T], Xml] { type Throws = ext.Throws } = { - implicit def genSeqExtractor[T, Coll[_]](implicit cbf: scala.collection.generic.CanBuildFrom[Nothing, T, Coll[T]], - ext: Extractor[T, Xml]): Extractor[Coll[T], Xml] { type Throws = ext.Throws } = { - GeneralExtractors.genSeqExtractor[T, Coll, Xml] } - - implicit def xmlExtractor(implicit ast: XmlAst): Extractor[Xml, Xml] { type Throws = DataGetException } = + + implicit def xmlExtractor(implicit ast: XmlAst + ): Extractor[Xml, Xml] { type Throws = DataGetException } = new Extractor[Xml, Xml] { type Throws = DataGetException - def extract(any: Xml, dataAst: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[Xml, DataGetException] = - mode.wrap(mode.catching[DataGetException, Xml](any.$wrap(any.$normalize))) + def extract(any: Xml, + dataAst: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[Xml, DataGetException] = + mode.wrap( + mode.catching[DataGetException, Xml](any.$wrap(any.$normalize))) } - } private[xml] trait Extractors_1 { - - implicit def stringableExtractors[T](implicit ext: StringParser[T]): Extractor[T, Xml] { - type Throws = DataGetException with ext.Throws } = new Extractor[T, Xml] { - + + implicit def stringableExtractors[T](implicit ext: StringParser[T] + ): Extractor[T, Xml] { + type Throws = DataGetException with ext.Throws + } = new Extractor[T, Xml] { + type Throws = DataGetException with ext.Throws - def extract(any: Xml, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DataGetException with ext.Throws] = mode.wrap { - val value: String = mode.catching[DataGetException, String](any.$ast.getString(any.$normalize)) + def extract(any: Xml, + ast: DataAst, + mode: Mode[_ <: MethodConstraint] + ): mode.Wrap[T, DataGetException with ext.Throws] = mode.wrap { + val value: String = mode.catching[DataGetException, String]( + any.$ast.getString(any.$normalize)) mode.unwrap(ext.parse(value, mode)) } } - - implicit def xmlBufferExtractor[T](implicit xmlAst: XmlAst, ext: Extractor[T, Xml]): - Extractor[T, XmlBuffer] { type Throws = ext.Throws } = new Extractor[T, XmlBuffer] { - type Throws = ext.Throws - def extract(any: XmlBuffer, ast: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, ext.Throws] = - ext.extract(Xml.construct(MutableCell(any.$root.value), Vector()), ast, mode) - } - - implicit def xmlBufferToXmlExtractor(implicit ast: XmlBufferAst): Extractor[XmlBuffer, Xml] = + + implicit def xmlBufferExtractor[T](implicit xmlAst: XmlAst, + ext: Extractor[T, Xml] + ): Extractor[T, XmlBuffer] { type Throws = ext.Throws } = + new Extractor[T, XmlBuffer] { + type Throws = ext.Throws + def extract( + any: XmlBuffer, + ast: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, ext.Throws] = + ext.extract( + Xml.construct(MutableCell(any.$root.value), Vector()), ast, mode) + } + + implicit def xmlBufferToXmlExtractor( + implicit ast: XmlBufferAst): Extractor[XmlBuffer, Xml] = new Extractor[XmlBuffer, Xml] { type Throws = DataGetException - def extract(any: Xml, dataAst: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[XmlBuffer, Throws] = - mode.wrap(XmlBuffer.construct(MutableCell(XmlDataType.xmlSerializer.serialize(any)), Vector())) + def extract( + any: Xml, + dataAst: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[XmlBuffer, Throws] = + mode.wrap( + XmlBuffer.construct( + MutableCell(XmlDataType.xmlSerializer.serialize(any)), + Vector())) } - } diff --git a/xml/shared/src/main/scala/rapture/xml/formatters.scala b/xml/shared/src/main/scala/rapture/xml/formatters.scala index 80f0b42..0e4b325 100644 --- a/xml/shared/src/main/scala/rapture/xml/formatters.scala +++ b/xml/shared/src/main/scala/rapture/xml/formatters.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -22,14 +22,16 @@ import rapture.data._ object formatters { object compact { - def apply[Ast <: XmlAst]()(implicit ast: Ast): Formatter[Ast] { type Out = String } = xmlFormatterImplicit[Ast] + def apply[Ast <: XmlAst]()( + implicit ast: Ast): Formatter[Ast] { type Out = String } = + xmlFormatterImplicit[Ast] - implicit def xmlFormatterImplicit[Ast <: XmlAst](implicit ast: Ast): Formatter[Ast] { type Out = String } = + implicit def xmlFormatterImplicit[Ast <: XmlAst]( + implicit ast: Ast): Formatter[Ast] { type Out = String } = new Formatter[Ast] { type Out = String // FIXME: This is a lazy implementation def format(xml: Any): String = xml.toString - } + } } } - diff --git a/xml/shared/src/main/scala/rapture/xml/macros.scala b/xml/shared/src/main/scala/rapture/xml/macros.scala index 71f49b4..0169563 100644 --- a/xml/shared/src/main/scala/rapture/xml/macros.scala +++ b/xml/shared/src/main/scala/rapture/xml/macros.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -21,17 +21,18 @@ import rapture.base._ import rapture.data._ private[xml] object XmlMacros { - def xmlExtractorMacro[T: c.WeakTypeTag, Th](c: WhiteboxContext): c.Expr[Extractor[T, Xml] { type Throws = Th }] = + def xmlExtractorMacro[T : c.WeakTypeTag, Th]( + c: WhiteboxContext): c.Expr[Extractor[T, Xml] { type Throws = Th }] = Macros.extractorMacro[T, Xml, Th](c) - + //def xmlBufferExtractorMacro[T: c.WeakTypeTag](c: Context) = // Macros.extractorMacro2[T, XmlBuffer](c) - - def xmlSerializerMacro[T: c.WeakTypeTag](c: WhiteboxContext)(ast: c.Expr[XmlAst]): - c.Expr[Serializer[T, Xml]] = + + def xmlSerializerMacro[T : c.WeakTypeTag](c: WhiteboxContext)( + ast: c.Expr[XmlAst]): c.Expr[Serializer[T, Xml]] = Macros.serializerMacro[T, Xml](c)(ast) - - def xmlBufferSerializerMacro[T: c.WeakTypeTag](c: WhiteboxContext)(ast: c.Expr[XmlBufferAst]): - c.Expr[Serializer[T, XmlBuffer]] = + + def xmlBufferSerializerMacro[T : c.WeakTypeTag](c: WhiteboxContext)( + ast: c.Expr[XmlBufferAst]): c.Expr[Serializer[T, XmlBuffer]] = Macros.serializerMacro[T, XmlBuffer](c)(ast) } diff --git a/xml/shared/src/main/scala/rapture/xml/package.scala b/xml/shared/src/main/scala/rapture/xml/package.scala index 1098348..d7d9af5 100644 --- a/xml/shared/src/main/scala/rapture/xml/package.scala +++ b/xml/shared/src/main/scala/rapture/xml/package.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -33,10 +33,11 @@ object `package` { val TypeMismatchException = rapture.data.TypeMismatchException val MissingValueException = rapture.data.MissingValueException - implicit def xmlStringContext(sc: StringContext)(implicit parser: Parser[String, XmlAst]) = + implicit def xmlStringContext(sc: StringContext)( + implicit parser: Parser[String, XmlAst]) = new XmlStrings(sc) - - implicit def xmlBufferStringContext(sc: StringContext) - (implicit parser: Parser[String, XmlBufferAst]) = + + implicit def xmlBufferStringContext(sc: StringContext)( + implicit parser: Parser[String, XmlBufferAst]) = new XmlBufferStrings(sc) } diff --git a/xml/shared/src/main/scala/rapture/xml/serializers.scala b/xml/shared/src/main/scala/rapture/xml/serializers.scala index fd682ac..9bbe6e2 100644 --- a/xml/shared/src/main/scala/rapture/xml/serializers.scala +++ b/xml/shared/src/main/scala/rapture/xml/serializers.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -27,31 +27,40 @@ private[xml] case class DirectXmlSerializer[T](ast: XmlAst) private[xml] trait Serializers { case class BasicXmlSerializer[T](serialization: T => Any) - extends Serializer[T, Xml] { def serialize(t: T): Any = serialization(t) } - - implicit def xmlBufferSerializer[T](implicit ser: Serializer[T, Xml]): - Serializer[T, XmlBuffer] = - new Serializer[T, XmlBuffer] { def serialize(t: T): Any = ser.serialize(t) } + extends Serializer[T, Xml] { + def serialize(t: T): Any = serialization(t) + } + + implicit def xmlBufferSerializer[T]( + implicit ser: Serializer[T, Xml]): Serializer[T, XmlBuffer] = + new Serializer[T, XmlBuffer] { + def serialize(t: T): Any = ser.serialize(t) + } implicit def intSerializer(implicit ast: XmlAst): Serializer[Int, Xml] = BasicXmlSerializer(ast fromString _.toString) - implicit def booleanSerializer(implicit ast: XmlAst): Serializer[Boolean, Xml] = + implicit def booleanSerializer( + implicit ast: XmlAst): Serializer[Boolean, Xml] = BasicXmlSerializer(ast fromString _.toString) - implicit def stringSerializer(implicit ast: XmlAst): Serializer[String, Xml] = + implicit def stringSerializer( + implicit ast: XmlAst): Serializer[String, Xml] = BasicXmlSerializer(ast fromString _) implicit def floatSerializer(implicit ast: XmlAst): Serializer[Float, Xml] = BasicXmlSerializer(ast fromString _.toString) - implicit def doubleSerializer(implicit ast: XmlAst): Serializer[Double, Xml] = + implicit def doubleSerializer( + implicit ast: XmlAst): Serializer[Double, Xml] = BasicXmlSerializer(ast fromString _.toString) - implicit def bigDecimalSerializer(implicit ast: XmlAst): Serializer[BigDecimal, Xml] = + implicit def bigDecimalSerializer( + implicit ast: XmlAst): Serializer[BigDecimal, Xml] = BasicXmlSerializer(ast fromString _.toString) - implicit def bigIntSerializer(implicit ast: XmlAst): Serializer[BigInt, Xml] = + implicit def bigIntSerializer( + implicit ast: XmlAst): Serializer[BigInt, Xml] = BasicXmlSerializer(ast fromString _.toString) implicit def longSerializer(implicit ast: XmlAst): Serializer[Long, Xml] = @@ -66,28 +75,34 @@ private[xml] trait Serializers { implicit def nilSerializer(implicit ast: XmlAst): Serializer[Nil.type, Xml] = BasicXmlSerializer(v => ast fromArray Nil) - implicit def traversableSerializer[Type, Coll[T] <: Traversable[T]] - (implicit ast: XmlAst, ser: Serializer[Type, Xml]): Serializer[Coll[Type], Xml] = + implicit def traversableSerializer[Type, Coll[T] <: Traversable[T]]( + implicit ast: XmlAst, + ser: Serializer[Type, Xml]): Serializer[Coll[Type], Xml] = BasicXmlSerializer(ast fromArray _.map(ser.serialize).to[List]) - implicit def optionSerializer[Type] - (implicit ast: XmlAst, ser: Serializer[Type, Xml]): Serializer[Option[Type], Xml] = + implicit def optionSerializer[Type]( + implicit ast: XmlAst, + ser: Serializer[Type, Xml]): Serializer[Option[Type], Xml] = BasicXmlSerializer(_ map ser.serialize getOrElse ast.nullValue) - implicit def mapSerializer[Type, Ast <: XmlAst] - (implicit ast: Ast, ser: Serializer[Type, Xml]): Serializer[Map[String, Type], Xml] = + implicit def mapSerializer[Type, Ast <: XmlAst]( + implicit ast: Ast, + ser: Serializer[Type, Xml]): Serializer[Map[String, Type], Xml] = new Serializer[Map[String, Type], Xml] { - def serialize(m: Map[String, Type]) = ast.fromObject(m.mapValues(ser.serialize)) + def serialize(m: Map[String, Type]) = + ast.fromObject(m.mapValues(ser.serialize)) } - implicit def directXmlSerializer[T: DirectXmlSerializer](implicit ast: XmlAst): - Serializer[T, Xml] = - BasicXmlSerializer(obj => xmlSerializer.serialize(Xml.construct(MutableCell(obj), - Vector())(?[DirectXmlSerializer[T]].ast))) + implicit def directXmlSerializer[T : DirectXmlSerializer]( + implicit ast: XmlAst): Serializer[T, Xml] = + BasicXmlSerializer( + obj => + xmlSerializer.serialize(Xml.construct(MutableCell(obj), Vector())( + ?[DirectXmlSerializer[T]].ast))) - implicit def xmlSerializer[XmlType <: XmlDataType[XmlType, _ <: XmlAst]] - (implicit ast: XmlAst): Serializer[XmlType, Xml] = + implicit def xmlSerializer[XmlType <: XmlDataType[XmlType, _ <: XmlAst]]( + implicit ast: XmlAst): Serializer[XmlType, Xml] = BasicXmlSerializer[XmlType]({ j => - if(j.$ast == ast) j.$normalize else ast.convert(j.$normalize, j.$ast) + if (j.$ast == ast) j.$normalize else ast.convert(j.$normalize, j.$ast) }) } diff --git a/xml/shared/src/main/scala/rapture/xml/validator.scala b/xml/shared/src/main/scala/rapture/xml/validator.scala index 7613833..0ecfef2 100644 --- a/xml/shared/src/main/scala/rapture/xml/validator.scala +++ b/xml/shared/src/main/scala/rapture/xml/validator.scala @@ -13,32 +13,38 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml private[xml] object XmlValidator { - case class ValidationException(strNo: Int, pos: Int, expected: String, found: Char) + case class ValidationException( + strNo: Int, pos: Int, expected: String, found: Char) extends Exception - - case class DuplicateKeyException(strNo: Int, pos: Int, key: String) extends Exception - + + case class DuplicateKeyException(strNo: Int, pos: Int, key: String) + extends Exception + def validate(parts: List[String]) = { var i = 0 var n = 0 var stack: List[String] = Nil def s = parts(n) - def cur = if(i >= s.length) '\u0000' else s(i) - def ahead(j: Int) = if(i + j >= s.length) '\u0000' else s(i + j) + def cur = if (i >= s.length) '\u0000' else s(i) + def ahead(j: Int) = if (i + j >= s.length) '\u0000' else s(i + j) def fail(expected: String) = throw ValidationException(n, i, expected, cur) - def failPosition(expected: String) = throw ValidationException(n, i, expected, cur) - def duplicateKey(start: Int, key: String) = throw DuplicateKeyException(n, start, key) - - def takeWhitespace(): Unit = while(cur.isWhitespace) next() + def failPosition(expected: String) = + throw ValidationException(n, i, expected, cur) + def duplicateKey(start: Int, key: String) = + throw DuplicateKeyException(n, start, key) + + def takeWhitespace(): Unit = while (cur.isWhitespace) next() - def consume(cs: Char*): Unit = cs foreach { c => if(cur == c) next() else fail(s"'$c'") } + def consume(cs: Char*): Unit = cs foreach { c => + if (cur == c) next() else fail(s"'$c'") + } def next() = i += 1 @@ -50,20 +56,20 @@ private[xml] object XmlValidator { case '!' => takeSpecial() case _ => takeStartTag(i) } - if(!stack.isEmpty) takeText() + if (!stack.isEmpty) takeText() } def takePi(): Unit = { consume('?') takeName() takeWhitespace() - while(i < s.length && cur != '?') next() + while (i < s.length && cur != '?') next() consume('?', '>') } def takeComment(): Unit = { consume("--": _*) - while(i < s.length && !(cur == '-' && ahead(1) == '-')) next() + while (i < s.length && !(cur == '-' && ahead(1) == '-')) next() consume("-->": _*) } @@ -81,7 +87,7 @@ private[xml] object XmlValidator { case _ => fail("CDATA or PCDATA section") } - while(i < s.length && !(cur == ']' && ahead(1) == ']')) next() + while (i < s.length && !(cur == ']' && ahead(1) == ']')) next() consume("]]>": _*) case _ => fail("'-' or '['") } @@ -96,8 +102,8 @@ private[xml] object XmlValidator { def takeName(): String = { val start = i - if(!cur.isLetter) fail("letter") else next() - while(cur.isLetterOrDigit && i < s.length) next() + if (!cur.isLetter) fail("letter") else next() + while (cur.isLetterOrDigit && i < s.length) next() s.substring(start, i) } @@ -148,10 +154,10 @@ private[xml] object XmlValidator { } def takeAttributeValue(): Unit = cur match { - case quot@('\'' | '"') => + case quot @ ('\'' | '"') => consume(quot) var finished = false - while(!finished) cur match { + while (!finished) cur match { case `quot` => consume(quot) finished = true @@ -162,10 +168,10 @@ private[xml] object XmlValidator { } case _ => fail("single or double quote") } - + takeTag() takeWhitespace() - if(i != s.length) fail("end of data") + if (i != s.length) fail("end of data") } } diff --git a/xml/shared/src/main/scala/rapture/xml/xml.scala b/xml/shared/src/main/scala/rapture/xml/xml.scala index b3275a3..8f00443 100644 --- a/xml/shared/src/main/scala/rapture/xml/xml.scala +++ b/xml/shared/src/main/scala/rapture/xml/xml.scala @@ -13,7 +13,7 @@ Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -*/ + */ package rapture.xml @@ -23,11 +23,13 @@ import rapture.data._ import language.experimental.macros private[xml] trait Xml_2 { - implicit def xmlExtractorMacro[T <: Product, Th]: Extractor[T, Xml] { type Throws = Th } = - macro XmlMacros.xmlExtractorMacro[T, Th] + implicit def xmlExtractorMacro[T <: Product, Th]: Extractor[T, Xml] { + type Throws = Th + } = macro XmlMacros.xmlExtractorMacro[T, Th] - implicit def xmlSerializerMacro[T <: Product](implicit ast: XmlAst): Serializer[T, Xml] = - macro XmlMacros.xmlSerializerMacro[T] + implicit def xmlSerializerMacro[T <: Product]( + implicit ast: XmlAst): Serializer[T, Xml] = macro XmlMacros + .xmlSerializerMacro[T] } private[xml] trait Xml_1 extends Xml_2 { @@ -40,96 +42,112 @@ private[xml] class DynamicWorkaround(xml: Xml) { trait `Xml.parse` extends MethodConstraint -private[xml] trait XmlDataCompanion[+Type <: XmlDataType[Type, AstType], - AstType <: XmlAst] extends DataCompanion[Type, AstType] { +private[xml] trait XmlDataCompanion[ + +Type <: XmlDataType[Type, AstType], AstType <: XmlAst] + extends DataCompanion[Type, AstType] { type ParseMethodConstraint = `Xml.parse` - } - private[xml] object XmlDataType extends Extractors with Serializers -private[xml] trait XmlDataType[+T <: XmlDataType[T, AstType], AstType <: XmlAst] +private[xml] trait XmlDataType[ + +T <: XmlDataType[T, AstType], AstType <: XmlAst] extends DataType[T, AstType] object XmlBuffer extends XmlDataCompanion[XmlBuffer, XmlBufferAst] { - - def construct(any: MutableCell, path: Vector[Either[Int, String]])(implicit ast: - XmlBufferAst): XmlBuffer = new XmlBuffer(any, path) + + def construct(any: MutableCell, path: Vector[Either[Int, String]])( + implicit ast: XmlBufferAst): XmlBuffer = new XmlBuffer(any, path) } /** Companion object to the `Xml` type, providing factory and extractor methods, and a XML * pretty printer. */ object Xml extends XmlDataCompanion[Xml, XmlAst] with Xml_1 { - - def construct(any: MutableCell, path: Vector[Either[Int, String]])(implicit ast: - XmlAst): Xml = new Xml(any, path) + + def construct(any: MutableCell, path: Vector[Either[Int, String]])( + implicit ast: XmlAst): Xml = new Xml(any, path) def ast(xml: Xml): XmlAst = xml.$ast - def extractor[T](implicit ext: Extractor[T, Xml]): Extractor[T, Xml] { type Throws = ext.Throws } = ext + def extractor[T](implicit ext: Extractor[T, Xml] + ): Extractor[T, Xml] { type Throws = ext.Throws } = ext def serializer[T](implicit ser: Serializer[T, Xml]) = ser - implicit def xmlCastExtractor[T: XmlCastExtractor](implicit ast: XmlAst): - Extractor[T, XmlDataType[_, _ <: XmlAst]] = + implicit def xmlCastExtractor[T : XmlCastExtractor]( + implicit ast: XmlAst): Extractor[T, XmlDataType[_, _ <: XmlAst]] = new Extractor[T, XmlDataType[_, _ <: XmlAst]] { type Throws = DataGetException - def extract(value: XmlDataType[_, _ <: XmlAst], ast2: DataAst, mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DataGetException] = + def extract( + value: XmlDataType[_, _ <: XmlAst], + ast2: DataAst, + mode: Mode[_ <: MethodConstraint]): mode.Wrap[T, DataGetException] = mode.wrap(ast2 match { case ast2: XmlAst => val norm = mode.catching[DataGetException, Any](value.$normalize) try { - if(ast == ast2) norm.asInstanceOf[T] - else XmlDataType.xmlSerializer.serialize(Xml.construct(MutableCell(norm), - Vector())(ast2)).asInstanceOf[T] - } catch { case e: ClassCastException => - mode.exception[T, DataGetException](TypeMismatchException(ast.getType(norm), - implicitly[XmlCastExtractor[T]].dataType)) + if (ast == ast2) norm.asInstanceOf[T] + else + XmlDataType.xmlSerializer + .serialize(Xml.construct(MutableCell(norm), Vector())(ast2)) + .asInstanceOf[T] + } catch { + case e: ClassCastException => + mode.exception[T, DataGetException](TypeMismatchException( + ast.getType(norm), + implicitly[XmlCastExtractor[T]].dataType)) } case _ => ??? }) } - } /** Represents some parsed XML. */ -class Xml(val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())(implicit - val $ast: XmlAst) extends XmlDataType[Xml, XmlAst] with DynamicData[Xml, XmlAst] { - +class Xml( + val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())( + implicit val $ast: XmlAst) + extends XmlDataType[Xml, XmlAst] with DynamicData[Xml, XmlAst] { + def $wrap(any: Any, path: Vector[Either[Int, String]]): Xml = new Xml(MutableCell(any), path) - + def $deref(path: Vector[Either[Int, String]]): Xml = new Xml($root, path) def $extract(sp: Vector[Either[Int, String]]): Xml = - if(sp.isEmpty) this else sp match { - case Left(i) +: tail => apply(i).$extract(tail) - case Right(e) +: tail => selectDynamic(e).$extract(tail) - } - + if (sp.isEmpty) this + else + sp match { + case Left(i) +: tail => apply(i).$extract(tail) + case Right(e) +: tail => selectDynamic(e).$extract(tail) + } + override def toString = try Xml.format(this)(formatters.compact()($ast)) catch { case e: Exception => "undefined" } } -class XmlBuffer(val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector()) - (implicit val $ast: XmlBufferAst) extends - XmlDataType[XmlBuffer, XmlBufferAst] with - MutableDataType[XmlBuffer, XmlBufferAst] with DynamicData[XmlBuffer, XmlBufferAst] { +class XmlBuffer( + val $root: MutableCell, val $path: Vector[Either[Int, String]] = Vector())( + implicit val $ast: XmlBufferAst) + extends XmlDataType[XmlBuffer, XmlBufferAst] + with MutableDataType[XmlBuffer, XmlBufferAst] + with DynamicData[XmlBuffer, XmlBufferAst] { def $wrap(any: Any, path: Vector[Either[Int, String]]): XmlBuffer = new XmlBuffer(MutableCell(any), path) - - def $deref(path: Vector[Either[Int, String]]): XmlBuffer = new XmlBuffer($root, path) - + + def $deref(path: Vector[Either[Int, String]]): XmlBuffer = + new XmlBuffer($root, path) + def $extract(sp: Vector[Either[Int, String]]): XmlBuffer = - if(sp.isEmpty) this else sp match { - case Left(i) +: tail => apply(i).$extract(tail) - case Right(e) +: tail => selectDynamic(e).$extract(tail) - } - + if (sp.isEmpty) this + else + sp match { + case Left(i) +: tail => apply(i).$extract(tail) + case Right(e) +: tail => selectDynamic(e).$extract(tail) + } + override def toString = try XmlBuffer.format(this)(formatters.compact()($ast)) catch { case e: Exception => "undefined"