#pragma once #include #include #include #include #include #include #include #include namespace Unvirt::CmdHelper { #pragma region Delegate Parameters enum class LoadStage { Shallow, Deep }; struct LoadParam { LoadStage stage; std::u8string filepath; }; struct UnloadParam {}; struct SaveParam { std::u8string filepath; }; struct InfoParam {}; enum class LsPart { Object, Manager, Search, }; struct LsParam { LsPart part; size_t page; }; enum class DataPart { Object, Manager, }; struct DataParam { DataPart part; size_t index; }; enum class ChunkPart { Object, Manager, }; struct ChunkParam { ChunkPart part; size_t index; }; enum class SearchPart { Object, Manager, }; enum class SearchMode { PlainText, Regex, }; struct SearchParam { SearchPart part; SearchMode mode; std::u8string text; }; struct ItemsParam { size_t count; }; enum class StyleLevel { Full, Simple, }; struct StyleParam { StyleLevel level; }; struct EncodingParam { std::vector enc; }; struct TempParam { std::u8string dirpath; }; struct RscClearParam {}; struct RscAddParam { std::u8string dirpath; }; struct TestParam {}; struct VersionParam {}; struct HelpParam {}; struct ExitParam {}; #pragma endregion #pragma region Delegates using LoadDelegate = std::function; using UnloadDelegate = std::function; using SaveDelegate = std::function; using InfoDelegate = std::function; using LsDelegate = std::function; using DataDelegate = std::function; using ChunkDelegate = std::function; using SearchDelegate = std::function; using ItemsDelegate = std::function; using StyleDelegate = std::function; using EncodingDelegate = std::function; using TempDelegate = std::function; using RscClearDelegate = std::function; using RscAddDelegate = std::function; using TestDelegate = std::function; using VersionDelegate = std::function; using HelpDelegate = std::function; using ExitDelegate = std::function; #pragma endregion #pragma region Error Types enum class Error { Lexer, ///< Fail to do lexer. TooMuchParam, ///< The count of parameter is larger than expected. TooLessParam, ///< The count of parameter is to less as expected. BadArg, ///< The format of argument is wrong. BadVerb, ///< Given verb do not match with any existing items. }; template using Result = std::expected; #pragma endregion class ParamStack { public: ParamStack(std::vector&& params); ~ParamStack(); YYCC_DEFAULT_COPY_MOVE(ParamStack) public: std::optional Next(); private: std::vector params; size_t cursor; }; class Commander { public: Commander(); ~Commander(); YYCC_DELETE_COPY_MOVE(Commander) public: Result Dispatch(const std::u8string_view &cmd) const; private: Result BuildStack(const std::u8string_view &cmd) const; private: Result Branch(ParamStack &stack) const; Result LoadBranch(ParamStack &stack) const; Result UnloadBranch(ParamStack &stack) const; Result SaveBranch(ParamStack &stack) const; Result InfoBranch(ParamStack &stack) const; Result LsBranch(ParamStack &stack) const; Result DataBranch(ParamStack &stack) const; Result ChunkBranch(ParamStack &stack) const; Result SearchBranch(ParamStack &stack) const; Result ItemsBranch(ParamStack &stack) const; Result StyleBranch(ParamStack &stack) const; Result EncodingBranch(ParamStack &stack) const; Result TempBranch(ParamStack &stack) const; Result RscBranch(ParamStack &stack) const; Result RscClearBranch(ParamStack &stack) const; Result RscAddBranch(ParamStack &stack) const; Result TestBranch(ParamStack &stack) const; Result VersionBranch(ParamStack &stack) const; Result HelpBranch(ParamStack &stack) const; Result ExitBranch(ParamStack &stack) const; public: void SetLoadDelegate(LoadDelegate &&delegate); void SetUnloadDelegate(UnloadDelegate &&delegate); void SetSaveDelegate(SaveDelegate &&delegate); void SetInfoDelegate(InfoDelegate &&delegate); void SetLsDelegate(LsDelegate &&delegate); void SetDataDelegate(DataDelegate &&delegate); void SetChunkDelegate(ChunkDelegate &&delegate); void SetSearchDelegate(SearchDelegate &&delegate); void SetItemsDelegate(ItemsDelegate &&delegate); void SetStyleDelegate(StyleDelegate &&delegate); void SetEncodingDelegate(EncodingDelegate &&delegate); void SetTempDelegate(TempDelegate &&delegate); void SetRscClearDelegate(RscClearDelegate &&delegate); void SetRscAddDelegate(RscAddDelegate &&delegate); void SetTestDelegate(TestDelegate &&delegate); void SetVersionDelegate(VersionDelegate &&delegate); void SetHelpDelegate(HelpDelegate &&delegate); void SetExitDelegate(ExitDelegate &&delegate); private: LoadDelegate load_delegate; UnloadDelegate unload_delegate; SaveDelegate save_delegate; InfoDelegate info_delegate; LsDelegate ls_delegate; DataDelegate data_delegate; ChunkDelegate chunk_delegate; SearchDelegate search_delegate; ItemsDelegate items_delegate; StyleDelegate style_delegate; EncodingDelegate encoding_delegate; TempDelegate temp_delegate; RscClearDelegate rsc_clear_delegate; RscAddDelegate rsc_add_delegate; TestDelegate test_delegate; VersionDelegate version_delegate; HelpDelegate help_delegate; ExitDelegate exit_delegate; }; } // namespace Unvirt::CmdHelper