![JAR search and dependency download from the Maven repository](/logo.png)
org.kynthus.hatalib.argparse.instance.ParserInstances0.scala Maven / Gradle / Ivy
The newest version!
package org.kynthus.hatalib.argparse.instance
import org.kynthus.hatalib.argparse.concept._
import org.kynthus.hatalib.core.concept.{ResultCategory, Run}
import org.kynthus.hatalib.core.syntax.BiNaturalTransformationSyntax.BiNaturalTransformationOps
import org.kynthus.hatalib.core.syntax.TagSyntax.TagOps
import scalaz.syntax.applicative.ApplicativeIdV
import scalaz.syntax.std.function2.ToFunction2Ops
import scalaz.syntax.tag.ToTagOps
import scalaz.{@@, Applicative, \/, ~~>}
import scopt.{OParser, OParserBuilder, Read}
import shapeless.labelled.FieldType
import shapeless.ops.record.{Remover, Selector, Updater}
import shapeless.record.recordOps
import shapeless.{::, HList, Lazy, Refute, lazily}
import scala.collection.immutable.Queue
import scala.language.higherKinds
/**
* パーサへの各種設定を行う型クラスインスタンスの第1候補です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[instance] trait ParserInstances0 extends Any {
/**
* 構築中の情報へ新しい型に対応したオプションを付与します。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput パーサの新しい型
* @tparam InsertingParser 新しい型に対応したオプションを付与する型
* @tparam InsertedParser 新しい型に対応したオプションを付与した型
* @tparam InsertedCategory 構築中の情報をラップする型
* @return 構築中の情報へ新しい型に対応したオプションを付与する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def InsertElementParser[
Input,
Instance,
NewInput: Read,
InsertingParser <: HList,
InsertedParser <: HList,
InsertedCategory[_]
](
implicit
runCategory: ResultCategory[InsertedCategory] @@ Run.type,
applicative: Applicative[InsertedCategory],
currentUpdater: Updater.Aux[
InsertingParser,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
InsertedParser
],
currentNotExist: Refute[
Selector[
InsertingParser,
ParserCurrent.T
]
]
): ElementParser.Aux[
InsertingParser @@ (Input @@ Instance),
NewInput,
Instance,
InsertedCategory[InsertedParser @@ (NewInput @@ Instance)]
] = ParserInstances0.InsertElementParser
/**
* 構築中の情報へ型を持たないオプションを付与します。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
* @tparam UnusedInput パーサの現在値の型(未使用)
* @tparam Instance 現在の初期値の型
* @tparam InsertingParser 型を持たないオプションを付与する型
* @tparam InsertedParser 型を持たないオプションを付与した型
* @tparam InsertedCategory 構築中の情報をラップする型
* @return 構築中の情報へ型を持たないオプションを付与する型クラスインスタンス。
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def InsertUnitParser[
UnusedInput,
Instance,
InsertingParser <: HList,
InsertedParser <: HList,
InsertedCategory[_]
](
implicit
runCategory: ResultCategory[InsertedCategory] @@ Run.type,
applicative: Applicative[InsertedCategory],
currentUpdater: Updater.Aux[
InsertingParser,
FieldType[
ParserCurrent.T,
OParser[Unit, Instance]
],
InsertedParser
],
currentNotExist: Refute[
Selector[
InsertingParser,
ParserCurrent.T
]
]
): UnitParser.Aux[
InsertingParser @@ (UnusedInput @@ Instance),
Instance,
InsertedCategory[InsertedParser @@ (Unit @@ Instance)]
] = ParserInstances0.InsertUnitParser
/**
* 構築中の情報へ新しい型に対応したオプションを追加します。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput パーサの新しい型
* @tparam UpdatingParser 新しい型に対応したオプションを追加する型
* @tparam RemovedCurrent 現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを新しい型に対応したオプションで設定しなおした型
* @tparam UpdatedDecided 決定済みパーサを更新した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報へ新しい型に対応したオプションを追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def UpdateElementParser[
Input,
Instance,
NewInput: Read,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedCurrent,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
UpdatedCurrent
],
decidedUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ElementParser.Aux[
UpdatingParser @@ (Input @@ Instance),
NewInput,
Instance,
UpdatedCategory[UpdatedDecided @@ (NewInput @@ Instance)]
] = ParserInstances0.UpdateElementParser
/**
* 構築中の情報へ型を持たないオプションを追加します。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 型を持たないオプションを追加する型
* @tparam RemovedCurrent 現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを型を持たないオプションで設定しなおした型
* @tparam UpdatedDecided 決定済みパーサを更新した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報へ型を持たないオプションを追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def UpdateUnitParser[
Input,
Instance,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedCurrent,
FieldType[
ParserCurrent.T,
OParser[Unit, Instance]
],
UpdatedCurrent
],
decidedUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): UnitParser.Aux[
UpdatingParser @@ (Input @@ Instance),
Instance,
UpdatedCategory[UpdatedDecided @@ (Unit @@ Instance)]
] = ParserInstances0.UpdateUnitParser
/**
* 構築中の情報のうちオプションに対する詳細設定を追加します。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentSelector 構築後の情報に現在設定中のパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 詳細設定を追加する型
* @tparam UpdatedParser 詳細設定を追加した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報のうちオプションに対する詳細設定を追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def UpdateConfigParser[
Input,
Instance,
UpdatingParser <: HList,
UpdatedParser <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentSelector: Selector.Aux[
UpdatingParser,
ParserCurrent.T,
OParser[Input, Instance]
],
currentUpdater: Updater.Aux[
UpdatingParser,
FieldType[
ParserCurrent.T,
OParser[Input, Instance]
],
UpdatedParser
]
): ConfigParser.Aux[
UpdatingParser @@ (Input @@ Instance),
Input,
Instance,
UpdatedCategory[UpdatedParser @@ (Input @@ Instance)]
] = ParserInstances0.UpdateConfigParser
/**
* 構築中の情報を子パーサへ分岐させます。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param hierarchyRemover 構築中の情報からパーサ階層を削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param hierarchyUpdater 構築中の情報が持つパーサ階層を更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 子パーサへの分岐を行う型
* @tparam ExistHierarchy 現在のパーサ階層の型
* @tparam RemovedCurrent 構築中の情報から現在設定中のパーサを削除した後の型
* @tparam RemovedHierarchy 構築中の情報からパーサ階層を削除した後の型
* @tparam UpdatedHierarchy パーサ階層を更新した後の型
* @tparam UpdatedDecided 決定済みパーサを更新した後の型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報を子パーサへ分岐させる型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def UpdateChildrenParser[
Input,
Instance,
UpdatingParser <: HList,
ExistHierarchy <: HList,
RemovedCurrent <: HList,
RemovedHierarchy <: HList,
UpdatedHierarchy <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
hierarchyRemover: Remover.Aux[
RemovedCurrent,
ParserHierarchy.T,
(ExistHierarchy, RemovedHierarchy)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
hierarchyUpdater: Updater.Aux[
RemovedHierarchy,
FieldType[
ParserHierarchy.T,
OParser[Input, Instance] :: ExistHierarchy
],
UpdatedHierarchy
],
decidedUpdater: Updater.Aux[
UpdatedHierarchy,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ChildrenParser.Aux[
UpdatingParser @@ (Input @@ Instance),
UpdatedCategory[UpdatedDecided @@ (Input @@ Instance)]
] = ParserInstances0.UpdateChildrenParser
/**
* 構築中の情報を親パーサへ合流させます。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param lazyHierarchyRemover 構築中の情報からパーサ階層を削除できることを保証する(再帰的なので遅延)
* @param hierarchyUpdater 構築中の情報が持つパーサ階層を更新できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput 親パーサへの合流後の現在値の型
* @tparam UpdatingParser 親パーサへの合流を行う型
* @tparam RemovedCurrent 構築中の情報から現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを更新した後の型
* @tparam TailHierarchy パーサ階層の2番目以降の型
* @tparam RemovedHierarchy 構築中の情報からパーサ階層を削除した後の型
* @tparam UpdatedHierarchy パーサ階層を更新した後の型
* @tparam UpdatedDecided 決定済みパーサを更新した後の型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報を親パーサへ合流させる型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
implicit final def UpdateParentParser[
Input,
Instance,
NewInput,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
TailHierarchy <: HList,
RemovedHierarchy <: HList,
UpdatedHierarchy <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
lazyHierarchyRemover: Lazy[
Remover.Aux[
RemovedCurrent,
ParserHierarchy.T,
(OParser[NewInput, Instance] :: TailHierarchy, RemovedHierarchy)
]
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedHierarchy,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
UpdatedCurrent
],
hierarchyUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserHierarchy.T,
TailHierarchy
],
UpdatedHierarchy
],
decidedUpdater: Updater.Aux[
UpdatedHierarchy,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ParentParser.Aux[
UpdatingParser @@ (Input @@ Instance),
UpdatedCategory[UpdatedDecided @@ (NewInput @@ Instance)]
] = ParserInstances0.UpdateParentParser
}
/**
* パーサへの各種設定を行う型クラスインスタンスの第1候補を内部的に定義します。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private object ParserInstances0 extends AnyRef {
/**
* 構築中の情報へ新しい型に対応したオプションを付与します(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput パーサの新しい型
* @tparam InsertingParser 新しい型に対応したオプションを付与する型
* @tparam InsertedParser 新しい型に対応したオプションを付与した型
* @tparam InsertedCategory 構築中の情報をラップする型
* @return 構築中の情報へ新しい型に対応したオプションを付与する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def InsertElementParser[
Input,
Instance,
NewInput: Read,
InsertingParser <: HList,
InsertedParser <: HList,
InsertedCategory[_]
](
implicit
runCategory: ResultCategory[InsertedCategory] @@ Run.type,
applicative: Applicative[InsertedCategory],
currentUpdater: Updater.Aux[
InsertingParser,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
InsertedParser
],
currentNotExist: Refute[
Selector[
InsertingParser,
ParserCurrent.T
]
]
): ElementParser.Aux[
InsertingParser @@ (Input @@ Instance),
NewInput,
Instance,
InsertedCategory[InsertedParser @@ (NewInput @@ Instance)]
] = new ElementParser[InsertingParser @@ (Input @@ Instance)] {
/**
* 初期値の型に対するパーサを構築する際に使用します。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] val builder: OParserBuilder[super.Struct] = OParser.builder
/**
* 新しいオプションに対応する型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Member = NewInput
/**
* 各オプションの初期値を持つ型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Struct = Instance
/**
* 新しい型に対応したオプションを付与した後の型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = InsertedCategory[InsertedParser @@ (NewInput @@ super.Struct)]
/**
* パーサに設定したオプションをまとめて追加します。
*
* @param derived オプションの追加先
* @param parser 追加するオプション
* @return 現在の型を更新し、オプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def apply
(
derived: => InsertingParser @@ (Input @@ super.Struct),
parser: OParser[super.Member, super.Struct]
): super.Result = this (derived) = parser
/**
* 単独の位置引数を追加します。
*
* @param derived オプションの追加先
* @param name 位置引数名
* @return 現在の型を更新し、位置引数を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def arg
(
derived: => InsertingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.arg[super.Member](name)
/**
* 単独のオプション付き引数を追加します。
*
* @param derived オプションの追加先
* @param name オプション名
* @return 現在の型を更新し、オプション付き引数を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def opt
(
derived: => InsertingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.opt[super.Member](name)
/**
* 構築中の情報へ新しい型に対応したオプションを付与した結果を返します。
*
* @param derived 構築中の情報を持つ値
* @param parser 新しい型に対応したオプション
* @return 構築中の情報へ新しい型に対応したオプションを付与した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] def update
(
derived: => InsertingParser @@ (Input @@ super.Struct),
parser: OParser[super.Member, super.Struct]
): super.Result = {
// 構築中の情報からタグを外し、新しい型のオプションを現在設定中のパーサとして追加
val insertedParser: InsertedParser = derived.unwrap.updated(ParserCurrent, parser)
// 再度タグ付けして返す
val result: InsertedParser @@ (NewInput @@ super.Struct) = insertedParser.wrap
result.pure
}
}
/**
* 構築中の情報へ型を持たないオプションを付与します(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param currentNotExist 構築中の情報が現在設定中のパーサを持たないことを保証する
* @tparam UnusedInput パーサの現在値の型(未使用)
* @tparam Instance 現在の初期値の型
* @tparam InsertingParser 型を持たないオプションを付与する型
* @tparam InsertedParser 型を持たないオプションを付与した型
* @tparam InsertedCategory 構築中の情報をラップする型
* @return 構築中の情報へ型を持たないオプションを付与する型クラスインスタンス。
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def InsertUnitParser[
UnusedInput,
Instance,
InsertingParser <: HList,
InsertedParser <: HList,
InsertedCategory[_]
](
implicit
runCategory: ResultCategory[InsertedCategory] @@ Run.type,
applicative: Applicative[InsertedCategory],
currentUpdater: Updater.Aux[
InsertingParser,
FieldType[
ParserCurrent.T,
OParser[Unit, Instance]
],
InsertedParser
],
currentNotExist: Refute[
Selector[
InsertingParser,
ParserCurrent.T
]
]
): UnitParser.Aux[
InsertingParser @@ (UnusedInput @@ Instance),
Instance,
InsertedCategory[InsertedParser @@ (Unit @@ Instance)]
] = new UnitParser[InsertingParser @@ (UnusedInput @@ Instance)] {
/**
* 初期値の型に対するパーサを構築する際に使用します。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] val builder: OParserBuilder[super.Struct] = OParser.builder
/**
* 各オプションの初期値を持つ型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Struct = Instance
/**
* 型を持たないオプションを付与した後の型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = InsertedCategory[InsertedParser @@ (Unit @@ super.Struct)]
/**
* プログラム名を設定します。
*
* @param derived オプションの追加先
* @param name プログラム名
* @return プログラム名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def programName
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.programName(name)
/**
* ヘッダメッセージを設定します。
*
* @param derived メッセージの追加先
* @param message ヘッダメッセージ
* @return ヘッダメッセージを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def head
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
message: String*
): super.Result = this (derived) = this.builder.head(message: _*)
/**
* サブコマンドを追加します。
*
* @param derived サブコマンドの追加先
* @param name サブコマンド名
* @return サブコマンドを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def cmd
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.cmd(name)
/**
* ヘルプ表示用のオプションを追加します。
*
* @param derived オプションの追加先
* @param name ヘルプ表示用のオプション名
* @return ヘルプ表示用のオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def help
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.help(name)
/**
* バージョン表示用のオプションを追加します。
*
* @param derived オプションの追加先
* @param name バージョン表示用のオプション名
* @return バージョン表示用のオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def version
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.version(name)
/**
* コマンドの使用方法として表示されるメッセージを追加します。
*
* @param derived メッセージの追加先
* @param message コマンド使用方法のメッセージ
* @return コマンドの使用方法を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def note
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
message: String
): super.Result = this (derived) = this.builder.note(message)
/**
* 実際にコマンドから渡されたオプション値を検証します。
*
* @param derived オプションの追加先
* @param checker フィールド値に対する、正常・異常の判定処理
* @param toDisjunction 成功・失敗を表現可能な型から[[scalaz.\/]]へ変換できることを保証する
* @param toEither [[scalaz.\/]]から[[scala.Either]]へ変換できることを保証する
* @tparam UnusedRight 成功を表現する型が持つ右側の型([[scala.Unit]]への変換により破棄)
* @tparam UnusedCategory 2つの型パラメータを持ち、成功・失敗を表現可能な型
* @return 検証処理を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def checkConfig[UnusedRight, UnusedCategory[_, _]]
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
checker: super.Struct => UnusedCategory[String, UnusedRight]
)(implicit
toDisjunction: UnusedCategory ~~> \/,
toEither: \/ ~~> Either
): super.Result = this (derived) = this.builder.checkConfig {
checker(_)
.biTransform
.map(_ => ())
.biTransform
}
/**
* 構築中の情報へ型を持たないオプションを付与した結果を返します。
*
* @param derived 構築中の情報を持つ値
* @param parser 型を持たないオプション
* @return 構築中の情報へ型を持たないオプションを付与した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] def update
(
derived: => InsertingParser @@ (UnusedInput @@ super.Struct),
parser: OParser[Unit, super.Struct]
): super.Result = {
// 構築中の情報からタグを外し、型を持たないオプションを現在設定中のパーサとして追加
val insertedParser: InsertedParser = derived.unwrap.updated(ParserCurrent, parser)
// 再度タグ付けして返す
val result: InsertedParser @@ (Unit @@ super.Struct) = insertedParser.wrap
result.pure
}
}
/**
* 構築中の情報へ新しい型に対応したオプションを追加します(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput パーサの新しい型
* @tparam UpdatingParser 新しい型に対応したオプションを追加する型
* @tparam RemovedCurrent 現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを新しい型に対応したオプションで設定しなおした型
* @tparam UpdatedDecided 決定済みパーサを更新した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報へ新しい型に対応したオプションを追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def UpdateElementParser[
Input,
Instance,
NewInput: Read,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedCurrent,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
UpdatedCurrent
],
decidedUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ElementParser.Aux[
UpdatingParser @@ (Input @@ Instance),
NewInput,
Instance,
UpdatedCategory[UpdatedDecided @@ (NewInput @@ Instance)]
] = new ElementParser[UpdatingParser @@ (Input @@ Instance)] {
/**
* 初期値の型に対するパーサを構築する際に使用します。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] val builder: OParserBuilder[super.Struct] = OParser.builder
/**
* 新しいオプションに対応する型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Member = NewInput
/**
* 各オプションの初期値を持つ型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Struct = Instance
/**
* 新しい型に対応したオプションを追加した後の型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = UpdatedCategory[UpdatedDecided @@ (super.Member @@ super.Struct)]
/**
* パーサに設定したオプションをまとめて追加します。
*
* @param derived オプションの追加先
* @param parser 追加するオプション
* @return 現在の型を更新し、オプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def apply
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
parser: OParser[super.Member, super.Struct]
): super.Result = this (derived) = parser
/**
* 単独の位置引数を追加します。
*
* @param derived オプションの追加先
* @param name 位置引数名
* @return 現在の型を更新し、位置引数を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def arg
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.arg[super.Member](name)
/**
* 単独のオプション付き引数を追加します。
*
* @param derived オプションの追加先
* @param name オプション名
* @return 現在の型を更新し、オプション付き引数を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def opt
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.opt[super.Member](name)
/**
* 構築中の情報へ新しい型に対応したオプションを追加した結果を返します。
*
* @param derived 構築中の情報を持つ値
* @param parser 新しい型に対応したオプション
* @return 構築中の情報へ新しい型に対応したオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] def update
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
parser: OParser[super.Member, super.Struct]
): super.Result = {
// 構築中の情報からタグを外す
val updatingParser: UpdatingParser = derived.unwrap
// 現在設定中のパーサを構築中の情報から取得後に削除し、決定済みパーサのキューへ追加
val (parserCurrent, removedCurrent):
(OParser[Input, super.Struct], RemovedCurrent) =
updatingParser.remove(ParserCurrent)
// 決定済みパーサを取得
val parserDecided: List[Queue[OParser[_, super.Struct]]] = updatingParser(ParserDecided)
// 現在設定中のパーサを新しいものへ更新する
val updatedCurrent: UpdatedCurrent = removedCurrent.updated(ParserCurrent, parser)
// 決定済みパーサのキューへ追加
val updatedDecided: UpdatedDecided = updatedCurrent.updated(
ParserDecided,
parserDecided.head.enqueue(parserCurrent) :: parserDecided.tail
)
// 再度タグ付けして返す
val result: UpdatedDecided @@ (super.Member @@ super.Struct) = updatedDecided.wrap
result.pure
}
}
/**
* 構築中の情報へ型を持たないオプションを追加します(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 型を持たないオプションを追加する型
* @tparam RemovedCurrent 現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを型を持たないオプションで設定しなおした型
* @tparam UpdatedDecided 決定済みパーサを更新した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報へ型を持たないオプションを追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def UpdateUnitParser[
Input,
Instance,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedCurrent,
FieldType[
ParserCurrent.T,
OParser[Unit, Instance]
],
UpdatedCurrent
],
decidedUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): UnitParser.Aux[
UpdatingParser @@ (Input @@ Instance),
Instance,
UpdatedCategory[UpdatedDecided @@ (Unit @@ Instance)]
] = new UnitParser[UpdatingParser @@ (Input @@ Instance)] {
/**
* 初期値の型に対するパーサを構築する際に使用します。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] val builder: OParserBuilder[super.Struct] = OParser.builder
/**
* 各オプションの初期値を持つ型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Struct = Instance
/**
* 型を持たないオプションを追加した後の型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = UpdatedCategory[UpdatedDecided @@ (Unit @@ super.Struct)]
/**
* プログラム名を設定します。
*
* @param derived オプションの追加先
* @param name プログラム名
* @return プログラム名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def programName
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.programName(name)
/**
* ヘッダメッセージを設定します。
*
* @param derived メッセージの追加先
* @param message ヘッダメッセージ
* @return ヘッダメッセージを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def head
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
message: String*
): super.Result = this (derived) = this.builder.head(message: _*)
/**
* サブコマンドを追加します。
*
* @param derived サブコマンドの追加先
* @param name サブコマンド名
* @return サブコマンドを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def cmd
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.cmd(name)
/**
* ヘルプ表示用のオプションを追加します。
*
* @param derived オプションの追加先
* @param name ヘルプ表示用のオプション名
* @return ヘルプ表示用のオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def help
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.help(name)
/**
* バージョン表示用のオプションを追加します。
*
* @param derived オプションの追加先
* @param name バージョン表示用のオプション名
* @return バージョン表示用のオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def version
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
name: String
): super.Result = this (derived) = this.builder.version(name)
/**
* コマンドの使用方法として表示されるメッセージを追加します。
*
* @param derived メッセージの追加先
* @param message コマンド使用方法のメッセージ
* @return コマンドの使用方法を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def note
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
message: String
): super.Result = this (derived) = this.builder.note(message)
/**
* 実際にコマンドから渡されたオプション値を検証します。
*
* @param derived オプションの追加先
* @param checker フィールド値に対する、正常・異常の判定処理
* @param toDisjunction 成功・失敗を表現可能な型から[[scalaz.\/]]へ変換できることを保証する
* @param toEither [[scalaz.\/]]から[[scala.Either]]へ変換できることを保証する
* @tparam UnusedRight 成功を表現する型が持つ右側の型([[scala.Unit]]への変換により破棄)
* @tparam UnusedCategory 2つの型パラメータを持ち、成功・失敗を表現可能な型
* @return 検証処理を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def checkConfig[UnusedRight, UnusedCategory[_, _]]
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
checker: super.Struct => UnusedCategory[String, UnusedRight]
)(
implicit
toDisjunction: UnusedCategory ~~> \/,
toEither: \/ ~~> Either
): super.Result = this (derived) = this.builder.checkConfig {
checker(_)
.biTransform
.map(_ => ())
.biTransform
}
/**
* 構築中の情報へ型を持たないオプションを追加した結果を返します。
*
* @param derived 構築中の情報を持つ値
* @param parser 型を持たないオプション
* @return 構築中の情報へ型を持たないオプションを追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] def update
(
derived: => UpdatingParser @@ (Input @@ super.Struct),
parser: OParser[Unit, super.Struct]
): super.Result = {
// 構築中の情報からタグを外す
val updatingParser: UpdatingParser = derived.unwrap
// 現在設定中のパーサを構築中の情報から取得後に削除し、決定済みパーサのキューへ追加
val (parserCurrent, removedCurrent):
(OParser[Input, super.Struct], RemovedCurrent) =
updatingParser.remove(ParserCurrent)
// 決定済みパーサを取得
val parserDecided: List[Queue[OParser[_, super.Struct]]] = updatingParser(ParserDecided)
// 現在設定中のパーサを新しいものへ更新する
val updatedCurrent: UpdatedCurrent = removedCurrent.updated(ParserCurrent, parser)
// 決定済みパーサのキューへ追加
val updatedDecided: UpdatedDecided = updatedCurrent.updated(
ParserDecided,
parserDecided.head.enqueue(parserCurrent) :: parserDecided.tail
)
// 再度タグ付けして返す
val result: UpdatedDecided @@ (Unit @@ super.Struct) = updatedDecided.wrap
result.pure
}
}
/**
* 構築中の情報のうちオプションに対する詳細設定を追加します(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentSelector 構築後の情報に現在設定中のパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 詳細設定を追加する型
* @tparam UpdatedParser 詳細設定を追加した型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報のうちオプションに対する詳細設定を追加する型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def UpdateConfigParser[
Input,
Instance,
UpdatingParser <: HList,
UpdatedParser <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentSelector: Selector.Aux[
UpdatingParser,
ParserCurrent.T,
OParser[Input, Instance]
],
currentUpdater: Updater.Aux[
UpdatingParser,
FieldType[
ParserCurrent.T,
OParser[Input, Instance]
],
UpdatedParser
]
): ConfigParser.Aux[
UpdatingParser @@ (Input @@ Instance),
Input,
Instance,
UpdatedCategory[UpdatedParser @@ (Input @@ Instance)]
] = new ConfigParser[UpdatingParser @@ (Input @@ Instance)] {
/**
* 現在のオプションに対応する型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Member = Input
/**
* 各オプションの初期値を持つ型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Struct = Instance
/**
* オプションへ詳細設定を適用した後の型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = UpdatedCategory[UpdatedParser @@ (super.Member @@ super.Struct)]
/**
* オプションに対して別名を設定します。
*
* @param derived 別名の設定先
* @param name オプションの別名
* @return 別名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def abbr
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
name: String
): super.Result = this (derived) = _.abbr(name)
/**
* オプションが指定された際に実行する処理を設定します。
*
* @param derived 実行する処理の設定先
* @param function 実行する処理
* @return 実行する処理を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def action
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
function: (super.Struct, super.Member) => super.Struct
): super.Result = this (derived) = _.action(function.flip)
/**
* オプションの説明文を設定します。
*
* @param derived オプションに対する説明文の設定先
* @param message オプションに対する説明文
* @return 説明文を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def text
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
message: String
): super.Result = this (derived) = _.text(message)
/**
* オプションに最低限必要な引数の数を設定します。
*
* @param derived 最低限必要な引数の数の設定先
* @param occurs 最低限必要な引数の数
* @return 最低限必要な引数の数を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def minOccurs
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
occurs: Int
): super.Result = this (derived) = _.minOccurs(occurs)
/**
* オプションに引数をいくつまで指定できるかを設定します。
*
* @param derived 引数を最大いくつまで指定できるかの設定先
* @param occurs 引数の最大数
* @return 引数の最大数を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def maxOccurs
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
occurs: Int
): super.Result = this (derived) = _.maxOccurs(occurs)
/**
* オプションを必須扱いにします。
*
* @param derived オプションを必須化する設定を行う先
* @return オプションを必須化した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def required
(derived: => UpdatingParser @@ (super.Member @@ super.Struct)):
super.Result = this (derived) = _.required()
/**
* オプションを任意(省略可能)にします。
*
* @param derived オプションを任意化する設定を行う先
* @return オプションを任意化した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def optional
(derived: => UpdatingParser @@ (super.Member @@ super.Struct)):
super.Result = this (derived) = _.optional()
/**
* オプションに対して引数を無制限に指定できるようにします。
*
* @param derived 引数を無制限に指定できるよう設定を行う先
* @return 引数の指定数を無制限とした結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def unbounded
(derived: => UpdatingParser @@ (super.Member @@ super.Struct)):
super.Result = this (derived) = _.unbounded()
/**
* オプションを隠しオプションにします。
*
* @param derived 隠しオプション化の設定先
* @return 隠しオプション化した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def hidden
(derived: => UpdatingParser @@ (super.Member @@ super.Struct)):
super.Result = this (derived) = _.hidden()
/**
* オプションのキー名を設定します。
*
* @param derived キー名の設定先
* @param name キー名
* @return キー名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def keyName
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
name: String
): super.Result = this (derived) = _.keyName(name)
/**
* オプションの値名を設定します。
*
* @param derived 値名の設定先
* @param name 値名
* @return 値名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def valueName
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
name: String
): super.Result = this (derived) = _.valueName(name)
/**
* オプションのキー名と値名を設定します。
*
* @param derived キー名と値名の設定先
* @param keyName キー名
* @param valueName 値名
* @return キー名と値名を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def keyValueName
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
keyName: String,
valueName: String
): super.Result = this (derived) = _.keyValueName(keyName, valueName)
/**
* 実際にコマンドから渡されたオプション値を検証します。
*
* @param derived 検証処理の設定先
* @param validator 検証処理
* @param toDisjunction 成功・失敗を表現可能な型から[[scalaz.\/]]へ変換できることを保証する
* @param toEither [[scalaz.\/]]から[[scala.Either]]へ変換できることを保証する
* @tparam UnusedRight 成功を表現する型が持つ右側の型([[scala.Unit]]への変換により破棄)
* @tparam UnusedCategory 2つの型パラメータを持ち、成功・失敗を表現可能な型
* @return 検証処理を設定した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def validate[UnusedRight, UnusedCategory[_, _]]
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
validator: super.Member => UnusedCategory[String, UnusedRight]
)(
implicit
toDisjunction: UnusedCategory ~~> \/,
toEither: \/ ~~> Either
): super.Result = this (derived) = _.validate {
validator(_)
.biTransform
.map(_ => ())
.biTransform
}
/**
* 構築中の情報が持つオプションへ詳細設定を追加した結果を返します。
*
* @param derived 現在設定中のオプションを持つ値
* @param function 詳細設定を追加する処理
* @return 構築中の情報が持つオプションへ詳細設定を追加した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] def update
(
derived: => UpdatingParser @@ (super.Member @@ super.Struct),
function: OParser[super.Member, super.Struct] => OParser[super.Member, super.Struct]
): super.Result = {
// 構築中の情報からタグを外す
val updatingParser: UpdatingParser = derived.unwrap
// 現在設定中のパーサを新しいものへ更新する
val currentParser: OParser[super.Member, super.Struct] = updatingParser(ParserCurrent)
val updatedParser: UpdatedParser = updatingParser.replace(ParserCurrent, function(currentParser))
// 再度タグ付けして返す
val result: UpdatedParser @@ (super.Member @@ super.Struct) = updatedParser.wrap
result.pure
}
}
/**
* 構築中の情報を子パーサへ分岐させます(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param hierarchyRemover 構築中の情報からパーサ階層を削除できることを保証する
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param hierarchyUpdater 構築中の情報が持つパーサ階層を更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam UpdatingParser 子パーサへの分岐を行う型
* @tparam ExistHierarchy 現在のパーサ階層の型
* @tparam RemovedCurrent 構築中の情報から現在設定中のパーサを削除した後の型
* @tparam RemovedHierarchy 構築中の情報からパーサ階層を削除した後の型
* @tparam UpdatedHierarchy パーサ階層を更新した後の型
* @tparam UpdatedDecided 決定済みパーサを更新した後の型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報を子パーサへ分岐させる型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def UpdateChildrenParser[
Input,
Instance,
UpdatingParser <: HList,
ExistHierarchy <: HList,
RemovedCurrent <: HList,
RemovedHierarchy <: HList,
UpdatedHierarchy <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
hierarchyRemover: Remover.Aux[
RemovedCurrent,
ParserHierarchy.T,
(ExistHierarchy, RemovedHierarchy)
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
hierarchyUpdater: Updater.Aux[
RemovedHierarchy,
FieldType[
ParserHierarchy.T,
OParser[Input, Instance] :: ExistHierarchy
],
UpdatedHierarchy
],
decidedUpdater: Updater.Aux[
UpdatedHierarchy,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ChildrenParser.Aux[
UpdatingParser @@ (Input @@ Instance),
UpdatedCategory[UpdatedDecided @@ (Input @@ Instance)]
] = new ChildrenParser[UpdatingParser @@ (Input @@ Instance)] {
/**
* 子パーサへの分岐後に返す型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = UpdatedCategory[UpdatedDecided @@ (Input @@ Instance)]
/**
* 構築中の情報を子パーサへ分岐させた結果を返します。
*
* @param derived 子パーサへ分岐可能な値
* @return 子パーサへ分岐した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def apply
(derived: => UpdatingParser @@ (Input @@ Instance)):
this.Result = {
// 構築中の情報からタグを外す
val updatingParser: UpdatingParser = derived.unwrap
// 現在設定中のパーサとパーサ階層を取得し、いったん情報から削除する
val (current, removedCurrent):
(OParser[Input, Instance], RemovedCurrent) =
updatingParser.remove(ParserCurrent)
val (hierarchy, removedHierarchy):
(ExistHierarchy, RemovedHierarchy) =
removedCurrent.remove(ParserHierarchy)
// 決定済みパーサを取得する
val decided: List[Queue[OParser[_, Instance]]] = updatingParser(ParserDecided)
// 現在設定中のパーサをパーサ階層の先頭へ追加する形で更新する
val updatedHierarchy: UpdatedHierarchy =
removedHierarchy.updated(ParserHierarchy, current :: hierarchy)
// 空のキューを用意し、決定済みパーサの先頭へ追加する
val empty: Queue[OParser[_, Instance]] = Queue.empty
val updatedParser: UpdatedDecided = updatedHierarchy.updated(
ParserDecided,
empty :: decided
)
// 更新結果を再度タグ付けして返す
val result: UpdatedDecided @@ (Input @@ Instance) = updatedParser.wrap
result.pure
}
}
/**
* 構築中の情報を親パーサへ合流させます(内部)。
*
* @param runCategory 動作設定を持つ値を格納する型を決定するマーカー
* @param applicative 構築中の情報をラップ可能なことを保証する
* @param currentRemover 構築中の情報から現在設定中のパーサを削除できることを保証する
* @param lazyHierarchyRemover 構築中の情報からパーサ階層を削除できることを保証する(再帰的なので遅延)
* @param decidedSelector 構築中の情報に決定済みパーサが存在することを保証する
* @param currentUpdater 構築中の情報が持つ現在設定中のパーサを更新できることを保証する
* @param hierarchyUpdater 構築中の情報が持つパーサ階層を更新できることを保証する
* @param decidedUpdater 構築中の情報が持つ決定済みパーサを更新できることを保証する
* @tparam Input パーサの現在値の型
* @tparam Instance 現在の初期値の型
* @tparam NewInput 親パーサへの合流後の現在値の型
* @tparam UpdatingParser 親パーサへの合流を行う型
* @tparam RemovedCurrent 構築中の情報から現在設定中のパーサを削除した後の型
* @tparam UpdatedCurrent 現在設定中のパーサを更新した後の型
* @tparam TailHierarchy パーサ階層の2番目以降の型
* @tparam RemovedHierarchy 構築中の情報からパーサ階層を削除した後の型
* @tparam UpdatedHierarchy パーサ階層を更新した後の型
* @tparam UpdatedDecided 決定済みパーサを更新した後の型
* @tparam UpdatedCategory 構築中の情報をラップする型
* @return 構築中の情報を親パーサへ合流させる型クラスインスタンス
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private final def UpdateParentParser[
Input,
Instance,
NewInput,
UpdatingParser <: HList,
RemovedCurrent <: HList,
UpdatedCurrent <: HList,
TailHierarchy <: HList,
RemovedHierarchy <: HList,
UpdatedHierarchy <: HList,
UpdatedDecided <: HList,
UpdatedCategory[_]
](
implicit
runCategory: ResultCategory[UpdatedCategory] @@ Run.type,
applicative: Applicative[UpdatedCategory],
currentRemover: Remover.Aux[
UpdatingParser,
ParserCurrent.T,
(OParser[Input, Instance], RemovedCurrent)
],
lazyHierarchyRemover: Lazy[
Remover.Aux[
RemovedCurrent,
ParserHierarchy.T,
(OParser[NewInput, Instance] :: TailHierarchy, RemovedHierarchy)
]
],
decidedSelector: Selector.Aux[
UpdatingParser,
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
currentUpdater: Updater.Aux[
RemovedHierarchy,
FieldType[
ParserCurrent.T,
OParser[NewInput, Instance]
],
UpdatedCurrent
],
hierarchyUpdater: Updater.Aux[
UpdatedCurrent,
FieldType[
ParserHierarchy.T,
TailHierarchy
],
UpdatedHierarchy
],
decidedUpdater: Updater.Aux[
UpdatedHierarchy,
FieldType[
ParserDecided.T,
List[Queue[OParser[_, Instance]]]
],
UpdatedDecided
]
): ParentParser.Aux[
UpdatingParser @@ (Input @@ Instance),
UpdatedCategory[UpdatedDecided @@ (NewInput @@ Instance)]
] = new ParentParser[UpdatingParser @@ (Input @@ Instance)] {
/**
* 構築中の情報からパーサ階層を削除できることを保証します
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
private[this] implicit val hierarchyRemover: Remover.Aux[
RemovedCurrent,
ParserHierarchy.T,
(OParser[NewInput, Instance] :: TailHierarchy, RemovedHierarchy)
] = lazily.apply
/**
* 親パーサへの合流後に返す型です。
*
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override type Result = UpdatedCategory[UpdatedDecided @@ (NewInput @@ Instance)]
/**
* 構築中の情報を親パーサへ合流させた結果を返します。
*
* @param derived 親パーサへ合流可能な値
* @return 親パーサへ合流した結果
* @author Kynthus Auoeau
* @since 1.0.0
* @version 1.0.0
*/
override def apply
(derived: => UpdatingParser @@ (Input @@ Instance)):
this.Result = {
// 構築中の情報からタグを外す
val updatingParser: UpdatingParser = derived.unwrap
// 現在設定中のパーサとパーサ階層を取得し、いったん情報から削除する
val (current, removedCurrent):
(OParser[Input, Instance], RemovedCurrent) =
updatingParser.remove(ParserCurrent)
val (hierarchy, removedHierarchy):
(OParser[NewInput, Instance] :: TailHierarchy, RemovedHierarchy) =
removedCurrent.remove(ParserHierarchy)
// 決定済みパーサを取得する
val decided: List[Queue[OParser[_, Instance]]] = updatingParser(ParserDecided)
// 決定済みパーサから取得後、パーサ階層の先頭へ子パーサとして指定し、現在設定中のパーサへ戻す
val updatedCurrent: UpdatedCurrent = removedHierarchy.updated(
ParserCurrent,
hierarchy.head.children(decided.head :+ current: _*)
)
// パーサ階層にはもともと保持していた階層から、先頭のみ除いたパーサ階層を設定しなおす
val updatedHierarchy: UpdatedHierarchy =
updatedCurrent.updated(ParserHierarchy, hierarchy.tail)
// 決定済みパーサのうち、先頭のキューは破棄する
val updatedDecided: UpdatedDecided =
updatedHierarchy.updated(ParserDecided, decided.tail)
// 更新結果を再度タグ付けして返す
val result: UpdatedDecided @@ (NewInput @@ Instance) = updatedDecided.wrap
result.pure
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy