Files
sbt/cache/SeparatedCache.scala
T

67 lines
1.7 KiB
Scala
Raw Normal View History

/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package sbt
2009-08-16 14:29:08 -04:00
2010-10-26 18:02:27 -04:00
import Types.:+:
2011-05-17 20:09:20 -04:00
import sbinary.{DefaultProtocol, Format, Input, Output => Out}
2010-10-26 18:02:27 -04:00
import DefaultProtocol.ByteFormat
2009-08-16 14:29:08 -04:00
import java.io.{File, InputStream, OutputStream}
2010-10-26 18:02:27 -04:00
trait InputCache[I]
2009-08-16 14:29:08 -04:00
{
2010-10-26 18:02:27 -04:00
type Internal
def convert(i: I): Internal
def read(from: Input): Internal
2011-05-17 20:09:20 -04:00
def write(to: Out, j: Internal): Unit
2010-10-26 18:02:27 -04:00
def equiv: Equiv[Internal]
2009-08-16 14:29:08 -04:00
}
2010-10-26 18:02:27 -04:00
object InputCache
2009-08-31 10:41:59 -04:00
{
2010-10-26 18:02:27 -04:00
implicit def basicInputCache[I](implicit fmt: Format[I], eqv: Equiv[I]): InputCache[I] =
new InputCache[I]
{
type Internal = I
def convert(i: I) = i
def read(from: Input): I = fmt.reads(from)
2011-05-17 20:09:20 -04:00
def write(to: Out, i: I) = fmt.writes(to, i)
2010-10-26 18:02:27 -04:00
def equiv = eqv
}
2011-06-20 15:25:23 -04:00
def lzy[I](mkIn: => InputCache[I]): InputCache[I] =
new InputCache[I]
{
lazy val ic = mkIn
type Internal = ic.Internal
def convert(i: I) = ic convert i
def read(from: Input): ic.Internal = ic.read(from)
def write(to: Out, i: ic.Internal) = ic.write(to, i)
def equiv = ic.equiv
}
2009-08-16 14:29:08 -04:00
}
2010-10-26 18:02:27 -04:00
class BasicCache[I,O](implicit input: InputCache[I], outFormat: Format[O]) extends Cache[I,O]
2009-08-16 14:29:08 -04:00
{
def apply(file: File)(in: I) =
2010-10-26 18:02:27 -04:00
{
val j = input.convert(in)
try { applyImpl(file, j) }
catch { case e: Exception => Right(update(file)(j)) }
}
protected def applyImpl(file: File, in: input.Internal) =
2009-08-16 14:29:08 -04:00
{
Using.fileInputStream(file) { stream =>
2010-10-26 18:02:27 -04:00
val previousIn = input.read(stream)
if(input.equiv.equiv(in, previousIn))
Left(outFormat.reads(stream))
2009-08-16 14:29:08 -04:00
else
2010-10-26 18:02:27 -04:00
Right(update(file)(in))
2009-08-16 14:29:08 -04:00
}
}
2010-10-26 18:02:27 -04:00
protected def update(file: File)(in: input.Internal) = (out: O) =>
2009-08-16 14:29:08 -04:00
{
Using.fileOutputStream(false)(file) { stream =>
2010-10-26 18:02:27 -04:00
input.write(stream, in)
outFormat.writes(stream, out)
2009-08-16 14:29:08 -04:00
}
}
}