std::unique_ptr prepared_item::make_sequential_reader()

in src/native/diffs/core/prepared_item.cpp [116:182]


std::unique_ptr<io::sequential::reader> prepared_item::make_sequential_reader() const
{
	return std::visit(
		overload{
			[](reader_kind &kind)
			{
				auto reader = kind.m_factory->make_reader();
				std::unique_ptr<io::sequential::reader> result =
					std::make_unique<io::sequential::basic_reader_wrapper>(reader);
				return result;
			},
			[](sequential_reader_kind &kind) { return kind.m_factory->make_sequential_reader(); },
			[](slice_kind &kind)
			{
				auto reader = kind.m_item->make_reader();
				auto slice  = reader.slice(kind.m_offset, kind.m_length);
				std::unique_ptr<io::sequential::reader> result =
					std::make_unique<io::sequential::basic_reader_wrapper>(slice);
				return result;
			},
			[](chain_kind &kind)
			{
				std::vector<std::unique_ptr<io::sequential::reader>> readers;
				for (auto &item : kind.m_items)
				{
					readers.emplace_back(item->make_sequential_reader());
				}
				std::unique_ptr<io::sequential::reader> result =
					std::make_unique<io::sequential::chain_reader>(std::move(readers));
				return result;
			},
			[&](fetch_slice_kind &kind)
			{
				// printf("Fetching slice from kitchen...\n");
				std::shared_ptr<prepared_item> fetched_slice;

				// We're going to try to mutate into the reader version
		        // by fetching from the kitchen.
		        // We may wait here while more works is done as a result.
				if (auto kitchen = kind.kitchen.lock())
				{
					fetched_slice = kitchen->fetch_slice(m_item_definition);
				}
				else
				{
					// kitchen is gone!
					ADU_LOG("Kitchen missing when trying to prepare reader.");
					throw errors::user_exception(errors::error_code::diffs_prepared_item_kitchen_gone);
				}

				if (!std::holds_alternative<reader_kind>(fetched_slice->m_kind))
				{
					throw errors::user_exception(
						errors::error_code::diffs_prepared_item_wrong_kind, "Fetched item not reader kind");
				}

				m_kind = fetched_slice->m_kind;

				auto &factory = std::get<reader_kind>(m_kind).m_factory;
				auto reader   = factory->make_reader();
				std::unique_ptr<io::sequential::reader> result =
					std::make_unique<io::sequential::basic_reader_wrapper>(reader);
				return result;
			},
		},
		m_kind);
}