All Downloads are FREE. Search and download functionalities are using the official Maven repository.

izumi.fundamentals.platform.cli.impl.CLIParserState.scala Maven / Gradle / Ivy

The newest version!
package izumi.fundamentals.platform.cli.impl

import izumi.fundamentals.platform.cli.CLIParser.ParserError
import izumi.fundamentals.platform.cli.model.raw._
import izumi.fundamentals.platform.language.Quirks

sealed trait CLIParserState {
  def addRole(name: String): CLIParserState

  def addFlag(rawArg: String)(flag: RawFlag): CLIParserState

  def addParameter(rawArg: String)(parameter: RawValue): CLIParserState

  def openParameter(rawArg: String)(name: String): CLIParserState

  def addFreeArg(processed: Vector[String])(arg: String): CLIParserState

  def splitter(processed: Vector[String]): CLIParserState

  def freeze(): Either[ParserError, RawAppArgs]
}

object CLIParserState {

  class Error(error: ParserError) extends CLIParserState {
    override def addRole(name: String): CLIParserState = {
      Quirks.discard(name)
      this
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      Quirks.discard(rawArg, flag)
      this
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      Quirks.discard(rawArg, parameter)
      this
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      Quirks.discard(arg, processed)
      this
    }

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      Quirks.discard(rawArg, name)
      this
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      Quirks.discard(processed)
      this
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Left(error)
    }
  }

  class Initial() extends CLIParserState {
    override def addRole(name: String): CLIParserState = {
      new RoleParameters(RawEntrypointParams.empty, Vector.empty, RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      Quirks.discard(rawArg)
      new GlobalParameters(RawEntrypointParams(Vector(flag), Vector.empty))
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      Quirks.discard(rawArg)
      new GlobalParameters(RawEntrypointParams(Vector.empty, Vector(parameter)))
    }

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      Quirks.discard(rawArg)
      new OpenGlobalParameters(RawEntrypointParams.empty, name)
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      new Error(ParserError.DanglingArgument(processed, arg))
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      new Error(ParserError.DanglingSplitter(processed))
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(RawEntrypointParams.empty, Vector.empty))
    }
  }

  class OpenGlobalParameters(p: RawEntrypointParams, name: String) extends CLIParserState {

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      new OpenGlobalParameters(withFlag(), name)
    }

    override def addRole(name: String): CLIParserState = {
      new RoleParameters(withFlag(), Vector.empty, RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      new GlobalParameters(p.copy(flags = p.flags ++ Vector(RawFlag(name), flag)))
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      new GlobalParameters(withFlag().copy(values = p.values :+ parameter))
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      Quirks.discard(processed)
      new GlobalParameters(p.copy(values = p.values :+ RawValue(name, arg)))
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      new Error(ParserError.DanglingSplitter(processed))
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(withFlag(), Vector.empty))
    }

    private def withFlag(): RawEntrypointParams = {
      p.copy(flags = p.flags :+ RawFlag(this.name))
    }
  }

  class GlobalParameters(p: RawEntrypointParams) extends CLIParserState {
    override def addRole(name: String): CLIParserState = {
      new RoleParameters(p, Vector.empty, RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      new GlobalParameters(p.copy(flags = p.flags :+ flag))
    }

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      Quirks.discard(rawArg)
      new OpenGlobalParameters(p, name)
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      new GlobalParameters(p.copy(values = p.values :+ parameter))
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      new Error(ParserError.DanglingArgument(processed, arg))
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      new Error(ParserError.DanglingSplitter(processed))
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(p, Vector.empty))
    }
  }

  class RoleParameters(globalParameters: RawEntrypointParams, roles: Vector[RawRoleParams], currentRole: RawRoleParams) extends CLIParserState {
    override def addRole(name: String): CLIParserState = {
      new RoleParameters(globalParameters, roles :+ currentRole, RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      new OpenRoleParameters(globalParameters, roles, currentRole, name)
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      Quirks.discard(rawArg)
      new RoleParameters(globalParameters, roles, currentRole.copy(roleParameters = currentRole.roleParameters.copy(flags = currentRole.roleParameters.flags :+ flag)))
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      Quirks.discard(rawArg)
      new RoleParameters(
        globalParameters,
        roles,
        currentRole.copy(roleParameters = currentRole.roleParameters.copy(values = currentRole.roleParameters.values :+ parameter)),
      )
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      new RoleArgs(globalParameters, roles, currentRole)
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      new RoleArgs(globalParameters, roles, currentRole.copy(freeArgs = currentRole.freeArgs :+ arg))
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(globalParameters, roles :+ currentRole))
    }
  }

  class OpenRoleParameters(globalParameters: RawEntrypointParams, roles: Vector[RawRoleParams], currentRole: RawRoleParams, name: String) extends CLIParserState {

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      new OpenRoleParameters(globalParameters, roles, withFlag(), name)
    }

    override def addRole(name: String): CLIParserState = {
      new RoleParameters(globalParameters, roles :+ withFlag(), RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      new RoleParameters(
        globalParameters,
        roles,
        currentRole.copy(roleParameters = currentRole.roleParameters.copy(flags = currentRole.roleParameters.flags ++ Vector(RawFlag(name), flag))),
      )
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      val wf = withFlag()
      new RoleParameters(globalParameters, roles, wf.copy(roleParameters = wf.roleParameters.copy(values = wf.roleParameters.values :+ parameter)))
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      Quirks.discard(processed)
      new RoleParameters(
        globalParameters,
        roles,
        currentRole.copy(roleParameters = currentRole.roleParameters.copy(values = currentRole.roleParameters.values :+ RawValue(name, arg))),
      )

    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      new Error(ParserError.DanglingSplitter(processed))
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(globalParameters, roles :+ withFlag()))
    }

    private def withFlag(): RawRoleParams = {
      currentRole.copy(roleParameters = currentRole.roleParameters.copy(flags = currentRole.roleParameters.flags :+ RawFlag(this.name)))
    }
  }

  class RoleArgs(globalParameters: RawEntrypointParams, roles: Vector[RawRoleParams], currentRole: RawRoleParams) extends CLIParserState {
    override def addRole(name: String): CLIParserState = {
      new RoleParameters(globalParameters, roles :+ currentRole, RawRoleParams(name, RawEntrypointParams.empty, Vector.empty))
    }

    override def openParameter(rawArg: String)(name: String): CLIParserState = {
      Quirks.discard(name)
      extend(rawArg)
    }

    override def addFlag(rawArg: String)(flag: RawFlag): CLIParserState = {
      Quirks.discard(flag)
      extend(rawArg)
    }

    override def addParameter(rawArg: String)(parameter: RawValue): CLIParserState = {
      Quirks.discard(parameter)
      extend(rawArg)
    }

    override def splitter(processed: Vector[String]): CLIParserState = {
      Quirks.discard(processed)
      extend("--")
    }

    override def addFreeArg(processed: Vector[String])(arg: String): CLIParserState = {
      Quirks.discard(processed)
      extend(arg)
    }

    override def freeze(): Either[ParserError, RawAppArgs] = {
      Right(RawAppArgs(globalParameters, roles :+ currentRole))
    }

    private def extend(rawArg: String): CLIParserState = {
      new RoleArgs(globalParameters, roles, currentRole.copy(freeArgs = currentRole.freeArgs :+ rawArg))
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy