Something went wrong. Try again.
Monorepo for PackTools - tooling for Minecraft Modpacks!
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869// JSON for packutils' requests, results and state files. The reader is strict: one document,// duplicate members and bad escapes refused, numbers kept as their text. The writer prints// Packwand's canonical form (2-space indent, `": "`, LF, a trailing newline, raw UTF-8, only `"`,// `\` and control characters escaped), so a state file written here has the bytes Packwand's// own writer gives. AI-authored (Claude).#pragma once
#include <cstddef>#include <cstdint>#include <expected>#include <optional>#include <string>#include <string_view>#include <vector>
namespace packutils::json {
struct Member;
struct Value { enum class Type : std::uint8_t { null, boolean, number, string, array, object };
Type type = Type::null; bool boolean = false; /// A number's text, or a string's decoded UTF-8. std::string text; std::vector<Value> items; /// In document order. std::vector<Member> members;
[[nodiscard]] static Value of_string(std::string_view text); [[nodiscard]] static Value of_integer(std::int64_t number); [[nodiscard]] static Value of_bool(bool on); [[nodiscard]] static Value array(); [[nodiscard]] static Value object();
/// An object's member, or null. [[nodiscard]] const Value *get(std::string_view key) const; /// Appends a member to an object (the caller keeps keys unique). void put(std::string_view key, Value value); void push(Value value);
[[nodiscard]] bool is(Type wanted) const { return type == wanted; } /// A string member's text, or nothing when it is missing or not a string. [[nodiscard]] std::optional<std::string_view> string_at(std::string_view key) const; /// A whole number in `[min, max]` (its text parsed exactly), or nothing. [[nodiscard]] std::optional<std::int64_t> integer(std::int64_t min, std::int64_t max) const;};
struct Member { std::string key; Value value;};
/// Why a document did not parse, with its byte offset.struct ParseError { std::string message; std::size_t offset = 0;};
[[nodiscard]] std::expected<Value, ParseError> parse(std::string_view bytes);
/// The canonical document with its trailing newline.[[nodiscard]] std::string canonical(const Value &value);/// One line, no spaces: for documents only a program reads.[[nodiscard]] std::string compact(const Value &value);
} // namespace packutils::json