di 0.1.0
Loading...
Searching...
No Matches
subcommand.h
Go to the documentation of this file.
1#pragma once
2
10#include "di/meta/language.h"
11#include "di/parser/prelude.h"
13#include "di/vocab/prelude.h"
14
15namespace di::cli::detail {
16class Subcommand {
17private:
18 using Parse = Result<> (*)(void*, Span<TransparentStringView>, AnyRef<Writer>, Span<TransparentStringView>);
19 using BashCompletionsInner = void (*)(TreeMap<Vector<TransparentString>, String>&, Span<TransparentStringView>);
20 using ZshCompletionsInner = void (*)(AnyRef<Writer>, u32, Span<TransparentStringView>);
21
22 template<auto member, typename T>
23 constexpr static auto concrete_parse(void* output_untyped, Span<TransparentStringView> input, AnyRef<Writer> writer,
24 Span<TransparentStringView> base_commands = {}) -> Result<> {
25 using Base = meta::MemberPointerClass<decltype(member)>;
26
27 auto output = static_cast<Base*>(output_untyped);
28 auto parser = get_cli_parser<T>();
29 (*output).*member = DI_TRY(parser.parse(input, writer, base_commands));
30 return {};
31 }
32
33 template<typename T>
34 constexpr static void concrete_bash_completions_inner(TreeMap<Vector<TransparentString>, String>& states,
35 Span<TransparentStringView> base_commands) {
36 auto parser = get_cli_parser<T>();
37 parser.bash_completions_inner(states, base_commands);
38 }
39
40 template<typename T>
41 constexpr static void concrete_write_zsh_completions_inner(AnyRef<Writer> writer, u32 indentation,
42 Span<TransparentStringView> base_commands) {
43 auto parser = get_cli_parser<T>();
44 parser.write_zsh_completions_inner(writer, indentation, base_commands);
45 }
46
47public:
48 Subcommand() = default;
49
50 template<auto member, typename T>
51 constexpr explicit Subcommand(Constexpr<member>, InPlaceType<T>)
52 : m_parse(concrete_parse<member, T>)
53 , m_bash_completions_inner(concrete_bash_completions_inner<T>)
54 , m_write_zsh_completionions_inner(concrete_write_zsh_completions_inner<T>)
55 , m_name(get_cli_parser<T>().app_name())
56 , m_description(get_cli_parser<T>().app_description()) {}
57
58 constexpr auto parse(void* base, Span<TransparentStringView> input, AnyRef<Writer> writer,
59 Span<TransparentStringView> base_commands = {}) const {
60 DI_ASSERT(m_parse);
61 return m_parse(base, input, writer, base_commands);
62 }
63
64 constexpr void inner_bash_completions(TreeMap<Vector<TransparentString>, String>& states,
65 Span<TransparentStringView> base_commands) const {
66 m_bash_completions_inner(states, base_commands);
67 }
68
69 constexpr void write_zsh_completions_inner(AnyRef<Writer> writer, u32 indentation,
70 Span<TransparentStringView> base_commands) const {
71 m_write_zsh_completionions_inner(writer, indentation, base_commands);
72 }
73
74 constexpr auto name() const -> TransparentStringView { return m_name; }
75 constexpr auto description() const -> StringView { return m_description; }
76
77private:
78 Parse m_parse { nullptr };
79 BashCompletionsInner m_bash_completions_inner { nullptr };
80 ZshCompletionsInner m_write_zsh_completionions_inner { nullptr };
82 StringView m_description;
83};
84}
#define DI_ASSERT(...)
Definition assert_bool.h:7
#define DI_TRY(...)
Definition monad_try.h:13
Any< Interface, RefStorage > AnyRef
Definition any_ref.h:7
constexpr auto get_cli_parser
Definition get_cli_parser.h:32
string::StringViewImpl< string::Utf8Encoding > StringView
Definition string_view.h:12
string::StringImpl< string::Utf8Encoding > String
Definition string.h:11
string::StringViewImpl< string::TransparentEncoding > TransparentStringView
Definition string_view.h:13
Type< detail::MemberPointerClassHelper< RemoveCV< T > > > MemberPointerClass
Definition language.h:195
__UINT32_TYPE__ u32
Definition integers.h:11
Expected< T, Error > Result
Definition result.h:8
constexpr auto parse
Definition parse.h:23