dius 0.1.0
Loading...
Searching...
No Matches
main.h
Go to the documentation of this file.
1#pragma once
2
3#include "di/cli/prelude.h"
4#include "di/container/string/prelude.h"
5#include "di/container/vector/prelude.h"
6#include "di/meta/core.h"
7#include "dius/print.h"
8
10template<typename T>
11concept HasHelp = requires(T const& value) { value->help; };
12
13template<typename T>
14constexpr auto help_set(T const& result) -> bool {
15 if constexpr (HasHelp<T>) {
16 return result->help;
17 } else {
18 return false;
19 }
20}
21}
22
23#define DIUS_MAIN(Type, NS) \
24 auto main(int argc, char** argv) -> int { \
25 auto args = ::di::Vector<::di::TransparentStringView> {}; \
26 for (int i = 0; i < argc; i++) { \
27 char* arg = argv[i]; \
28 size_t len = 0; \
29 while (arg[len] != '\0') { \
30 len++; \
31 } \
32 args.push_back({ arg, len }); \
33 } \
34 \
35 auto as_span = args.span(); \
36 auto parser = ::di::get_cli_parser<Type>(); \
37 auto result = parser.parse(as_span); \
38 using ParserResult = decltype(result); \
39 constexpr bool has_help = ::dius::main::detail::HasHelp<ParserResult>; \
40 if (!result) { \
41 ::dius::eprintln("Failed to parse command line arguments."_sv); \
42 if constexpr (has_help) { \
43 ::dius::eprintln("Run with '--help' for all list of valid options."_sv); \
44 } \
45 return 2; \
46 } \
47 \
48 if (::dius::main::detail::help_set(result)) { \
49 auto fd_writer = ::dius::SyncFile(::dius::SyncFile::Owned::No, 2); \
50 parser.write_help(fd_writer); \
51 return 0; \
52 } \
53 \
54 using Result = decltype(NS::main(*result)); \
55 if constexpr (::di::concepts::Expected<Result>) { \
56 auto main_result = NS::main(*result); \
57 if (!main_result) { \
58 ::dius::eprintln("Command failed: error: {}"_sv, main_result.error().message()); \
59 return 1; \
60 } \
61 } else { \
62 (void) NS::main(*result); \
63 } \
64 return 0; \
65 }
Definition main.h:11
Definition main.h:9
constexpr auto help_set(T const &result) -> bool
Definition main.h:14