Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : // Licensed under the Apache License, Version 2.0
3 : :
4 : : #include <algorithm>
5 : : #include <charconv>
6 : : #include <cstdint>
7 : : #include <cstdio>
8 : : #include <hpactor/cli/output_formatter.hpp>
9 : : #include <hpactor/cli/pager.hpp>
10 : :
11 : : namespace hpactor {
12 : : namespace cli {
13 : :
14 : 10 : Pager::Pager(uint32_t page_size) : page_size_(page_size) {}
15 : :
16 : 3 : bool Pager::show_page(uint32_t total_items,
17 : : std::function<void(uint32_t offset, uint32_t limit)> render,
18 : : OutputFormatter* output) {
19 : 3 : total_items_ = total_items;
20 : 3 : uint32_t start = current_offset_;
21 : 3 : uint32_t end = std::min(start + page_size_, total_items_);
22 : :
23 : 3 : render(start, end - start);
24 : :
25 : : char buf[128];
26 : 3 : int n = snprintf(buf, sizeof(buf), "Page %u of %u (%u-%u of %u)",
27 : : current_page(), total_pages(), start + 1, end, total_items_);
28 : 6 : output->raw(std::string(buf, static_cast<size_t>(n)));
29 : 6 : output->raw("[n]ext, [p]rev, [q]uit, /search, g<num>");
30 : :
31 : 3 : return end < total_items_;
32 : : }
33 : :
34 : 3 : uint32_t Pager::total_pages() const {
35 : 3 : if (total_items_ == 0)
36 : 0 : return 1;
37 : 3 : return (total_items_ + page_size_ - 1) / page_size_;
38 : : }
39 : :
40 : 3 : void Pager::goto_page(uint32_t page) {
41 : 3 : if (total_items_ > 0) {
42 : 0 : page = std::max(page, 1u);
43 : 0 : page = std::min(page, total_pages());
44 : : }
45 : 3 : current_offset_ = (page - 1) * page_size_;
46 : 3 : }
47 : :
48 : 0 : void Pager::next_page() {
49 : 0 : if (current_offset_ + page_size_ < total_items_) {
50 : 0 : current_offset_ += page_size_;
51 : : }
52 : 0 : }
53 : :
54 : 0 : void Pager::prev_page() {
55 : 0 : if (current_offset_ >= page_size_) {
56 : 0 : current_offset_ -= page_size_;
57 : : }
58 : 0 : }
59 : :
60 : 9 : Pager::Action Pager::parse_input(const std::string& input, std::string& arg) {
61 : 9 : if (input.empty())
62 : 1 : return Action::Next;
63 : 8 : if (input == "n" || input == "next")
64 : 2 : return Action::Next;
65 : 6 : if (input == "p" || input == "prev")
66 : 2 : return Action::Previous;
67 : 4 : if (input == "q" || input == "quit")
68 : 2 : return Action::Quit;
69 : 2 : if (input == "f" || input == "first") {
70 : 0 : goto_page(1);
71 : 0 : return Action::Goto;
72 : : }
73 : 2 : if (input == "l" || input == "last") {
74 : 0 : goto_page(total_pages());
75 : 0 : return Action::Goto;
76 : : }
77 : 2 : if (!input.empty() && input[0] == '/') {
78 : 1 : arg = input.substr(1);
79 : 1 : return Action::Search;
80 : : }
81 : 1 : if (!input.empty() && input[0] == 'g') {
82 : 1 : arg = input.substr(1);
83 : 1 : uint32_t page = 0;
84 : 1 : auto [ptr, ec] = std::from_chars(arg.data(), arg.data() + arg.size(), page);
85 : 1 : if (ec == std::errc{})
86 : 1 : goto_page(page);
87 : 1 : return Action::Goto;
88 : : }
89 : 0 : return Action::Unknown;
90 : : }
91 : :
92 : : } // namespace cli
93 : : } // namespace hpactor
|