scala/ScalaBook/chapter-09/src/main/scala/scalabook/file/VFile.scala

package scalabook.file

import path.Path

trait VFile[T <: VFile[T]] { self: T =>
  def path: Path
  def name = path.name
  
  def isNative = this.isInstanceOf[NativeFile]
  def asNative: Option[NativeFile] = None

  def exists: Boolean
  def isFile: Boolean
  def isFolder: Boolean


  def children: Iterable[T]

  def childrenNames: Iterable[String]

  def /(that: String): T
  def /(that: Path): T

  def inputStream: Option[java.io.InputStream]
  def outputStream: Option[java.io.OutputStream]

  override def hashCode = path.hashCode
  override def equals(any: Any) =
    any.isInstanceOf[VFile[_]] &&
    any.asInstanceOf[VFile[_]].getClass == this.getClass &&
    any.asInstanceOf[VFile[_]].path == this.path

  override def toString = path.toString
}

sealed class NoFileType extends VFile[NoFileType] {
  val path = Path("")
  val exists = false
  val isFile = false
  val isFolder = false
  val children = Nil
  val childrenNames = Nil

  def /(that: String) = throw new UnsupportedOperationException
  def /(that: Path) = throw new UnsupportedOperationException

  val inputStream = throw new UnsupportedOperationException
  val outputStream = throw new UnsupportedOperationException

  override def equals(any: Any) = this == any

  def as[T <: VFile[T]] = this.asInstanceOf[T]
}

object NoFile extends NoFileType