Pretty Diagnostics
Create your own pretty diagnostics
Loading...
Searching...
No Matches
source.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <filesystem>
4#include <optional>
5#include <string>
6#include <vector>
7
8namespace pretty_diagnostics {
15class Location {
16public:
24 Location(size_t row, size_t column, size_t index);
25
29 Location() = delete;
30
39 friend bool operator<(const Location& lhs, const Location& rhs) { return lhs._index < rhs._index; }
40
49 friend bool operator<=(const Location& lhs, const Location& rhs) { return rhs >= lhs; }
50
59 friend bool operator>(const Location& lhs, const Location& rhs) { return rhs < lhs; }
60
69 friend bool operator>=(const Location& lhs, const Location& rhs) { return !(lhs < rhs); }
70
79 friend bool operator==(const Location& lhs, const Location& rhs) {
80 return lhs._row == rhs._row && lhs._column == rhs._column && lhs._index == rhs._index;
81 }
82
91 friend bool operator!=(const Location& lhs, const Location& rhs) { return !(lhs == rhs); }
92
98 [[nodiscard]] auto column() const { return _column; }
99
105 [[nodiscard]] auto index() const { return _index; }
106
112 [[nodiscard]] auto row() const { return _row; }
113
114private:
115 size_t _row, _column;
116 size_t _index;
117};
118
122class Source {
123public:
124 virtual ~Source() = default;
125
134 [[nodiscard]] virtual Location from_coords(size_t row, size_t column) const = 0;
135
143 [[nodiscard]] virtual Location from_index(size_t index) const = 0;
144
153 [[nodiscard]] virtual std::string substr(const Location& start, const Location& end) const = 0;
154
162 [[nodiscard]] virtual std::string line(const Location& location) const = 0;
163
171 [[nodiscard]] virtual std::string line(size_t line_number) const = 0;
172
178 [[nodiscard]] virtual size_t line_count() const = 0;
179
185 [[nodiscard]] virtual const std::string& contents() const = 0;
186
192 [[nodiscard]] virtual std::string path() const = 0;
193
199 [[nodiscard]] virtual size_t size() const = 0;
200};
201
205class StringSource : public Source {
206public:
213 explicit StringSource(std::string contents, std::string display_path = "<memory>");
214
223 [[nodiscard]] Location from_coords(size_t row, size_t column) const override;
224
232 [[nodiscard]] Location from_index(size_t index) const override;
233
242 [[nodiscard]] std::string substr(const Location& start, const Location& end) const override;
243
251 [[nodiscard]] std::string line(const Location& location) const override;
252
260 [[nodiscard]] std::string line(size_t line_number) const override;
261
267 [[nodiscard]] size_t line_count() const override;
268
274 [[nodiscard]] const std::string& contents() const override;
275
281 [[nodiscard]] std::string path() const override;
282
288 [[nodiscard]] size_t size() const override;
289
290private:
291 std::vector<size_t> _line_starts;
292 std::string _display_path;
293 std::string _contents;
294};
295
299class FileSource final : public StringSource {
300public:
307 explicit FileSource(const std::filesystem::path& path, const std::filesystem::path& working_path = std::filesystem::current_path());
308
317 friend bool operator==(const FileSource& lhs, const FileSource& rhs) { return lhs.path() == rhs.path(); }
318
327 friend bool operator!=(const FileSource& lhs, const FileSource& rhs) { return !(lhs == rhs); }
328
329private:
330 [[nodiscard]] static std::string _read_contents(const std::filesystem::path& path);
331};
332} // namespace pretty_diagnostics
333
342std::ostream& operator<<(std::ostream& os, const pretty_diagnostics::Location& location);
343
352std::ostream& operator<<(std::ostream& os, const pretty_diagnostics::StringSource& source);
353
362std::ostream& operator<<(std::ostream& os, const pretty_diagnostics::FileSource& source);
363
372std::ostream& operator<<(std::ostream& os, const pretty_diagnostics::Source& source);
373
374// BSD 3-Clause License
375//
376// Copyright (c) 2025, Timo Behrend
377//
378// Redistribution and use in source and binary forms, with or without
379// modification, are permitted provided that the following conditions are met:
380//
381// 1. Redistributions of source code must retain the above copyright notice, this
382// list of conditions and the following disclaimer.
383//
384// 2. Redistributions in binary form must reproduce the above copyright notice,
385// this list of conditions and the following disclaimer in the documentation
386// and/or other materials provided with the distribution.
387//
388// 3. Neither the name of the copyright holder nor the names of its
389// contributors may be used to endorse or promote products derived from
390// this software without specific prior written permission.
391//
392// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
393// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
394// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
395// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
396// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
397// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
398// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
399// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
400// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
401// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
A Source implementation that reads from a file on disk.
Definition: source.hpp:299
friend bool operator==(const FileSource &lhs, const FileSource &rhs)
Equality compares path.
Definition: source.hpp:317
friend bool operator!=(const FileSource &lhs, const FileSource &rhs)
Inequality based on operator==
Definition: source.hpp:327
FileSource(const std::filesystem::path &path, const std::filesystem::path &working_path=std::filesystem::current_path())
Creates a file source from a filesystem path.
A position inside a Source, expressed as (row, column, index)
Definition: source.hpp:15
auto column() const
Returns the 0-based column number.
Definition: source.hpp:98
auto index() const
Returns the 0-based absolute character index.
Definition: source.hpp:105
Location()=delete
Constructs a default-initialized location (all -1).
Location(size_t row, size_t column, size_t index)
Constructs a location with the given coordinates and absolute index.
friend bool operator>(const Location &lhs, const Location &rhs)
Greater-than comparison derived from <
Definition: source.hpp:59
friend bool operator<(const Location &lhs, const Location &rhs)
Orders locations by their absolute index.
Definition: source.hpp:39
auto row() const
Returns the 0-based row (line) number.
Definition: source.hpp:112
friend bool operator!=(const Location &lhs, const Location &rhs)
Inequality based on operator==
Definition: source.hpp:91
friend bool operator<=(const Location &lhs, const Location &rhs)
Less-than-or-equal comparison derived from >=
Definition: source.hpp:49
friend bool operator>=(const Location &lhs, const Location &rhs)
Greater-than-or-equal comparison derived from <
Definition: source.hpp:69
friend bool operator==(const Location &lhs, const Location &rhs)
Equality compares row, column and index.
Definition: source.hpp:79
Abstract interface for reading and mapping source text.
Definition: source.hpp:122
virtual std::string substr(const Location &start, const Location &end) const =0
Returns the substring between two locations.
virtual Location from_coords(size_t row, size_t column) const =0
Returns a location corresponding to the given row and column.
virtual size_t line_count() const =0
Returns the total number of lines in the source.
virtual ~Source()=default
virtual Location from_index(size_t index) const =0
Returns a location for the given absolute character index.
virtual size_t size() const =0
Returns the total size (in characters) of the source.
virtual std::string line(size_t line_number) const =0
Returns the contents of the specified line number.
virtual std::string line(const Location &location) const =0
Returns the full line at the given location.
virtual const std::string & contents() const =0
Returns the entire contents of the source.
virtual std::string path() const =0
Returns a displayable path or identifier of the source.
A Source implementation that reads from an in-memory string.
Definition: source.hpp:205
Location from_coords(size_t row, size_t column) const override
Maps (row, column) to a Location within the string.
std::string path() const override
Returns a displayable path or identifier of the source.
std::string line(const Location &location) const override
Returns the contents of the line containing the given location.
Location from_index(size_t index) const override
Maps an absolute index to a Location within the string.
std::string substr(const Location &start, const Location &end) const override
Extracts a substring delimited by two locations.
std::string line(size_t line_number) const override
Returns the contents of the specified line number.
size_t size() const override
Returns the total size (in characters) of the source.
const std::string & contents() const override
Returns the entire contents of the source.
StringSource(std::string contents, std::string display_path="<memory>")
Creates a string source with an optional display path.
size_t line_count() const override
Returns the total number of lines in the string.
Definition: color.hpp:5
std::ostream & operator<<(std::ostream &os, const pretty_diagnostics::Location &location)
Streams a readable description of a Location