// Glaze Library
// For the license information refer to glaze.hpp

#include "glaze/yaml.hpp"

#include <array>
#include <cmath>
#include <cstdio>
#include <deque>
#include <forward_list>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include "glaze/json/generic.hpp"
#include "ut/ut.hpp"

using namespace ut;

// Test structures
struct simple_struct
{
   int x{};
   double y{};
   std::string name{};
};

template <>
struct glz::meta<simple_struct>
{
   using T = simple_struct;
   static constexpr auto value = object("x", &T::x, "y", &T::y, "name", &T::name);
};

struct nested_struct
{
   std::string title{};
   simple_struct data{};
   std::vector<int> numbers{};
};

struct map_member_struct
{
   std::string title{};
   std::map<std::string, std::string> data{};
};

struct optional_string_inner
{
   std::optional<std::string> desc{};
   int count{};
};

struct optional_string_outer
{
   std::string title{};
   optional_string_inner nested{};
};

struct seq_string_struct
{
   std::string title{};
   std::vector<std::string> items{};
};

struct set_string_struct
{
   std::set<std::string> items{};
};

template <>
struct glz::meta<nested_struct>
{
   using T = nested_struct;
   static constexpr auto value = object("title", &T::title, "data", &T::data, "numbers", &T::numbers);
};

struct nested_generic_member
{
   glz::generic c{};
};

template <>
struct glz::meta<nested_generic_member>
{
   using T = nested_generic_member;
   static constexpr auto value = object("c", &T::c);
};

struct struct_with_nested_generic
{
   nested_generic_member b{};
};

template <>
struct glz::meta<struct_with_nested_generic>
{
   using T = struct_with_nested_generic;
   static constexpr auto value = object("b", &T::b);
};

struct optional_struct
{
   std::string name{};
   std::optional<int> age{};
   std::optional<std::string> email{};
};

struct optional_vector_struct
{
   int x{};
   std::optional<std::vector<int>> items{};
   std::string name{};
};

template <>
struct glz::meta<optional_vector_struct>
{
   using T = optional_vector_struct;
   static constexpr auto value = object("x", &T::x, "items", &T::items, "name", &T::name);
};

template <>
struct glz::meta<optional_struct>
{
   using T = optional_struct;
   static constexpr auto value = object("name", &T::name, "age", &T::age, "email", &T::email);
};

struct bool_struct
{
   bool flag{};
};

template <>
struct glz::meta<bool_struct>
{
   using T = bool_struct;
   static constexpr auto value = object("flag", &T::flag);
};

enum class Color { red, green, blue };

template <>
struct glz::meta<Color>
{
   using enum Color;
   static constexpr auto value = enumerate("red", red, "green", green, "blue", blue);
};

struct enum_struct
{
   std::string name{};
   Color color{};
};

template <>
struct glz::meta<enum_struct>
{
   using T = enum_struct;
   static constexpr auto value = object("name", &T::name, "color", &T::color);
};

struct reflectable_config
{
   std::vector<int> servers{};
};

struct yaml_custom_read_struct
{
   int value{};

   void read_value(const std::string& input) { value = std::stoi(input); }
};

template <>
struct glz::meta<yaml_custom_read_struct>
{
   using T = yaml_custom_read_struct;
   static constexpr auto value = object("value", custom<&T::read_value, &T::value>);
};

// Struct with custom lambda-based read/write for YAML custom_t testing
struct yaml_custom_lambda_struct
{
   std::string label{};
   int score{};

   bool operator==(const yaml_custom_lambda_struct&) const = default;
};

template <>
struct glz::meta<yaml_custom_lambda_struct>
{
   using T = yaml_custom_lambda_struct;

   static constexpr auto read_fn = [](T& t, const std::string& str) {
      auto pos = str.find('|');
      if (pos != std::string::npos) {
         t.label = str.substr(0, pos);
         t.score = std::stoi(str.substr(pos + 1));
      }
   };

   static constexpr auto write_fn = [](const T& t) -> std::string { return t.label + "|" + std::to_string(t.score); };

   static constexpr auto value = object("data", glz::custom<read_fn, write_fn>);
};

// Struct with custom field alongside regular fields
struct yaml_custom_mixed_struct
{
   std::string name{};
   yaml_custom_lambda_struct item{};
   int count{};

   bool operator==(const yaml_custom_mixed_struct&) const = default;
};

template <>
struct glz::meta<yaml_custom_mixed_struct>
{
   using T = yaml_custom_mixed_struct;
   static constexpr auto value = object("name", &T::name, "item", &T::item, "count", &T::count);
};

// Struct with top-level custom serialization (serializes as a single scalar string)
struct yaml_custom_scalar_struct
{
   std::string key{};
   int val{};

   bool operator==(const yaml_custom_scalar_struct&) const = default;
};

template <>
struct glz::meta<yaml_custom_scalar_struct>
{
   using T = yaml_custom_scalar_struct;

   static constexpr auto read_fn = [](T& t, const std::string& str) {
      auto pos = str.find(':');
      if (pos != std::string::npos) {
         t.key = str.substr(0, pos);
         t.val = std::stoi(str.substr(pos + 1));
      }
   };

   static constexpr auto write_fn = [](const T& t) -> std::string { return t.key + ":" + std::to_string(t.val); };

   static constexpr auto value = glz::custom<read_fn, write_fn>;
};

// Struct with compile-time skip for YAML
struct yaml_skip_struct
{
   std::string id{};
   std::string secret{};
   int count{};
};

template <>
struct glz::meta<yaml_skip_struct>
{
   static constexpr bool skip(const std::string_view key, const glz::meta_context&) { return key == "secret"; }
};

// Struct with runtime skip_if for YAML
struct yaml_skip_if_struct
{
   std::string name{};
   int age{};
   std::string city{};
};

template <>
struct glz::meta<yaml_skip_if_struct>
{
   template <class V>
   static constexpr bool skip_if(V&& value, std::string_view key, const glz::meta_context&)
   {
      using D = std::decay_t<V>;
      if constexpr (std::same_as<D, int>) {
         return key == "age" && value == 0;
      }
      else {
         return false;
      }
   }
};

// Struct for empty array tests
struct yaml_empty_array_struct
{
   std::string name{"hello"};
   std::vector<int> items{};
   bool operator==(const yaml_empty_array_struct&) const = default;
};

struct yaml_multi_empty_arrays_struct
{
   std::vector<int> a{};
   std::vector<std::string> b{};
   int x{42};
   bool operator==(const yaml_multi_empty_arrays_struct&) const = default;
};

suite yaml_write_tests = [] {
   "write_simple_struct"_test = [] {
      simple_struct obj{42, 3.14, "test"};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      expect(buffer.find("x: 42") != std::string::npos);
      expect(buffer.find("y: 3.14") != std::string::npos);
      expect(buffer.find("name: test") != std::string::npos);
   };

   "write_nested_struct"_test = [] {
      nested_struct obj{"Hello", {1, 2.5, "inner"}, {1, 2, 3}};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      expect(buffer.find("title: Hello") != std::string::npos);
   };

   "write_vector"_test = [] {
      std::vector<int> vec{1, 2, 3, 4, 5};
      std::string buffer;
      auto ec = glz::write_yaml(vec, buffer);
      expect(!ec);
      expect(buffer.find("- 1") != std::string::npos);
      expect(buffer.find("- 5") != std::string::npos);
   };

   "write_map"_test = [] {
      std::map<std::string, int> m{{"one", 1}, {"two", 2}, {"three", 3}};
      std::string buffer;
      auto ec = glz::write_yaml(m, buffer);
      expect(!ec);
      expect(buffer.find("one: 1") != std::string::npos);
      expect(buffer.find("two: 2") != std::string::npos);
   };

   "write_optional_with_value"_test = [] {
      optional_struct obj{"John", 30, "john@example.com"};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      expect(buffer.find("name: John") != std::string::npos);
      expect(buffer.find("age: 30") != std::string::npos);
   };

   "write_optional_without_value"_test = [] {
      optional_struct obj{"Jane", std::nullopt, std::nullopt};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      expect(buffer.find("name: Jane") != std::string::npos);
   };

   "write_boolean"_test = [] {
      bool_struct obj{true};
      std::string buffer;
      auto ec = glz::write<glz::opts{.format = glz::YAML}>(obj, buffer);
      expect(!ec);
      expect(buffer.find("true") != std::string::npos);
   };

   "write_enum"_test = [] {
      enum_struct obj{"item", Color::green};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      expect(buffer.find("color: green") != std::string::npos);
   };

   "write_string_with_special_chars"_test = [] {
      simple_struct obj{1, 1.0, "hello: world"};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      // Should be quoted because it contains colon
      expect(buffer.find("name:") != std::string::npos);
   };

   "write_flow_style"_test = [] {
      simple_struct obj{42, 3.14, "test"};
      std::string buffer;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto ec = glz::write<opts>(obj, buffer);
      expect(!ec);
      expect(buffer.find("{") != std::string::npos);
      expect(buffer.find("}") != std::string::npos);
   };
};

suite yaml_read_tests = [] {
   "read_simple_block_mapping"_test = [] {
      std::string yaml = R"(x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
      expect(std::abs(obj.y - 3.14) < 0.001);
      expect(obj.name == "test");
   };

   "read_custom_meta_field"_test = [] {
      std::string yaml = "value: '42'";
      yaml_custom_read_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.value == 42);
   };

   "read_flow_mapping"_test = [] {
      std::string yaml = R"({x: 42, y: 3.14, name: test})";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
      expect(std::abs(obj.y - 3.14) < 0.001);
      expect(obj.name == "test");
   };

   "read_flow_sequence"_test = [] {
      std::string yaml = R"([1, 2, 3, 4, 5])";
      std::vector<int> vec{};
      auto ec = glz::read_yaml(vec, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(vec.size() == 5u);
      expect(vec[0] == 1);
      expect(vec[4] == 5);
   };

   "read_block_sequence"_test = [] {
      std::string yaml = R"(- 1
- 2
- 3)";
      std::vector<int> vec{};
      auto ec = glz::read_yaml(vec, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(vec.size() == 3u);
      expect(vec[0] == 1);
      expect(vec[2] == 3);
   };

   "read_double_quoted_string"_test = [] {
      std::string yaml = R"(x: 1
y: 2.0
name: "hello world")";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "hello world");
   };

   "read_single_quoted_string"_test = [] {
      std::string yaml = R"(x: 1
y: 2.0
name: 'hello world')";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "hello world");
   };

   "read_boolean_true"_test = [] {
      std::string yaml = "flag: true";
      bool_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.flag == true);
   };

   "read_boolean_false"_test = [] {
      std::string yaml = "flag: false";
      bool_struct obj{.flag = true};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.flag == false);
   };

   "read_null_optional"_test = [] {
      std::string yaml = R"(name: Test
age: null
email: ~)";
      optional_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "Test");
      expect(!obj.age.has_value());
      expect(!obj.email.has_value());
   };

   "read_optional_with_value"_test = [] {
      std::string yaml = R"(name: Test
age: 25
email: test@example.com)";
      optional_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "Test");
      expect(obj.age.value() == 25);
      expect(obj.email.value() == "test@example.com");
   };

   "read_enum"_test = [] {
      std::string yaml = R"(name: item
color: blue)";
      enum_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "item");
      expect(obj.color == Color::blue);
   };

   "read_map"_test = [] {
      std::string yaml = R"(one: 1
two: 2
three: 3)";
      std::map<std::string, int> m{};
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m["one"] == 1);
      expect(m["two"] == 2);
      expect(m["three"] == 3);
   };

   "read_flow_map"_test = [] {
      std::string yaml = R"({one: 1, two: 2, three: 3})";
      std::map<std::string, int> m{};
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m["one"] == 1);
      expect(m["two"] == 2);
   };

   "read_negative_number"_test = [] {
      std::string yaml = R"(x: -42
y: -3.14
name: neg)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == -42);
      expect(std::abs(obj.y - (-3.14)) < 0.001);
   };

   "read_hex_number"_test = [] {
      std::string yaml = "x: 0xFF\ny: 1.0\nname: hex";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 255);
   };

   "read_underscore_int"_test = [] {
      int value{};
      std::string yaml = "1_000_000";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(value == 1000000);
   };

   "read_underscore_float"_test = [] {
      double value{};
      std::string yaml = "1_234.567_89";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(std::abs(value - 1234.56789) < 0.00001);
   };

   "read_underscore_hex"_test = [] {
      int value{};
      std::string yaml = "0xFF_FF";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(value == 0xFFFF);
   };

   "read_underscore_octal"_test = [] {
      int value{};
      std::string yaml = "0o7_7_7";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(value == 0777);
   };

   "read_underscore_binary"_test = [] {
      int value{};
      std::string yaml = "0b1111_0000";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(value == 0b11110000);
   };

   "read_no_underscore_int"_test = [] {
      int value{};
      std::string yaml = "1000000";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec);
      expect(value == 1000000);
   };

   "read_with_comments"_test = [] {
      std::string yaml = R"(# This is a comment
x: 42 # inline comment
y: 3.14
# Another comment
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
      expect(obj.name == "test");
   };

   // Per YAML spec, # only starts a comment when preceded by whitespace
   "hash_in_plain_scalar"_test = [] {
      std::string yaml = "name: foo#bar";
      simple_struct obj{};
      obj.x = 1;
      obj.y = 1.0;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "foo#bar") << "Hash should be part of scalar, not start comment";
   };

   "hash_with_space_is_comment"_test = [] {
      std::string yaml = "name: foo #bar";
      simple_struct obj{};
      obj.x = 1;
      obj.y = 1.0;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "foo") << "Space+hash should start a comment";
   };

   "multiple_hashes_in_scalar"_test = [] {
      std::string yaml = "name: a#b#c#d";
      simple_struct obj{};
      obj.x = 1;
      obj.y = 1.0;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "a#b#c#d");
   };

   "url_with_fragment"_test = [] {
      std::string yaml = "name: http://example.com/page#section";
      simple_struct obj{};
      obj.x = 1;
      obj.y = 1.0;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "http://example.com/page#section");
   };

   "hash_at_start_is_comment"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
#name: should_be_ignored
name: actual_value)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "actual_value");
   };
};

suite yaml_roundtrip_tests = [] {
   "roundtrip_simple_struct"_test = [] {
      simple_struct original{42, 3.14159, "hello"};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      simple_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed.x == original.x);
      expect(std::abs(parsed.y - original.y) < 0.0001);
      expect(parsed.name == original.name);
   };

   "roundtrip_vector"_test = [] {
      std::vector<int> original{1, 2, 3, 4, 5};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::vector<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed == original);
   };

   "roundtrip_map"_test = [] {
      std::map<std::string, int> original{{"a", 1}, {"b", 2}, {"c", 3}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::map<std::string, int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed == original);
   };

   "roundtrip_optional"_test = [] {
      optional_struct original{"Test", 25, std::nullopt};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      optional_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed.name == original.name);
      expect(parsed.age == original.age);
   };

   "roundtrip_enum"_test = [] {
      enum_struct original{"item", Color::green};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      enum_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed.name == original.name);
      expect(parsed.color == original.color);
   };
};

suite yaml_block_scalar_tests = [] {
   "write_multiline_string"_test = [] {
      simple_struct obj{1, 1.0, "line1\nline2\nline3"};
      std::string buffer;
      auto ec = glz::write_yaml(obj, buffer);
      expect(!ec);
      // Multiline strings should use block scalar or quoted string
   };

   "roundtrip_literal_block_keep_multiple_newlines"_test = [] {
      std::string original = "line1\nline2\n\n\n";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("|+") != std::string::npos);

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "read_literal_block_scalar"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
name: |
  line1
  line2
  line3)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name.find("line1") != std::string::npos);
      expect(obj.name.find("line2") != std::string::npos);
   };

   "read_folded_block_scalar"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
name: >
  this is a
  folded string)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Folded scalar replaces single newlines with spaces
      expect(obj.name.find("this is a") != std::string::npos);
   };
};

suite yaml_writer_edge_case_tests = [] {
   "write_string_chomping_strip_marker"_test = [] {
      const std::string original = "line1\nline2";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "|-\n  line1\n  line2\n");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_string_chomping_clip_marker"_test = [] {
      const std::string original = "line1\nline2\n";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "|\n  line1\n  line2\n");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_string_chomping_keep_marker"_test = [] {
      const std::string original = "line1\nline2\n\n\n";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "|+\n  line1\n  line2\n  \n  \n");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_scalar_prefers_single_quotes_for_colon"_test = [] {
      const std::string original = "hello: world";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "'hello: world'");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_scalar_uses_double_quotes_when_single_quote_present"_test = [] {
      const std::string original = "it's: good";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "\"it's: good\"");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_double_quoted_escapes_tabs_quotes_backslashes_and_control"_test = [] {
      const std::string original = std::string("it's\t\"ok\"\\path") + char(0x01);
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "\"it's\\t\\\"ok\\\"\\\\path\\x01\"");

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "write_bool_like_and_number_like_scalars_are_quoted"_test = [] {
      std::string bool_yaml{};
      auto bool_wec = glz::write_yaml(std::string{"true"}, bool_yaml);
      expect(!bool_wec);
      expect(bool_yaml == "'true'");

      std::string number_yaml{};
      auto num_wec = glz::write_yaml(std::string{"123"}, number_yaml);
      expect(!num_wec);
      expect(number_yaml == "'123'");
   };

   "write_map_keys_with_indicators_are_quoted"_test = [] {
      std::map<std::string, int> value{{"a:b", 1}, {"x#y", 2}};
      std::string yaml{};
      auto wec = glz::write_yaml(value, yaml);
      expect(!wec);
      expect(yaml == "'a:b': 1\n'x#y': 2\n");
   };

   "write_scalar_quotes_string_with_comma"_test = [] {
      const std::string original = "hello, world";
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);
      expect(yaml == "'hello, world'");

      std::string parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == original);
   };

   "write_scalar_quotes_string_with_only_comma"_test = [] {
      const std::string original = "a,b,c";
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);
      expect(yaml == "'a,b,c'");

      std::string parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == original);
   };

   "write_map_keys_with_comma_are_quoted"_test = [] {
      std::map<std::string, int> value{{"a,b", 1}};
      std::string yaml{};
      auto ec = glz::write_yaml(value, yaml);
      expect(!ec);
      expect(yaml == "'a,b': 1\n");
   };

   "write_struct_with_comma_in_string_roundtrip"_test = [] {
      simple_struct original{7, 2.5, "one, two, three"};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      simple_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.x == original.x);
      expect(parsed.name == original.name);
   };

   "write_flow_map_with_multiline_scalar_roundtrip"_test = [] {
      const std::map<std::string, std::string> original{
         {"name", "svc"},
         {"script", "echo start\n./run"},
         {"notes", "line1\nline2\n"},
      };

      std::string yaml{};
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::map<std::string, std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

suite yaml_special_values_tests = [] {
   "read_infinity"_test = [] {
      std::string yaml = "x: 0\ny: .inf\nname: inf";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::isinf(obj.y));
      expect(obj.y > 0);
   };

   "read_negative_infinity"_test = [] {
      std::string yaml = "x: 0\ny: -.inf\nname: ninf";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::isinf(obj.y));
      expect(obj.y < 0);
   };

   "read_nan"_test = [] {
      std::string yaml = "x: 0\ny: .nan\nname: nan";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::isnan(obj.y));
   };
};

suite yaml_tuple_tests = [] {
   "write_tuple_flow"_test = [] {
      std::tuple<int, double, std::string> t{42, 3.14, "hello"};
      std::string buffer;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto ec = glz::write<opts>(t, buffer);
      expect(!ec);
      expect(buffer.find("[42") != std::string::npos);
      expect(buffer.find("3.14") != std::string::npos);
      expect(buffer.find("hello") != std::string::npos);
   };

   "write_tuple_block"_test = [] {
      std::tuple<int, double, std::string> t{42, 3.14, "hello"};
      std::string buffer;
      auto ec = glz::write_yaml(t, buffer);
      expect(!ec);
      expect(buffer.find("- 42") != std::string::npos);
      expect(buffer.find("- 3.14") != std::string::npos);
      expect(buffer.find("- hello") != std::string::npos);
   };

   "read_tuple_flow"_test = [] {
      std::string yaml = "[42, 3.14, hello]";
      std::tuple<int, double, std::string> t{};
      auto ec = glz::read_yaml(t, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::get<0>(t) == 42);
      expect(std::abs(std::get<1>(t) - 3.14) < 0.001);
      expect(std::get<2>(t) == "hello");
   };

   "read_tuple_block"_test = [] {
      std::string yaml = R"(- 42
- 3.14
- hello)";
      std::tuple<int, double, std::string> t{};
      auto ec = glz::read_yaml(t, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::get<0>(t) == 42);
      expect(std::abs(std::get<1>(t) - 3.14) < 0.001);
      expect(std::get<2>(t) == "hello");
   };

   "roundtrip_tuple"_test = [] {
      std::tuple<int, std::string, bool> original{123, "test", true};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::tuple<int, std::string, bool> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::get<0>(parsed) == std::get<0>(original));
      expect(std::get<1>(parsed) == std::get<1>(original));
      expect(std::get<2>(parsed) == std::get<2>(original));
   };
};

suite yaml_pair_tests = [] {
   "write_pair_flow"_test = [] {
      std::pair<std::string, int> p{"answer", 42};
      std::string buffer;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto ec = glz::write<opts>(p, buffer);
      expect(!ec);
      expect(buffer.find("{answer: 42}") != std::string::npos);
   };

   "write_pair_block"_test = [] {
      std::pair<std::string, int> p{"answer", 42};
      std::string buffer;
      auto ec = glz::write_yaml(p, buffer);
      expect(!ec);
      expect(buffer.find("answer: 42") != std::string::npos);
   };

   "read_pair_flow"_test = [] {
      std::string yaml = "{answer: 42}";
      std::pair<std::string, int> p{};
      auto ec = glz::read_yaml(p, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(p.first == "answer");
      expect(p.second == 42);
   };

   "read_pair_block"_test = [] {
      std::string yaml = "answer: 42";
      std::pair<std::string, int> p{};
      auto ec = glz::read_yaml(p, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(p.first == "answer");
      expect(p.second == 42);
   };

   "roundtrip_pair"_test = [] {
      std::pair<std::string, double> original{"pi", 3.14159};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::pair<std::string, double> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed.first == original.first);
      expect(std::abs(parsed.second - original.second) < 0.0001);
   };

   "read_pair_with_nested_value"_test = [] {
      std::string yaml = "{key: [1, 2, 3]}";
      std::pair<std::string, std::vector<int>> p{};
      auto ec = glz::read_yaml(p, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(p.first == "key");
      expect(p.second.size() == 3u);
      expect(p.second[0] == 1);
      expect(p.second[2] == 3);
   };

   "write_vector_of_pairs"_test = [] {
      std::vector<std::pair<std::string, int>> vec{{"one", 1}, {"two", 2}};
      std::string buffer;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto ec = glz::write<opts>(vec, buffer);
      expect(!ec);
      expect(buffer.find("one: 1") != std::string::npos);
      expect(buffer.find("two: 2") != std::string::npos);
   };
};

suite yaml_tag_tests = [] {
   "valid_str_tag"_test = [] {
      std::string yaml = "!!str hello";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello");
   };

   "valid_int_tag"_test = [] {
      std::string yaml = "!!int 42";
      int value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == 42);
   };

   "valid_float_tag"_test = [] {
      std::string yaml = "!!float 3.14";
      double value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::abs(value - 3.14) < 0.001);
   };

   "valid_bool_tag"_test = [] {
      std::string yaml = "!!bool true";
      bool value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == true);
   };

   "valid_null_tag"_test = [] {
      std::string yaml = "!!null null";
      std::optional<int> value{42};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(!value.has_value());
   };

   "valid_seq_tag"_test = [] {
      std::string yaml = "!!seq [1, 2, 3]";
      std::vector<int> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value.size() == 3u);
      expect(value[0] == 1);
   };

   "valid_map_tag"_test = [] {
      std::string yaml = "!!map {a: 1, b: 2}";
      std::map<std::string, int> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value["a"] == 1);
      expect(value["b"] == 2);
   };

   "invalid_str_tag_for_int"_test = [] {
      std::string yaml = "!!str 42";
      int value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "invalid_int_tag_for_string"_test = [] {
      std::string yaml = "!!int hello";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "invalid_bool_tag_for_int"_test = [] {
      std::string yaml = "!!bool 42";
      int value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "invalid_seq_tag_for_map"_test = [] {
      std::string yaml = "!!seq {a: 1}";
      std::map<std::string, int> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "invalid_map_tag_for_seq"_test = [] {
      std::string yaml = "!!map [1, 2, 3]";
      std::vector<int> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "unknown_custom_tag_ignored"_test = [] {
      std::string yaml = "!mytag value";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "value");
   };

   "unknown_shorthand_tag_ignored"_test = [] {
      std::string yaml = "!!custom value";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "value");
   };

   "malformed_named_tag_error"_test = [] {
      std::string yaml = "!invalid{}tag value";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "malformed_verbatim_tag_error"_test = [] {
      std::string yaml = "!<tag:yaml.org,2002:str value";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "malformed_empty_shorthand_tag_error"_test = [] {
      std::string yaml = "!! value";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
      expect(ec.ec == glz::error_code::syntax_error);
   };

   "verbatim_tag_str"_test = [] {
      std::string yaml = "!<tag:yaml.org,2002:str> hello";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello");
   };

   "int_tag_valid_for_float"_test = [] {
      // !!int is valid for float types (widening conversion)
      std::string yaml = "!!int 42";
      double value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == 42.0);
   };

   "map_with_str_tagged_values"_test = [] {
      // Map of string to string - only !!str tags are valid for values
      std::string yaml = R"({name: !!str Alice, city: !!str Boston})";
      std::map<std::string, std::string> obj;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["name"] == "Alice");
      expect(obj["city"] == "Boston");
   };

   "map_with_int_tagged_values"_test = [] {
      // Map of string to int - !!int tags are valid for values
      std::string yaml = R"({count: !!int 100, size: !!int 50})";
      std::map<std::string, int> obj;
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["count"] == 100);
      expect(obj["size"] == 50);
   };

   // ============================================================
   // Comprehensive String Parsing Tests
   // ============================================================

   // Double-quoted string escape tests
   "dq_escape_newline"_test = [] {
      std::string yaml = R"("hello\nworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\nworld");
   };

   "dq_escape_tab"_test = [] {
      std::string yaml = R"("hello\tworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\tworld");
   };

   "dq_escape_carriage_return"_test = [] {
      std::string yaml = R"("hello\rworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\rworld");
   };

   "dq_escape_backslash"_test = [] {
      std::string yaml = R"("hello\\world")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\\world");
   };

   "dq_escape_quote"_test = [] {
      std::string yaml = R"("hello\"world")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\"world");
   };

   "dq_escape_null"_test = [] {
      std::string yaml = R"("hello\0world")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == std::string("hello\0world", 11));
   };

   "dq_escape_bell"_test = [] {
      std::string yaml = R"("hello\aworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\aworld");
   };

   "dq_escape_backspace"_test = [] {
      std::string yaml = R"("hello\bworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\bworld");
   };

   "dq_escape_escape"_test = [] {
      std::string yaml = R"("hello\eworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\x1Bworld"); // ESC = 0x1B
   };

   "dq_escape_formfeed"_test = [] {
      std::string yaml = R"("hello\fworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\fworld");
   };

   "dq_escape_vtab"_test = [] {
      std::string yaml = R"("hello\vworld")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\vworld");
   };

   "dq_escape_slash"_test = [] {
      std::string yaml = R"("hello\/world")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello/world");
   };

   "dq_escape_space"_test = [] {
      std::string yaml = R"("hello\ world")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello world");
   };

   // Hex escape \xXX
   "dq_escape_hex_41"_test = [] {
      std::string yaml = R"("\x41")"; // 'A'
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "A");
   };

   "dq_escape_hex_00"_test = [] {
      std::string yaml = R"("a\x00z")"; // null in middle
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Build expected string carefully to avoid C++ hex escape ambiguity
      std::string expected = "a";
      expected.push_back('\0');
      expected.push_back('z');
      expect(value == expected);
   };

   "dq_escape_hex_ff"_test = [] {
      std::string yaml = R"("\xff")"; // 0xFF
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xc3\xbf");
   };

   "dq_escape_hex_lowercase"_test = [] {
      std::string yaml = R"("\x4a")"; // 'J'
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "J");
   };

   // Unicode escape \uXXXX
   "dq_escape_unicode_ascii"_test = [] {
      std::string yaml = R"("\u0041")"; // 'A'
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "A");
   };

   "dq_escape_unicode_2byte"_test = [] {
      std::string yaml = R"("\u00e9")"; // 'é' (U+00E9)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xc3\xa9"); // UTF-8 encoding of é
   };

   "dq_escape_unicode_3byte"_test = [] {
      std::string yaml = R"("\u4e2d")"; // '中' (U+4E2D)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xe4\xb8\xad"); // UTF-8 encoding
   };

   "dq_escape_unicode_euro"_test = [] {
      std::string yaml = R"("\u20ac")"; // '€' (U+20AC)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xe2\x82\xac"); // UTF-8 encoding
   };

   // Unicode escape \UXXXXXXXX (8 hex digits)
   "dq_escape_unicode8_ascii"_test = [] {
      std::string yaml = R"("\U00000041")"; // 'A'
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "A");
   };

   "dq_escape_unicode8_emoji"_test = [] {
      std::string yaml = R"("\U0001F600")"; // 😀 (U+1F600)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xf0\x9f\x98\x80"); // UTF-8 encoding
   };

   "dq_escape_unicode8_musical"_test = [] {
      std::string yaml = R"("\U0001D11E")"; // 𝄞 (U+1D11E) musical G clef
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\xf0\x9d\x84\x9e"); // UTF-8 encoding
   };

   // YAML-specific escapes
   "dq_escape_next_line"_test = [] {
      std::string yaml = R"("hello\Nworld")"; // \N = U+0085 (Next Line)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\xc2\x85world"); // UTF-8 encoding of U+0085
   };

   "dq_escape_nbsp"_test = [] {
      std::string yaml = R"("hello\_world")"; // \_ = U+00A0 (NBSP)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\xc2\xa0world"); // UTF-8 encoding of U+00A0
   };

   "dq_escape_line_separator"_test = [] {
      std::string yaml = R"("hello\Lworld")"; // \L = U+2028 (Line Separator)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\xe2\x80\xa8world"); // UTF-8 encoding of U+2028
   };

   "dq_escape_para_separator"_test = [] {
      std::string yaml = R"("hello\Pworld")"; // \P = U+2029 (Paragraph Separator)
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\xe2\x80\xa9world"); // UTF-8 encoding of U+2029
   };

   // Multiple escapes in one string
   "dq_multiple_escapes"_test = [] {
      std::string yaml = R"("line1\nline2\ttabbed\\backslash")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "line1\nline2\ttabbed\\backslash");
   };

   "dq_mixed_escapes"_test = [] {
      std::string yaml = R"("\x48\u0065llo\n\U00000057orld")"; // "Hello\nWorld"
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "Hello\nWorld");
   };

   // Edge cases
   "dq_empty_string"_test = [] {
      std::string yaml = R"("")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "");
   };

   "dq_only_escapes"_test = [] {
      std::string yaml = R"("\n\t\r")";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\n\t\r");
   };

   "dq_consecutive_backslashes"_test = [] {
      std::string yaml = R"("\\\\")"; // four backslashes in YAML = two in result
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "\\\\");
   };

   "dq_long_string"_test = [] {
      std::string yaml = "\"" + std::string(1000, 'a') + "\"";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == std::string(1000, 'a'));
   };

   "dq_long_string_with_escapes"_test = [] {
      std::string input;
      for (int i = 0; i < 100; ++i) {
         input += "text\\n";
      }
      std::string yaml = "\"" + input + "\"";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      std::string expected;
      for (int i = 0; i < 100; ++i) {
         expected += "text\n";
      }
      expect(value == expected);
   };

   // Single-quoted string tests
   "sq_basic"_test = [] {
      std::string yaml = "'hello world'";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello world");
   };

   "sq_empty"_test = [] {
      std::string yaml = "''";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "");
   };

   "sq_escaped_quote"_test = [] {
      std::string yaml = "'it''s'"; // '' = single quote
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "it's");
   };

   "sq_multiple_escaped_quotes"_test = [] {
      std::string yaml = "'a''b''c'"; // a'b'c
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "a'b'c");
   };

   "sq_no_escape_processing"_test = [] {
      std::string yaml = R"('hello\nworld')"; // \n should NOT be escaped
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello\\nworld"); // literal backslash-n
   };

   "sq_backslash_preserved"_test = [] {
      std::string yaml = R"('C:\path\to\file')";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "C:\\path\\to\\file");
   };

   "sq_long_string"_test = [] {
      std::string yaml = "'" + std::string(1000, 'b') + "'";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == std::string(1000, 'b'));
   };

   // Plain scalar tests (unquoted)
   "plain_simple"_test = [] {
      std::string yaml = "hello";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello");
   };

   "plain_with_spaces"_test = [] {
      std::string yaml = "hello world";
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == "hello world");
   };

   // Error cases
   "dq_invalid_hex_escape"_test = [] {
      std::string yaml = R"("\xGG")"; // invalid hex
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_incomplete_hex_escape"_test = [] {
      std::string yaml = R"("\x4")"; // only 1 hex digit
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_invalid_unicode_escape"_test = [] {
      std::string yaml = R"("\uGGGG")"; // invalid hex
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_incomplete_unicode_escape"_test = [] {
      std::string yaml = R"("\u004")"; // only 3 hex digits
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_incomplete_unicode8_escape"_test = [] {
      std::string yaml = R"("\U0001F60")"; // only 7 hex digits
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_reject_lone_high_surrogate_u"_test = [] {
      std::string yaml = R"("\uD800")"; // lone high surrogate, not a scalar value
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_reject_lone_low_surrogate_u"_test = [] {
      std::string yaml = R"("\uDC00")"; // lone low surrogate
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_reject_surrogate_unicode8"_test = [] {
      std::string yaml = R"("\U0000D800")"; // surrogate via 8-digit escape
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "dq_unterminated"_test = [] {
      std::string yaml = R"("hello)"; // no closing quote
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "sq_unterminated"_test = [] {
      std::string yaml = "'hello"; // no closing quote
      std::string value;
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   // Strings in object context
   "obj_dq_string_with_escapes"_test = [] {
      std::string yaml = R"(name: "hello\nworld")";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "hello\nworld");
   };

   "obj_sq_string_with_quote"_test = [] {
      std::string yaml = "name: 'it''s working'";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.name == "it's working");
   };

   // Flow sequence with quoted strings
   "flow_seq_dq_strings"_test = [] {
      std::string yaml = R"(["a\nb", "c\td"])";
      std::vector<std::string> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value.size() == 2);
      expect(value[0] == "a\nb");
      expect(value[1] == "c\td");
   };

   "flow_seq_sq_strings"_test = [] {
      std::string yaml = "['it''s', 'won''t']";
      std::vector<std::string> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value.size() == 2);
      expect(value[0] == "it's");
      expect(value[1] == "won't");
   };

   // Flow map with quoted strings
   "flow_map_dq_strings"_test = [] {
      std::string yaml = R"({"key\n1": "val\t1"})";
      std::map<std::string, std::string> value;
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value["key\n1"] == "val\t1");
   };
};

// ============================================================
// Container Type Tests
// ============================================================

suite yaml_container_tests = [] {
   "deque_roundtrip"_test = [] {
      std::deque<int> original{1, 2, 3, 4, 5};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::deque<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "deque_double_roundtrip"_test = [] {
      std::deque<double> original{1.5, 2.7, 3.14, 4.0, 5.555};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::deque<double> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == original.size());
      for (size_t i = 0; i < original.size(); ++i) {
         expect(std::abs(parsed[i] - original[i]) < 0.0001);
      }
   };

   "list_roundtrip"_test = [] {
      std::list<int> original{10, 20, 30, 40, 50};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::list<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "forward_list_write"_test = [] {
      std::forward_list<int> original{5, 4, 3, 2, 1};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // forward_list reading not supported, just verify write works
      expect(yaml.find("5") != std::string::npos);
   };

   "set_roundtrip"_test = [] {
      std::set<int> original{5, 3, 1, 4, 2};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::set<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "unordered_set_roundtrip"_test = [] {
      std::unordered_set<int> original{10, 20, 30, 40, 50};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::unordered_set<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "set_string_roundtrip"_test = [] {
      std::set<std::string> original{"apple", "banana", "cherry"};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::set<std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "set_block_sequence"_test = [] {
      std::string yaml = R"(- 5
- 3
- 1
- 4
- 2
)";
      std::set<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == std::set<int>{1, 2, 3, 4, 5});
   };

   "set_string_block_sequence"_test = [] {
      std::string yaml = R"(- apple
- banana
- cherry
)";
      std::set<std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == std::set<std::string>{"apple", "banana", "cherry"});
   };

   "set_block_sequence_in_struct"_test = [] {
      std::string yaml = R"(items:
  - s1
  - s2
  - s3
)";
      set_string_struct parsed{};
      auto rec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.items == std::set<std::string>{"s1", "s2", "s3"});
   };

   "vector_of_vectors_flow"_test = [] {
      std::vector<std::vector<int>> original{{1, 2, 3}, {4, 5}, {6, 7, 8, 9}};
      std::string yaml;
      // Use flow style for nested sequences to ensure parsability
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::vector<std::vector<int>> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "vector_of_strings"_test = [] {
      std::vector<std::string> original{"hello", "world", "test"};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::vector<std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "empty_vector"_test = [] {
      std::vector<int> original{};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // Empty sequence writes as [] in flow style
      expect(yaml == "[]" || yaml == "");
   };

   "empty_map"_test = [] {
      std::map<std::string, int> original{};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // Empty map writes as {} in flow style
      expect(yaml == "{}" || yaml == "");
   };
};

// ============================================================
// Sequence overwrite semantics (GitHub issue #2694)
// Reading a YAML sequence into a pre-populated container must OVERWRITE the
// existing contents (matching the JSON parser), not append to them.
// ============================================================

struct overwrite_struct
{
   std::vector<int> a = std::vector{3, 2, 4};
   int b = 4;
};

struct yaml_append_arrays_opts : glz::opts
{
   bool append_arrays = true;
};

// Move-constructible but NOT move-assignable, with settable members. Used to
// guard against a regression where inserting into a map of such a type via
// insert_or_assign would fail to compile (it must fall back to emplace).
struct non_assignable_value
{
   int a{};
   int b{};
   non_assignable_value() = default;
   non_assignable_value(const non_assignable_value&) = default;
   non_assignable_value(non_assignable_value&&) = default;
   non_assignable_value& operator=(const non_assignable_value&) = delete;
   non_assignable_value& operator=(non_assignable_value&&) = delete;
};

template <>
struct glz::meta<non_assignable_value>
{
   using T = non_assignable_value;
   static constexpr auto value = object("a", &T::a, "b", &T::b);
};

suite yaml_overwrite_semantics_tests = [] {
   // Exact reproduction from issue #2694: block sequence into a defaulted member.
   "issue_2694_block_sequence_member"_test = [] {
      overwrite_struct data{};
      const std::string yaml = "a:\n  - 3\n  - 4\nb: 2";
      auto ec = glz::read_yaml(data, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(data.a == std::vector{3, 4}); // previously appended to {3,2,4}
      expect(data.b == 2);
   };

   "flow_sequence_grows"_test = [] {
      std::vector<int> v{7};
      const std::string yaml = "[1, 2, 3, 4]";
      auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == std::vector{1, 2, 3, 4});
   };

   "flow_sequence_shrinks"_test = [] {
      std::vector<int> v{9, 9, 9, 9, 9};
      const std::string yaml = "[1, 2]";
      auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == std::vector{1, 2});
   };

   "block_sequence_shrinks"_test = [] {
      std::vector<int> v{9, 9, 9, 9, 9};
      const std::string yaml = "- 1\n- 2\n";
      auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == std::vector{1, 2});
   };

   "empty_flow_sequence_clears"_test = [] {
      std::vector<int> v{1, 2, 3};
      const std::string yaml = "[]";
      auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v.empty());
   };

   "same_size_replaces_not_merges"_test = [] {
      std::vector<int> v{5, 6, 7};
      const std::string yaml = "[1, 2, 3]";
      auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == std::vector{1, 2, 3});
   };

   "consecutive_reads_into_same_variable"_test = [] {
      std::vector<int> v;
      auto ec1 = glz::read_yaml(v, std::string{"[1, 2, 3]"});
      expect(!ec1);
      expect(v == std::vector{1, 2, 3});
      auto ec2 = glz::read_yaml(v, std::string{"[4, 5]"});
      expect(!ec2);
      expect(v == std::vector{4, 5}); // not {1, 2, 3, 4, 5}
   };

   "deque_overwrites"_test = [] {
      std::deque<int> d{9, 9, 9};
      auto ec = glz::read_yaml(d, std::string{"[1, 2]"});
      expect(!ec);
      expect(d == std::deque<int>{1, 2});
   };

   "list_overwrites"_test = [] {
      std::list<int> l{9, 9, 9};
      auto ec = glz::read_yaml(l, std::string{"- 1\n- 2\n"});
      expect(!ec);
      expect(l == std::list<int>{1, 2});
   };

   "set_block_overwrites"_test = [] {
      std::set<int> s{100, 200};
      auto ec = glz::read_yaml(s, std::string{"- 1\n- 2\n- 3\n"});
      expect(!ec);
      expect(s == std::set<int>{1, 2, 3}); // old members gone
   };

   "set_flow_overwrites"_test = [] {
      std::set<int> s{100, 200};
      auto ec = glz::read_yaml(s, std::string{"[1, 2, 3]"});
      expect(!ec);
      expect(s == std::set<int>{1, 2, 3});
   };

   "unordered_set_overwrites"_test = [] {
      std::unordered_set<int> s{100, 200};
      auto ec = glz::read_yaml(s, std::string{"[1, 2, 3]"});
      expect(!ec);
      expect(s == std::unordered_set<int>{1, 2, 3});
   };

   "nested_vectors_overwrite"_test = [] {
      // Outer shrinks and each reused inner element is cleared, not appended into.
      std::vector<std::vector<int>> v{{9, 9, 9}, {8, 8}};
      auto ec = glz::read_yaml(v, std::string{"[[1, 2], [3]]"});
      expect(!ec);
      expect(v == std::vector<std::vector<int>>{{1, 2}, {3}});
   };

   "struct_member_reuse_across_reads"_test = [] {
      overwrite_struct data{};
      data.a = {9, 9, 9, 9};
      const std::string yaml = "a: [1, 2]\nb: 5";
      auto ec = glz::read_yaml(data, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(data.a == std::vector{1, 2});
      expect(data.b == 5);
   };

   // std::array is fixed-size: overwritten in place, never cleared/resized.
   "fixed_array_overwrites_in_place"_test = [] {
      std::array<int, 3> arr{9, 9, 9};
      auto ec = glz::read_yaml(arr, std::string{"[1, 2, 3]"});
      expect(!ec);
      expect(arr == std::array<int, 3>{1, 2, 3});
   };

   // Opting into append_arrays keeps the pre-existing contents (matches JSON).
   "append_arrays_option_still_appends"_test = [] {
      std::vector<int> v{1, 2, 3};
      constexpr yaml_append_arrays_opts opts{{.format = glz::YAML}};
      auto ec = glz::read<opts>(v, std::string{"[4, 5, 6]"});
      expect(!ec);
      expect(v == std::vector{1, 2, 3, 4, 5, 6});
   };

   // ---- Maps/objects: overwrite an existing key's value, keep other keys ----
   // (matches JSON's value[key] merge; a full clear would wrongly drop key "b")

   "map_block_overwrites_existing_key"_test = [] {
      std::map<std::string, std::vector<int>> m{{"a", {7, 8, 9}}};
      const std::string yaml = "a:\n  - 1\n  - 2\n";
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m["a"] == std::vector{1, 2}); // overwritten, not appended
      expect(m.size() == 1u);
   };

   "map_flow_overwrites_and_keeps_other_keys"_test = [] {
      std::map<std::string, int> m{{"a", 1}, {"b", 2}};
      const std::string yaml = "{a: 9}";
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m["a"] == 9); // overwritten
      expect(m["b"] == 2); // untouched
      expect(m.size() == 2u);
   };

   "map_block_overwrites_adds_and_keeps"_test = [] {
      std::map<std::string, int> m{{"a", 1}, {"b", 2}};
      const std::string yaml = "a: 100\nc: 3";
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m["a"] == 100); // overwritten
      expect(m["b"] == 2); // kept
      expect(m["c"] == 3); // added
      expect(m.size() == 3u);
   };

   "unordered_map_overwrites"_test = [] {
      std::unordered_map<std::string, int> m{{"a", 1}};
      auto ec = glz::read_yaml(m, std::string{"a: 42\nb: 7"});
      expect(!ec);
      expect(m["a"] == 42);
      expect(m["b"] == 7);
   };

   "map_consecutive_reads_merge_and_overwrite"_test = [] {
      std::map<std::string, int> m;
      expect(!glz::read_yaml(m, std::string{"a: 1\nb: 2"}));
      expect(!glz::read_yaml(m, std::string{"a: 9"}));
      expect(m["a"] == 9); // overwritten on second read
      expect(m["b"] == 2); // kept from first read
   };

   // A duplicate key within a single document keeps its FIRST value. YAML
   // mappings disallow duplicate keys; glaze resolves them first-wins (see the
   // conformance suite, e.g. X38W), which differs from JSON's last-wins.
   "map_duplicate_key_first_wins"_test = [] {
      std::map<std::string, int> m;
      auto ec = glz::read_yaml(m, std::string{"a: 1\na: 2"});
      expect(!ec);
      expect(m["a"] == 1);
   };

   // A pre-existing key (from before the read) is still overwritten even though
   // in-document duplicates are first-wins: the first document occurrence wins
   // over the prior value, later duplicates are ignored.
   "map_preexisting_overwritten_but_indoc_first_wins"_test = [] {
      std::map<std::string, int> m{{"a", 100}};
      auto ec = glz::read_yaml(m, std::string{"a: 1\na: 2"});
      expect(!ec);
      expect(m["a"] == 1); // 100 overwritten by first doc value, second ignored
   };

   // glz::generic object entries overwrite too (routes through the map handler).
   "generic_object_overwrites"_test = [] {
      glz::generic j;
      expect(!glz::read_yaml(j, std::string{"a:\n  - 1\n  - 2\n  - 3\nb: 5"}));
      expect(!glz::read_yaml(j, std::string{"a:\n  - 9\nb: 6"}));
      expect(j.is_object());
      if (j.is_object()) {
         auto& obj = j.get_object();
         expect(obj["a"].is_array());
         if (obj["a"].is_array()) expect(obj["a"].get_array().size() == 1u);
         expect(obj["b"].get<double>() == 6.0);
      }
   };

   // A move-constructible but non-assignable mapped_type must still compile and
   // read: the insert_or_assign path is guarded on assignability and falls back
   // to emplace for such types (which then keep the prior emplace behavior).
   "map_of_non_assignable_value_reads"_test = [] {
      std::map<std::string, non_assignable_value> m;
      const std::string yaml = "w1:\n  a: 1\n  b: 2\n";
      auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(m.at("w1").a == 1);
      expect(m.at("w1").b == 2);
   };
};

// ============================================================
// Map with Various Key Types
// ============================================================

suite yaml_map_key_tests = [] {
   "map_int_keys_roundtrip"_test = [] {
      std::map<int, std::string> original{{1, "one"}, {2, "two"}, {3, "three"}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::map<int, std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "map_int_int_roundtrip"_test = [] {
      std::map<int, int> original{{1, 100}, {2, 200}, {3, 300}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::map<int, int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "unordered_map_string_int"_test = [] {
      std::unordered_map<std::string, int> original{{"alpha", 1}, {"beta", 2}, {"gamma", 3}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::unordered_map<std::string, int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "unordered_map_int_double"_test = [] {
      std::unordered_map<int, double> original{{1, 1.1}, {2, 2.2}, {3, 3.3}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::unordered_map<int, double> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == original.size());
      for (const auto& [k, v] : original) {
         expect(std::abs(parsed[k] - v) < 0.0001);
      }
   };

   "map_nested_value_flow"_test = [] {
      std::map<std::string, std::vector<int>> original{{"nums", {1, 2, 3}}, {"more", {4, 5}}};
      std::string yaml;
      // Use flow style for nested structures
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::map<std::string, std::vector<int>> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

// ============================================================
// Nullable Type Tests
// ============================================================

suite yaml_nullable_tests = [] {
   "shared_ptr_write"_test = [] {
      auto original = std::make_shared<int>(42);
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("42") != std::string::npos);
   };

   "shared_ptr_null_write"_test = [] {
      std::shared_ptr<int> original;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("null") != std::string::npos);
   };

   "unique_ptr_write"_test = [] {
      auto original = std::make_unique<double>(3.14);
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("3.14") != std::string::npos);
   };

   "unique_ptr_null_write"_test = [] {
      std::unique_ptr<std::string> original;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("null") != std::string::npos);
   };

   "optional_nested_struct"_test = [] {
      std::optional<simple_struct> original{simple_struct{10, 2.5, "nested"}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::optional<simple_struct> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.has_value());
      expect(parsed->x == 10);
      expect(std::abs(parsed->y - 2.5) < 0.001);
      expect(parsed->name == "nested");
   };

   "shared_ptr_struct_write"_test = [] {
      auto original = std::make_shared<simple_struct>(simple_struct{5, 1.5, "ptr"});
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("x:") != std::string::npos);
      expect(yaml.find("5") != std::string::npos);
   };

   "shared_ptr_read_scalar"_test = [] {
      std::shared_ptr<int> value;
      const std::string yaml = "42";
      auto rec = glz::read_yaml(value, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(value != nullptr);
      expect(*value == 42);
   };

   "shared_ptr_read_null"_test = [] {
      std::shared_ptr<int> value = std::make_shared<int>(7);
      const std::string yaml = "null";
      auto rec = glz::read_yaml(value, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(value == nullptr);
   };

   "unique_ptr_read_scalar"_test = [] {
      std::unique_ptr<double> value;
      const std::string yaml = "3.14";
      auto rec = glz::read_yaml(value, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(value != nullptr);
      expect(std::abs(*value - 3.14) < 0.0001);
   };

   "unique_ptr_read_null"_test = [] {
      std::unique_ptr<std::string> value = std::make_unique<std::string>("seed");
      const std::string yaml = "null";
      auto rec = glz::read_yaml(value, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(value == nullptr);
   };

   "shared_ptr_struct_roundtrip"_test = [] {
      auto original = std::make_shared<simple_struct>(simple_struct{5, 1.5, "ptr"});
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::shared_ptr<simple_struct> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed != nullptr);
      expect(parsed->x == 5);
      expect(std::abs(parsed->y - 1.5) < 0.001);
      expect(parsed->name == "ptr");
   };

   "unique_ptr_struct_roundtrip"_test = [] {
      auto original = std::make_unique<simple_struct>(simple_struct{9, 4.5, "uniq"});
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::unique_ptr<simple_struct> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed != nullptr);
      expect(parsed->x == 9);
      expect(std::abs(parsed->y - 4.5) < 0.001);
      expect(parsed->name == "uniq");
   };

   "unique_ptr_read_overwrites_existing"_test = [] {
      std::unique_ptr<int> value = std::make_unique<int>(99);
      const std::string yaml = "7";
      auto rec = glz::read_yaml(value, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(value != nullptr);
      expect(*value == 7);
   };
};

// ============================================================
// Array Type Tests
// ============================================================

suite yaml_array_tests = [] {
   "std_array_int_roundtrip"_test = [] {
      std::array<int, 5> original{1, 2, 3, 4, 5};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::array<int, 5> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "std_array_double_roundtrip"_test = [] {
      std::array<double, 3> original{1.1, 2.2, 3.3};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::array<double, 3> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      for (size_t i = 0; i < 3; ++i) {
         expect(std::abs(parsed[i] - original[i]) < 0.001);
      }
   };

   "std_array_string_roundtrip"_test = [] {
      std::array<std::string, 3> original{"one", "two", "three"};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::array<std::string, 3> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "nested_array_roundtrip"_test = [] {
      std::array<std::array<int, 2>, 3> original{{{1, 2}, {3, 4}, {5, 6}}};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::array<std::array<int, 2>, 3> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

// ============================================================
// Number Edge Case Tests
// ============================================================

suite yaml_number_tests = [] {
   "large_integer"_test = [] {
      int64_t original = 9223372036854775807LL; // Max int64
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      int64_t parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "large_negative_integer"_test = [] {
      int64_t original = -9223372036854775807LL;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      int64_t parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "uint64_max"_test = [] {
      uint64_t original = 18446744073709551615ULL; // Max uint64
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      uint64_t parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "scientific_notation"_test = [] {
      std::string yaml = "1.5e10";
      double parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::abs(parsed - 1.5e10) < 1e5);
   };

   "negative_scientific"_test = [] {
      std::string yaml = "-2.5e-5";
      double parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::abs(parsed - (-2.5e-5)) < 1e-10);
   };

   "zero_values"_test = [] {
      int i{};
      std::string yaml_i = "0";
      expect(!glz::read_yaml(i, yaml_i));
      expect(i == 0);

      double d{};
      std::string yaml_d = "0.0";
      expect(!glz::read_yaml(d, yaml_d));
      expect(d == 0.0);
   };

   "float_precision"_test = [] {
      float original = 3.14159265f;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      float parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::abs(parsed - original) < 0.0001f);
   };

   "octal_number"_test = [] {
      std::string yaml = "0o755";
      int parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == 0755);
   };

   "binary_number"_test = [] {
      std::string yaml = "0b101010";
      int parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == 42);
   };

   "write_infinity"_test = [] {
      double original = std::numeric_limits<double>::infinity();
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // YAML might use .inf, .Inf, inf, Inf, or other representation
      expect(!yaml.empty());
   };

   "write_nan"_test = [] {
      double original = std::numeric_limits<double>::quiet_NaN();
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // YAML might use .nan, .NaN, nan, NaN, or other representation
      expect(!yaml.empty());
   };
};

// ============================================================
// Variant Type Tests
// ============================================================

struct variant_a
{
   int value{};
};

struct variant_b
{
   std::string text{};
};

template <>
struct glz::meta<variant_a>
{
   using T = variant_a;
   static constexpr auto value = object("value", &T::value);
};

template <>
struct glz::meta<variant_b>
{
   using T = variant_b;
   static constexpr auto value = object("text", &T::text);
};

suite yaml_variant_tests = [] {
   "variant_int_double_string"_test = [] {
      std::variant<int, double, std::string> original = 42;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::variant<int, double, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<int>(parsed));
      expect(std::get<int>(parsed) == 42);
   };

   "variant_double_value"_test = [] {
      std::variant<int, double, std::string> original = 3.14;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::variant<int, double, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      // Note: May parse as int if no decimal point in output
   };

   "variant_string_value"_test = [] {
      std::variant<int, double, std::string> original = std::string("hello");
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::variant<int, double, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed));
      expect(std::get<std::string>(parsed) == "hello");
   };

   "generic_empty_object"_test = [] {
      std::string yaml = "{}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
   };

   "generic_empty_array"_test = [] {
      std::string yaml = "[]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
   };

   "generic_string"_test = [] {
      std::string yaml = "\"hello world\"";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed.data));
      expect(std::get<std::string>(parsed.data) == "hello world");
   };

   "generic_number"_test = [] {
      std::string yaml = "42.5";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::get<double>(parsed.data) == 42.5);
   };

   "generic_boolean_true"_test = [] {
      std::string yaml = "true";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed.data));
      expect(std::get<bool>(parsed.data) == true);
   };

   "generic_boolean_false"_test = [] {
      std::string yaml = "false";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed.data));
      expect(std::get<bool>(parsed.data) == false);
   };

   "generic_null"_test = [] {
      std::string yaml = "null";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::nullptr_t>(parsed.data));
   };

   "generic_object_with_values"_test = [] {
      std::string yaml = "{name: \"test\", value: 123}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
   };

   "generic_array_with_values"_test = [] {
      std::string yaml = "[1, 2, 3]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3);
   };

   // ============================================================
   // Extended glz::generic YAML Tests
   // ============================================================

   // Number format tests
   "generic_integer"_test = [] {
      std::string yaml = "42";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::get<double>(parsed.data) == 42.0);
   };

   "generic_negative_integer"_test = [] {
      std::string yaml = "-123";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::get<double>(parsed.data) == -123.0);
   };

   "generic_negative_float"_test = [] {
      std::string yaml = "-3.14159";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::abs(std::get<double>(parsed.data) - (-3.14159)) < 1e-10);
   };

   "generic_scientific_notation"_test = [] {
      std::string yaml = "1.5e10";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::get<double>(parsed.data) == 1.5e10);
   };

   "generic_negative_exponent"_test = [] {
      std::string yaml = "2.5e-3";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::abs(std::get<double>(parsed.data) - 0.0025) < 1e-10);
   };

   // Boolean format variations
   "generic_boolean_True"_test = [] {
      std::string yaml = "True";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed.data));
      expect(std::get<bool>(parsed.data) == true);
   };

   "generic_boolean_FALSE"_test = [] {
      std::string yaml = "FALSE";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed.data));
      expect(std::get<bool>(parsed.data) == false);
   };

   // Null format variations
   "generic_null_tilde"_test = [] {
      std::string yaml = "~";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::nullptr_t>(parsed.data));
   };

   "generic_null_Null"_test = [] {
      std::string yaml = "Null";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::nullptr_t>(parsed.data));
   };

   "generic_null_NULL"_test = [] {
      std::string yaml = "NULL";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::nullptr_t>(parsed.data));
   };

   // String format tests
   "generic_single_quoted_string"_test = [] {
      std::string yaml = "'hello world'";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed.data));
      expect(std::get<std::string>(parsed.data) == "hello world");
   };

   "generic_string_with_escapes"_test = [] {
      std::string yaml = "\"hello\\nworld\"";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed.data));
      expect(std::get<std::string>(parsed.data) == "hello\nworld");
   };

   // Nested object tests
   "generic_nested_object"_test = [] {
      std::string yaml = "{outer: {inner: {value: 42}}}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& outer = std::get<glz::generic::object_t>(parsed.data);
      expect(outer.contains("outer"));
      expect(std::holds_alternative<glz::generic::object_t>(outer.at("outer").data));

      auto& inner_obj = std::get<glz::generic::object_t>(outer.at("outer").data);
      expect(inner_obj.contains("inner"));
   };

   "generic_object_with_array"_test = [] {
      std::string yaml = "{name: \"test\", values: [1, 2, 3]}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("name"));
      expect(obj.contains("values"));
      expect(std::holds_alternative<std::string>(obj.at("name").data));
      expect(std::holds_alternative<glz::generic::array_t>(obj.at("values").data));

      auto& arr = std::get<glz::generic::array_t>(obj.at("values").data);
      expect(arr.size() == 3);
   };

   // Nested array tests
   "generic_nested_array"_test = [] {
      std::string yaml = "[[1, 2], [3, 4], [5, 6]]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3);

      for (const auto& inner : arr) {
         expect(std::holds_alternative<glz::generic::array_t>(inner.data));
         expect(std::get<glz::generic::array_t>(inner.data).size() == 2);
      }
   };

   "generic_array_of_objects"_test = [] {
      std::string yaml = "[{a: 1}, {b: 2}, {c: 3}]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3);

      for (const auto& item : arr) {
         expect(std::holds_alternative<glz::generic::object_t>(item.data));
      }
   };

   // Mixed type array
   "generic_mixed_array"_test = [] {
      std::string yaml = "[42, \"hello\", true, null, 3.14]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 5);
      expect(std::holds_alternative<double>(arr[0].data));
      expect(std::holds_alternative<std::string>(arr[1].data));
      expect(std::holds_alternative<bool>(arr[2].data));
      expect(std::holds_alternative<std::nullptr_t>(arr[3].data));
      expect(std::holds_alternative<double>(arr[4].data));
   };

   // Complex nested structure
   "generic_complex_structure"_test = [] {
      std::string yaml =
         "{users: [{name: \"Alice\", age: 30, active: true}, {name: \"Bob\", age: 25, active: false}], "
         "metadata: {version: 1.5, tags: [\"prod\", \"v2\"]}, nullable_field: null}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("users"));
      expect(root.contains("metadata"));
      expect(root.contains("nullable_field"));

      // Check users array
      auto& users = std::get<glz::generic::array_t>(root.at("users").data);
      expect(users.size() == 2);

      auto& alice = std::get<glz::generic::object_t>(users[0].data);
      expect(std::get<std::string>(alice.at("name").data) == "Alice");
      expect(std::get<double>(alice.at("age").data) == 30.0);
      expect(std::get<bool>(alice.at("active").data) == true);

      // Check metadata
      auto& metadata = std::get<glz::generic::object_t>(root.at("metadata").data);
      expect(std::get<double>(metadata.at("version").data) == 1.5);

      auto& tags = std::get<glz::generic::array_t>(metadata.at("tags").data);
      expect(tags.size() == 2);

      // Check nullable field
      expect(std::holds_alternative<std::nullptr_t>(root.at("nullable_field").data));
   };

   // Deeply nested structure
   "generic_deeply_nested"_test = [] {
      std::string yaml = "{a: {b: {c: {d: {e: {f: 42}}}}}}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      // Navigate through the nesting
      auto* current = &parsed;
      for (const char* key : {"a", "b", "c", "d", "e"}) {
         expect(std::holds_alternative<glz::generic::object_t>(current->data));
         auto& obj = std::get<glz::generic::object_t>(current->data);
         expect(obj.contains(key));
         current = &obj.at(key);
      }
      expect(std::holds_alternative<glz::generic::object_t>(current->data));
      auto& final_obj = std::get<glz::generic::object_t>(current->data);
      expect(std::get<double>(final_obj.at("f").data) == 42.0);
   };

   // Object with all value types
   "generic_object_all_types"_test = [] {
      std::string yaml =
         "{string_val: \"text\", int_val: 42, float_val: 3.14, bool_true: true, "
         "bool_false: false, null_val: null, array_val: [1, 2], object_val: {nested: true}}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj.at("string_val").data));
      expect(std::holds_alternative<double>(obj.at("int_val").data));
      expect(std::holds_alternative<double>(obj.at("float_val").data));
      expect(std::holds_alternative<bool>(obj.at("bool_true").data));
      expect(std::holds_alternative<bool>(obj.at("bool_false").data));
      expect(std::holds_alternative<std::nullptr_t>(obj.at("null_val").data));
      expect(std::holds_alternative<glz::generic::array_t>(obj.at("array_val").data));
      expect(std::holds_alternative<glz::generic::object_t>(obj.at("object_val").data));
   };

   // Flow style with whitespace variations
   "generic_flow_object_with_spaces"_test = [] {
      std::string yaml = "{ name: \"John\", age: 30, active: true }";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 3);
      expect(std::get<std::string>(obj.at("name").data) == "John");
      expect(std::get<double>(obj.at("age").data) == 30.0);
      expect(std::get<bool>(obj.at("active").data) == true);
   };

   "generic_flow_array_with_spaces"_test = [] {
      std::string yaml = "[ 1, 2, 3 ]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3);
      expect(std::get<double>(arr[0].data) == 1.0);
      expect(std::get<double>(arr[1].data) == 2.0);
      expect(std::get<double>(arr[2].data) == 3.0);
   };

   "generic_flow_nested"_test = [] {
      std::string yaml = "{person: {name: \"Alice\", age: 25, hobbies: [\"reading\", \"coding\"]}}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("person"));

      auto& person = std::get<glz::generic::object_t>(root.at("person").data);
      expect(std::get<std::string>(person.at("name").data) == "Alice");
      expect(std::get<double>(person.at("age").data) == 25.0);

      auto& hobbies = std::get<glz::generic::array_t>(person.at("hobbies").data);
      expect(hobbies.size() == 2);
   };

   // Edge cases
   "generic_empty_string"_test = [] {
      std::string yaml = "\"\"";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed.data));
      expect(std::get<std::string>(parsed.data).empty());
   };

   "generic_zero"_test = [] {
      std::string yaml = "0";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
      expect(std::get<double>(parsed.data) == 0.0);
   };

   "generic_negative_zero"_test = [] {
      std::string yaml = "-0";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
   };

   "generic_object_single_key"_test = [] {
      std::string yaml = "{key: \"value\"}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1);
      expect(std::get<std::string>(obj.at("key").data) == "value");
   };

   "generic_array_single_element"_test = [] {
      std::string yaml = "[42]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      expect(std::get<double>(arr[0].data) == 42.0);
   };

   "generic_object_numeric_string_key"_test = [] {
      std::string yaml = "{\"123\": \"numeric key\"}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("123"));
   };

   // Large numbers
   "generic_large_integer"_test = [] {
      std::string yaml = "9007199254740992";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
   };

   "generic_very_small_float"_test = [] {
      std::string yaml = "1e-308";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed.data));
   };
};

// ============================================================
// Complex Nested Structure Tests
// ============================================================

struct address
{
   std::string street{};
   std::string city{};
   int zip{};
};

template <>
struct glz::meta<address>
{
   using T = address;
   static constexpr auto value = object("street", &T::street, "city", &T::city, "zip", &T::zip);
};

struct person
{
   std::string name{};
   int age{};
   address addr{};
   std::vector<std::string> hobbies{};
};

template <>
struct glz::meta<person>
{
   using T = person;
   static constexpr auto value = object("name", &T::name, "age", &T::age, "addr", &T::addr, "hobbies", &T::hobbies);
};

struct company
{
   std::string name{};
   std::vector<person> employees{};
   std::map<std::string, int> departments{};
};

template <>
struct glz::meta<company>
{
   using T = company;
   static constexpr auto value = object("name", &T::name, "employees", &T::employees, "departments", &T::departments);
};

suite yaml_complex_struct_tests = [] {
   "person_roundtrip"_test = [] {
      person original{"John Doe", 30, {"123 Main St", "Springfield", 12345}, {"reading", "coding"}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      person parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.name == original.name);
      expect(parsed.age == original.age);
      expect(parsed.addr.street == original.addr.street);
      expect(parsed.addr.city == original.addr.city);
      expect(parsed.addr.zip == original.addr.zip);
      expect(parsed.hobbies == original.hobbies);
   };

   "company_write"_test = [] {
      company original{"TechCorp",
                       {{"Alice", 25, {"456 Oak Ave", "Techville", 54321}, {"gaming"}},
                        {"Bob", 35, {"789 Pine Rd", "Codeburg", 98765}, {"hiking", "photography"}}},
                       {{"Engineering", 50}, {"Sales", 30}}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // Verify the structure is written
      expect(yaml.find("TechCorp") != std::string::npos);
      expect(yaml.find("Alice") != std::string::npos);
      expect(yaml.find("Engineering") != std::string::npos);
   };

   "deeply_nested_write"_test = [] {
      std::map<std::string, std::vector<std::map<std::string, int>>> original{
         {"group1", {{{"a", 1}, {"b", 2}}, {{"c", 3}}}}, {"group2", {{{"d", 4}}}}};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);
      // Just verify the write works
      expect(yaml.find("group1") != std::string::npos);
      expect(yaml.find("group2") != std::string::npos);
   };
};

// ============================================================
// Error Handling Tests
// ============================================================

suite yaml_error_tests = [] {
   "invalid_int"_test = [] {
      int value{};
      std::string yaml = "not_a_number";
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "invalid_bool"_test = [] {
      bool value{};
      std::string yaml = "maybe";
      auto ec = glz::read_yaml(value, yaml);
      expect(bool(ec));
   };

   "missing_key_in_struct"_test = [] {
      std::string yaml = R"(x: 1
y: 2.0)";
      // name is missing but has default
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 1);
      expect(obj.name.empty()); // default value
   };

   "type_mismatch_array_to_object"_test = [] {
      simple_struct obj{};
      std::string yaml = "[1, 2, 3]";
      auto ec = glz::read_yaml(obj, yaml);
      expect(bool(ec));
   };

   "type_mismatch_object_to_array"_test = [] {
      std::vector<int> vec{};
      std::string yaml = "key: value";
      auto ec = glz::read_yaml(vec, yaml);
      expect(bool(ec));
   };

   "unclosed_bracket"_test = [] {
      std::vector<int> vec{};
      std::string yaml = "[1, 2, 3";
      auto ec = glz::read_yaml(vec, yaml);
      expect(bool(ec));
   };

   "unclosed_brace"_test = [] {
      std::map<std::string, int> m{};
      std::string yaml = "{a: 1, b: 2";
      auto ec = glz::read_yaml(m, yaml);
      expect(bool(ec));
   };
};

// ============================================================
// Boolean Variations Tests
// ============================================================

suite yaml_boolean_tests = [] {
   "bool_yes"_test = [] {
      bool value{};
      std::string yaml = "yes";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == true);
   };

   "bool_no"_test = [] {
      bool value{true};
      std::string yaml = "no";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == false);
   };

   "bool_on"_test = [] {
      bool value{};
      std::string yaml = "on";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == true);
   };

   "bool_off"_test = [] {
      bool value{true};
      std::string yaml = "off";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == false);
   };

   "bool_True"_test = [] {
      bool value{};
      std::string yaml = "True";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == true);
   };

   "bool_False"_test = [] {
      bool value{true};
      std::string yaml = "False";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == false);
   };

   "bool_TRUE"_test = [] {
      bool value{};
      std::string yaml = "TRUE";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == true);
   };

   "bool_FALSE"_test = [] {
      bool value{true};
      std::string yaml = "FALSE";
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(value == false);
   };
};

// ============================================================
// Indentation and Whitespace Tests
// ============================================================

suite yaml_whitespace_tests = [] {
   "extra_whitespace_in_mapping"_test = [] {
      std::string yaml = R"(x:    42
y:   3.14
name:   test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
      expect(obj.name == "test");
   };

   "leading_whitespace"_test = [] {
      std::string yaml = R"(   x: 1
   y: 2.0
   name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 1);
   };

   "trailing_newlines"_test = [] {
      std::string yaml = "x: 1\ny: 2.0\nname: test\n\n\n";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 1);
   };

   "tabs_in_values"_test = [] {
      std::string yaml = "x:\t42\ny:\t3.14\nname:\ttest";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };
};

// ============================================================
// Document Markers Tests
// ============================================================

suite yaml_document_tests = [] {
   "document_start_marker"_test = [] {
      std::string yaml = R"(---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   "document_start_inline_first_key"_test = [] {
      std::string yaml = R"(--- key: value
next: item)";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(bool(ec));
   };

   "document_end_marker"_test = [] {
      std::string yaml = R"(x: 42
y: 3.14
name: test
...)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   "both_markers"_test = [] {
      std::string yaml = R"(---
x: 42
y: 3.14
name: test
...)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // YAML directive tests
   "yaml_version_directive"_test = [] {
      std::string yaml = R"(%YAML 1.2
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
      expect(obj.name == "test");
   };

   "yaml_tag_directive"_test = [] {
      std::string yaml = R"(%TAG ! tag:example.com,2000:
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   "yaml_multiple_directives"_test = [] {
      std::string yaml = R"(%YAML 1.2
%TAG ! tag:example.com,2000:
%TAG !! tag:yaml.org,2002:
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   "yaml_directive_with_generic"_test = [] {
      std::string yaml = R"(%YAML 1.2
---
name: Alice)";
      glz::generic parsed;
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   "yaml_directive_with_blank_lines"_test = [] {
      std::string yaml = R"(%YAML 1.2

---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // YAML 1.1 should be accepted (per spec)
   "yaml_directive_version_1_1"_test = [] {
      std::string yaml = R"(%YAML 1.1
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // Higher minor versions should be accepted (per spec: process with warning)
   "yaml_directive_version_1_3"_test = [] {
      std::string yaml = R"(%YAML 1.3
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // Duplicate %YAML directive is an error (per spec)
   "yaml_directive_duplicate_error"_test = [] {
      std::string yaml = R"(%YAML 1.2
%YAML 1.2
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(bool(ec)) << "Duplicate %YAML directive should be an error";
   };

   // %YAML with major version > 1 should be rejected (per spec)
   "yaml_directive_major_version_2_error"_test = [] {
      std::string yaml = R"(%YAML 2.0
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(bool(ec)) << "%YAML 2.0 should be rejected";
   };

   // %YAML with major version 3 should be rejected
   "yaml_directive_major_version_3_error"_test = [] {
      std::string yaml = R"(%YAML 3.0
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(bool(ec)) << "%YAML 3.0 should be rejected";
   };

   // Unknown directives should be silently ignored (per spec)
   "yaml_directive_unknown_ignored"_test = [] {
      std::string yaml = R"(%FOOBAR some params here
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // Multiple unknown directives should be ignored
   "yaml_directive_multiple_unknown_ignored"_test = [] {
      std::string yaml = R"(%FOO bar
%BAZ qux
%YAML 1.2
%ANOTHER directive
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };

   // %YAML 1.0 should be accepted (major version 1)
   "yaml_directive_version_1_0"_test = [] {
      std::string yaml = R"(%YAML 1.0
---
x: 42
y: 3.14
name: test)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 42);
   };
};

// ============================================================
// Mixed Flow and Block Style Tests
// ============================================================

suite yaml_mixed_style_tests = [] {
   "flow_in_block_mapping"_test = [] {
      std::string yaml = R"(title: Test
data: {x: 1, y: 2.0, name: inner}
numbers: [1, 2, 3])";
      nested_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.title == "Test");
      expect(obj.data.x == 1);
      expect(obj.numbers.size() == 3);
   };

   "vector_of_maps_write"_test = [] {
      std::vector<std::map<std::string, int>> original{{{"a", 1}, {"b", 2}}, {{"a", 3}, {"b", 4}}};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);
      // Verify write output
      expect(yaml.find("a:") != std::string::npos);
      expect(yaml.find("b:") != std::string::npos);
   };
};

// ============================================================
// Anchor and Alias Tests (if supported)
// ============================================================

// Anchor/Alias Tests (source span replay)

suite yaml_anchor_tests = [] {
   "scalar_anchor_alias_string"_test = [] {
      std::string yaml = R"(anchor: &a hello
alias: *a)";
      std::map<std::string, std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["anchor"] == "hello");
      expect(obj["alias"] == "hello");
   };

   "scalar_anchor_alias_int"_test = [] {
      std::string yaml = R"(anchor: &a 42
alias: *a)";
      std::map<std::string, int> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["anchor"] == 42);
      expect(obj["alias"] == 42);
   };

   "scalar_anchor_alias_double"_test = [] {
      std::string yaml = R"(anchor: &a 3.14
alias: *a)";
      std::map<std::string, double> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["anchor"] == 3.14);
      expect(obj["alias"] == 3.14);
   };

   "scalar_anchor_alias_bool"_test = [] {
      std::string yaml = R"(anchor: &a true
alias: *a)";
      std::map<std::string, bool> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["anchor"] == true);
      expect(obj["alias"] == true);
   };

   "scalar_anchor_alias_generic"_test = [] {
      std::string yaml = R"(first: &anchor Value
second: *anchor)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"({"first":"Value","second":"Value"})") << json;
   };

   "anchor_on_flow_mapping"_test = [] {
      std::string yaml = R"(root: &m {key1: val1, key2: val2}
alias: *m)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"({"root":{"key1":"val1","key2":"val2"},"alias":{"key1":"val1","key2":"val2"}})") << json;
   };

   "anchor_on_flow_sequence"_test = [] {
      std::string yaml = R"(root: &s [1, 2, 3]
alias: *s)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"({"root":[1,2,3],"alias":[1,2,3]})") << json;
   };

   "multiple_anchors"_test = [] {
      std::string yaml = R"(a: &x hello
b: &y world
c: *x
d: *y)";
      std::map<std::string, std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["a"] == "hello");
      expect(obj["b"] == "world");
      expect(obj["c"] == "hello");
      expect(obj["d"] == "world");
   };

   "anchor_override"_test = [] {
      std::string yaml = R"(a: &x first
b: *x
c: &x second
d: *x)";
      std::map<std::string, std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["a"] == "first");
      expect(obj["b"] == "first");
      expect(obj["c"] == "second");
      expect(obj["d"] == "second");
   };

   "anchor_double_quoted"_test = [] {
      std::string yaml = "a: &q \"hello world\"\nb: *q";
      std::map<std::string, std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["a"] == "hello world");
      expect(obj["b"] == "hello world");
   };

   "anchor_single_quoted"_test = [] {
      std::string yaml = "a: &q 'hello world'\nb: *q";
      std::map<std::string, std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["a"] == "hello world");
      expect(obj["b"] == "hello world");
   };

   "undefined_alias_error"_test = [] {
      std::string yaml = "a: *nonexistent";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(bool(ec)) << "Expected error for undefined alias";
   };

   "anchor_on_alias_error"_test = [] {
      std::string yaml = "key1: &a value\nkey2: &b *a";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(bool(ec)) << "Expected error for anchor on alias";
   };

   "nested_anchor_reference"_test = [] {
      std::string yaml = R"(outer:
  inner: &val deep
ref: *val)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"({"outer":{"inner":"deep"},"ref":"deep"})") << json;
   };

   "aliases_in_block_sequence"_test = [] {
      std::string yaml = R"(- &a hello
- &b world
- *a
- *b)";
      std::vector<std::string> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.size() == 4);
      expect(obj[0] == "hello");
      expect(obj[1] == "world");
      expect(obj[2] == "hello");
      expect(obj[3] == "world");
   };

   "anchor_on_sequence_value"_test = [] {
      std::string yaml = R"(&seq
- a)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"(["a"])") << json;
   };

   "document_start_anchor"_test = [] {
      std::string yaml = R"(--- &seq
- a)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"(["a"])") << json;
   };

   "spec_2_10_sammy_sosa"_test = [] {
      std::string yaml = R"(---
hr:
  - Mark McGwire
  - &SS Sammy Sosa
rbi:
  - *SS
  - Ken Griffey)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERROR");
      expect(json == R"({"hr":["Mark McGwire","Sammy Sosa"],"rbi":["Sammy Sosa","Ken Griffey"]})") << json;
   };

   "anchor_on_flow_map_typed"_test = [] {
      std::string yaml = R"(root: &m {x: 1, y: 2}
copy: *m)";
      std::map<std::string, std::map<std::string, int>> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["root"]["x"] == 1);
      expect(obj["root"]["y"] == 2);
      expect(obj["copy"]["x"] == 1);
      expect(obj["copy"]["y"] == 2);
   };

   "anchor_on_flow_seq_typed"_test = [] {
      std::string yaml = R"(root: &s [10, 20, 30]
copy: *s)";
      std::map<std::string, std::vector<int>> obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj["root"].size() == 3);
      expect(obj["root"][0] == 10);
      expect(obj["copy"].size() == 3);
      expect(obj["copy"][2] == 30);
   };

   "anchor_skip_unknown_key"_test = [] {
      // Test that skip_yaml_value handles anchors/aliases when skipping
      std::string yaml = R"(x: 1
y: 1.0
name: &a skipped
extra: *a)";
      simple_struct obj{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.x == 1);
      expect(obj.y == 1.0);
      expect(obj.name == "skipped");
   };

   // https://github.com/stephenberry/glaze/issues/2352
   "skip_unknown_indentless_sequence"_test = [] {
      // Unindented sequence under unknown key
      {
         std::string yaml = R"(---
x: 1
y: 1.0
name: foo
c:
- baz
...)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::yaml::yaml_opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 1);
         expect(data.y == 1.0);
         expect(data.name == "foo");
      }

      // Multiple items in unknown indentless sequence
      {
         std::string yaml = R"(x: 1
c:
- baz1
- baz2
y: 2.0
name: bar)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::yaml::yaml_opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 1);
         expect(data.y == 2.0);
         expect(data.name == "bar");
      }

      // Unknown key with indented (normal) block sequence on next line
      {
         std::string yaml = R"(x: 1
c:
  - baz1
  - baz2
y: 2.0
name: bar)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::yaml::yaml_opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 1);
         expect(data.y == 2.0);
         expect(data.name == "bar");
      }
   };

   // https://github.com/stephenberry/glaze/issues/2356
   "known_field_indentless_sequence"_test = [] {
      // Unindented sequence under a known key
      {
         std::string yaml = R"(---
title: foo
numbers:
- 1
- 2
- 3
...)";
         nested_struct data{};
         auto ec = glz::read_yaml(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.title == "foo");
         expect(data.numbers.size() == 3);
         expect(data.numbers[0] == 1);
         expect(data.numbers[1] == 2);
         expect(data.numbers[2] == 3);
      }

      // Known key indentless sequence followed by another key
      {
         std::string yaml = R"(title: hello
numbers:
- 10
- 20
- 30
title: world)";
         nested_struct data{};
         auto ec = glz::read_yaml(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.title == "world");
         expect(data.numbers.size() == 3);
         expect(data.numbers[0] == 10);
         expect(data.numbers[1] == 20);
         expect(data.numbers[2] == 30);
      }
   };

   "skip_unknown_nested_block_mapping"_test = [] {
      // When an unknown key has a block mapping value on subsequent lines,
      // all entries of that nested mapping must be skipped.
      // Bug: skip_yaml_value only skipped the first key-value pair,
      // causing remaining entries to leak into the parent struct parser.
      {
         std::string yaml = R"(x: 42
unknown_key:
  name: leaked
  y: 999.0
)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 42);
         expect(data.y == 0.0) << "y should remain default, not be overwritten by nested mapping";
         expect(data.name == "") << "name should remain default, not be overwritten by nested mapping";
      }

      // Unknown key with deeper nesting
      {
         std::string yaml = R"(x: 1
unknown:
  sub1:
    deep: value
  sub2: val2
y: 3.14
name: hello)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 1);
         expect(data.y == 3.14);
         expect(data.name == "hello");
      }

      // Multiple unknown keys with block mapping values
      {
         std::string yaml = R"(unknown1:
  a: 1
  b: 2
x: 10
unknown2:
  name: wrong
  y: 777.0
y: 2.5
name: correct)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 10);
         expect(data.y == 2.5);
         expect(data.name == "correct");
      }

      // Comments within a nested block mapping must be skipped
      {
         std::string yaml = R"(x: 42
unknown:
  key1: val1
  # a comment
  key2: val2
y: 3.14
name: hello)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 42);
         expect(data.y == 3.14);
         expect(data.name == "hello");
      }
   };

   "skip_unknown_multiline_plain_scalar"_test = [] {
      // When an unknown key has a multi-line plain scalar value,
      // continuation lines at deeper indentation must be skipped.
      // Bug: skip_plain_scalar only reads to the end of the first line,
      // so continuation lines are misinterpreted as struct keys, causing
      // a syntax error.
      {
         std::string yaml = R"(x: 42
unknown: this value
  continues here
y: 3.14
name: hello)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 42);
         expect(data.y == 3.14);
         expect(data.name == "hello");
      }

      // Multi-line plain scalar with multiple continuation lines
      {
         std::string yaml = R"(unknown: line one
  line two
  line three
x: 99
y: 1.5
name: works)";
         simple_struct data{};
         auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 99);
         expect(data.y == 1.5);
         expect(data.name == "works");
      }
   };

   "flow_mapping_newline_before_comma"_test = [] {
      // In YAML flow context, newlines are treated as whitespace.
      // A newline between a value and the comma separator should be valid.
      // Bug: parse_flow_mapping used skip_inline_ws (spaces/tabs only) instead
      // of skip_flow_ws_and_newlines after values, rejecting valid YAML.
      {
         // Newline before comma
         std::string yaml = "{x: 1\n, y: 2.5\n, name: hello}";
         simple_struct data{};
         auto ec = glz::read_yaml(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 1);
         expect(data.y == 2.5);
         expect(data.name == "hello");
      }

      // Newline after value, comma on next line (indented)
      {
         std::string yaml = "{x: 42\n  , y: 3.14}";
         simple_struct data{};
         auto ec = glz::read_yaml(data, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(data.x == 42);
         expect(data.y == 3.14);
      }
   };

   "anchor_empty_node"_test = [] {
      std::string yaml = R"(a: &anchor
b: *anchor)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"a":null,"b":null})") << json;
   };

   "alias_as_mapping_key"_test = [] {
      std::string yaml = R"(a: &ref hello
*ref : world)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"a":"hello","hello":"world"})") << json;
   };

   "anchor_on_key_with_alias"_test = [] {
      std::string yaml = R"(&a a: &b b
*b : *a)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"a":"b","b":"a"})") << json;
   };

   "anchor_on_tagged_key"_test = [] {
      std::string yaml = R"(&a5 !!str key5: value4
other: *a5)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"key5":"value4","other":"key5"})") << json;
   };

   "tag_then_anchor_on_key"_test = [] {
      std::string yaml = R"(!!str &a key: value
other: *a)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"key":"value","other":"key"})") << json;
   };

   "anchor_on_quoted_key_with_space_before_colon"_test = [] {
      std::string yaml = R"(&a 'key' : value
other: *a)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"({"key":"value","other":"key"})") << json;
   };

   "anchor_block_mapping_replay"_test = [] {
      std::string yaml = R"(bill-to: &id001
    given: Chris
    family: Dumars
ship-to: *id001)";
      glz::generic parsed{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      std::string expected =
         R"({"bill-to":{"given":"Chris","family":"Dumars"},"ship-to":{"given":"Chris","family":"Dumars"}})";
      expect(json == expected) << json;
   };
};

// ============================================================
// Tab Handling Tests
// ============================================================

suite yaml_tab_tests = [] {
   "tab_in_literal_block_scalar"_test = [] {
      std::string yaml = "|\n literal\n \ttext\n";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("ERR");
      expect(json == R"("literal\n\ttext\n")") << json;
   };

   "tab_in_block_scalar_mapping"_test = [] {
      std::string yaml = "block:\t|\n  void main() {\n  \tprintf(\"hello\");\n  }\n";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
   };

   "tab_as_indentation_error"_test = [] {
      std::string yaml = "a:\n\tb: value\n";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(bool(ec)) << "Tab as indentation should error";
   };

   "tab_after_spaces_in_mapping_error"_test = [] {
      std::string yaml = "a:\n  \tb: value\n";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(bool(ec)) << "Tab after spaces in mapping indentation should error";
   };
};

// ============================================================
// Multiline String Continuation Tests
// ============================================================

suite yaml_multiline_tests = [] {
   "literal_block_strip"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
name: |-
  line1
  line2
  line3)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Strip indicator removes trailing newlines
   };

   "literal_block_keep"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
name: |+
  line1
  line2
  line3

)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Keep indicator preserves trailing newlines
   };

   "folded_block_basic"_test = [] {
      std::string yaml = R"(x: 1
y: 1.0
name: >
  this is a long
  string that should
  be folded)";
      simple_struct obj{};
      auto ec = glz::read_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Folded replaces single newlines with spaces
   };
};

// ============================================================
// Char Type Tests (write only - char reading not supported)
// ============================================================

suite yaml_char_tests = [] {
   "char_write"_test = [] {
      char original = 'A';
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // char reading not supported, just verify write works
      expect(yaml.find("A") != std::string::npos);
   };

   "unsigned_char_roundtrip"_test = [] {
      unsigned char original = 255;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      // unsigned char is a num_t, should be readable
      unsigned char parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

// ============================================================
// File I/O Tests
// ============================================================

struct file_struct
{
   int x{};
   double y{};
   std::string name{};
};

template <>
struct glz::meta<file_struct>
{
   using T = file_struct;
   static constexpr auto value = object("x", &T::x, "y", &T::y, "name", &T::name);
};

struct k8s_metadata
{
   std::string name{};
   std::map<std::string, std::string> labels{};
};

struct k8s_label_selector
{
   std::map<std::string, std::string> matchLabels{};
};

struct k8s_container_port
{
   int containerPort{};
};

struct k8s_container
{
   std::string name{};
   std::string image{};
   std::vector<k8s_container_port> ports{};
};

struct k8s_pod_spec
{
   std::vector<k8s_container> containers{};
};

struct k8s_pod_template_metadata
{
   std::map<std::string, std::string> labels{};
};

struct k8s_pod_template
{
   k8s_pod_template_metadata metadata{};
   k8s_pod_spec spec{};
};

struct k8s_deployment_spec
{
   int replicas{};
   k8s_label_selector selector{};
   k8s_pod_template template_{};
};

template <>
struct glz::meta<k8s_deployment_spec>
{
   static constexpr std::string_view rename_key(const std::string_view key)
   {
      if (key == "template_") {
         return "template";
      }
      return key;
   }
};

struct k8s_deployment
{
   std::string apiVersion{};
   std::string kind{};
   k8s_metadata metadata{};
   k8s_deployment_spec spec{};
};

struct k8s_service_port
{
   std::string name{};
   std::string protocol{};
   int port{};
   int targetPort{};
};

struct k8s_service_spec
{
   std::map<std::string, std::string> selector{};
   std::vector<k8s_service_port> ports{};
};

struct k8s_service
{
   std::string apiVersion{};
   std::string kind{};
   k8s_metadata metadata{};
   k8s_service_spec spec{};
};

template <class T, class Check>
static void roundtrip_yaml(const std::string& yaml, Check&& check)
{
   T parsed{};
   auto rec = glz::read_yaml(parsed, yaml);
   expect(!rec) << glz::format_error(rec, yaml);
   check(parsed);

   std::string output;
   auto wec = glz::write_yaml(parsed, output);
   expect(!wec);

   T reparsed{};
   auto rec2 = glz::read_yaml(reparsed, output);
   expect(!rec2) << glz::format_error(rec2, output);
   check(reparsed);
}

struct advanced_flags
{
   bool enabled{};
   bool archived{};
};

struct advanced_counts
{
   int retries{};
   int timeout_ms{};
   double ratio{};
};

struct advanced_flow
{
   std::vector<int> values{};
   std::map<std::string, std::string> mapping{};
};

struct advanced_nested
{
   std::string name{};
   std::vector<int> ids{};
   std::map<std::string, std::string> labels{};
};

struct advanced_doc
{
   std::string title{};
   std::string description{};
   std::string literal{};
   std::string multiline_plain{};
   std::string quoted{};
   advanced_flags flags{};
   advanced_counts counts{};
   std::vector<std::string> list{};
   advanced_flow flow{};
   advanced_nested nested{};
   std::optional<std::string> note{};
};

suite yaml_file_io_tests = [] {
   "write_file_yaml"_test = [] {
      file_struct obj{42, 3.14, "test_file"};
      std::string filename = "./test_output.yaml";

      auto ec = glz::write_file_yaml(obj, filename);
      expect(!ec);

      // Read it back
      file_struct parsed{};
      auto rec = glz::read_file_yaml(parsed, filename);
      expect(!rec);
      expect(parsed.x == obj.x);
      expect(std::abs(parsed.y - obj.y) < 0.001);
      expect(parsed.name == obj.name);

      // Clean up
      std::remove(filename.c_str());
   };

   "read_file_yaml_not_found"_test = [] {
      file_struct obj{};
      auto ec = glz::read_file_yaml(obj, "./nonexistent_file.yaml");
      expect(bool(ec)); // Should error
   };
};

// ============================================================
// External YAML String Tests
// ============================================================

suite yaml_external_yaml_string_tests = [] {
   // Sources:
   // - https://k8s-examples.container-solutions.com/examples/Deployment/simple-deployment.yaml
   // - https://k8s-examples.container-solutions.com/examples/Service/simple.yaml
   "external_service_generic_roundtrip"_test = [] {
      const std::string yaml = R"(---
apiVersion: v1
kind: Service
metadata:
  name: simple-service
spec:
  selector:
    app: App1
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
)";
      auto check = [](const glz::generic& parsed) {
         auto& root = std::get<glz::generic::object_t>(parsed.data);
         expect(std::get<std::string>(root.at("kind").data) == "Service");

         auto& spec = std::get<glz::generic::object_t>(root.at("spec").data);
         auto& selector = std::get<glz::generic::object_t>(spec.at("selector").data);
         expect(std::get<std::string>(selector.at("app").data) == "App1");

         auto& ports = std::get<glz::generic::array_t>(spec.at("ports").data);
         expect(ports.size() == 1);
         auto& port0 = std::get<glz::generic::object_t>(ports[0].data);
         expect(std::get<std::string>(port0.at("name").data) == "http");
         expect(std::get<double>(port0.at("port").data) == 80.0);
      };

      roundtrip_yaml<glz::generic>(yaml, check);
   };

   "external_service_struct_roundtrip"_test = [] {
      const std::string yaml = R"(---
apiVersion: v1
kind: Service
metadata:
  name: simple-service
spec:
  selector:
    app: App1
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
)";
      auto check = [](const k8s_service& svc) {
         expect(svc.apiVersion == "v1");
         expect(svc.kind == "Service");
         expect(svc.metadata.name == "simple-service");
         expect(svc.spec.selector.at("app") == "App1");
         expect(svc.spec.ports.size() == 1);
         expect(svc.spec.ports[0].protocol == "TCP");
         expect(svc.spec.ports[0].port == 80);
         expect(svc.spec.ports[0].targetPort == 9376);
      };

      roundtrip_yaml<k8s_service>(yaml, check);
   };

   "external_deployment_generic_roundtrip"_test = [] {
      const std::string yaml = R"(---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
)";
      auto check = [](const glz::generic& parsed) {
         auto& root = std::get<glz::generic::object_t>(parsed.data);
         expect(std::get<std::string>(root.at("kind").data) == "Deployment");

         auto& spec = std::get<glz::generic::object_t>(root.at("spec").data);
         expect(std::get<double>(spec.at("replicas").data) == 3.0);

         auto& template_obj = std::get<glz::generic::object_t>(spec.at("template").data);
         auto& pod_spec = std::get<glz::generic::object_t>(template_obj.at("spec").data);
         auto& containers = std::get<glz::generic::array_t>(pod_spec.at("containers").data);
         expect(containers.size() == 1);

         auto& container0 = std::get<glz::generic::object_t>(containers[0].data);
         expect(std::get<std::string>(container0.at("name").data) == "nginx");
         expect(std::get<std::string>(container0.at("image").data) == "nginx:1.7.9");
      };

      roundtrip_yaml<glz::generic>(yaml, check);
   };

   "external_deployment_struct_roundtrip"_test = [] {
      const std::string yaml = R"(---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
            - containerPort: 80
)";
      auto check = [](const k8s_deployment& dep) {
         expect(dep.apiVersion == "apps/v1");
         expect(dep.kind == "Deployment");
         expect(dep.metadata.name == "nginx-deployment");
         expect(dep.spec.replicas == 3);
         expect(dep.spec.template_.spec.containers.size() == 1);
         expect(dep.spec.template_.spec.containers[0].image == "nginx:1.7.9");
         expect(dep.spec.template_.spec.containers[0].ports.size() == 1);
         expect(dep.spec.template_.spec.containers[0].ports[0].containerPort == 80);
      };

      roundtrip_yaml<k8s_deployment>(yaml, check);
   };

   "reflectable_flow_mapping_empty_sequence_roundtrip"_test = [] {
      const std::string yaml = R"({
  "servers":
  [

  ]
})";
      auto check = [](const reflectable_config& cfg) { expect(cfg.servers.empty()); };
      roundtrip_yaml<reflectable_config>(yaml, check);
   };

   "generic_flow_mapping_empty_sequence_output"_test = [] {
      const std::string yaml = R"({
  "servers":
  [

  ]
})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);
      expect(output.find("servers") != std::string::npos);
      expect(output.find("[]") != std::string::npos);

      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);
      auto& root = std::get<glz::generic::object_t>(reparsed.data);
      expect(root.contains("servers"));
      auto& servers = std::get<glz::generic::array_t>(root.at("servers").data);
      expect(servers.empty());
   };

   "external_advanced_generic_roundtrip"_test = [] {
      const std::string yaml = R"(---
title: "Advanced YAML"
description: >
  This is a folded
  description with a blank line.

  Second paragraph.
literal: |-
  line one
    line two
  line three
multiline_plain:
  meta.statement.conditional.case.python
  keyword.control.conditional.case.python
quoted: "beta: colon"
flags:
  enabled: true
  archived: false
counts:
  retries: 3
  timeout_ms: 1500
  ratio: 0.75
list:
  - alpha
  - "beta: colon"
  - 'gamma # not comment'
flow:
  values: [1, 2, 3]
  mapping: {a: one, b: two, c: three}
nested:
  name: sample
  ids: [10, 20, 30]
  labels:
    env: dev
    tier: backend
note: null
)";
      auto check = [](const glz::generic& parsed) {
         auto& root = std::get<glz::generic::object_t>(parsed.data);
         expect(std::get<std::string>(root.at("title").data) == "Advanced YAML");

         auto& description = std::get<std::string>(root.at("description").data);
         expect(description.find("This is a folded description") != std::string::npos);
         expect(description.find("Second paragraph.") != std::string::npos);

         expect(std::get<std::string>(root.at("literal").data) == "line one\n  line two\nline three");
         expect(std::get<std::string>(root.at("multiline_plain").data) ==
                "meta.statement.conditional.case.python keyword.control.conditional.case.python");
         expect(std::get<std::string>(root.at("quoted").data) == "beta: colon");

         auto& flags = std::get<glz::generic::object_t>(root.at("flags").data);
         expect(std::get<bool>(flags.at("enabled").data));
         expect(!std::get<bool>(flags.at("archived").data));

         auto& counts = std::get<glz::generic::object_t>(root.at("counts").data);
         expect(std::get<double>(counts.at("retries").data) == 3.0);
         expect(std::get<double>(counts.at("timeout_ms").data) == 1500.0);
         expect(std::abs(std::get<double>(counts.at("ratio").data) - 0.75) < 0.0001);

         auto& list = std::get<glz::generic::array_t>(root.at("list").data);
         expect(list.size() == 3);
         expect(std::get<std::string>(list[0].data) == "alpha");
         expect(std::get<std::string>(list[1].data) == "beta: colon");
         expect(std::get<std::string>(list[2].data) == "gamma # not comment");

         auto& flow = std::get<glz::generic::object_t>(root.at("flow").data);
         auto& values = std::get<glz::generic::array_t>(flow.at("values").data);
         expect(values.size() == 3);
         expect(std::get<double>(values[0].data) == 1.0);
         expect(std::get<double>(values[2].data) == 3.0);
         auto& mapping = std::get<glz::generic::object_t>(flow.at("mapping").data);
         expect(std::get<std::string>(mapping.at("b").data) == "two");

         auto& nested = std::get<glz::generic::object_t>(root.at("nested").data);
         expect(std::get<std::string>(nested.at("name").data) == "sample");
         auto& ids = std::get<glz::generic::array_t>(nested.at("ids").data);
         expect(ids.size() == 3);
         auto& labels = std::get<glz::generic::object_t>(nested.at("labels").data);
         expect(std::get<std::string>(labels.at("env").data) == "dev");
         expect(std::get<std::string>(labels.at("tier").data) == "backend");

         auto& note = root.at("note").data;
         expect(std::holds_alternative<std::nullptr_t>(note));
      };

      roundtrip_yaml<glz::generic>(yaml, check);
   };

   "external_advanced_struct_roundtrip"_test = [] {
      const std::string yaml = R"(---
title: "Advanced YAML"
description: >
  This is a folded
  description with a blank line.

  Second paragraph.
literal: |-
  line one
    line two
  line three
multiline_plain:
  meta.statement.conditional.case.python
  keyword.control.conditional.case.python
quoted: "beta: colon"
flags:
  enabled: true
  archived: false
counts:
  retries: 3
  timeout_ms: 1500
  ratio: 0.75
list:
  - alpha
  - "beta: colon"
  - 'gamma # not comment'
flow:
  values: [1, 2, 3]
  mapping: {a: one, b: two, c: three}
nested:
  name: sample
  ids: [10, 20, 30]
  labels:
    env: dev
    tier: backend
note: null
)";
      auto check = [](const advanced_doc& doc) {
         expect(doc.title == "Advanced YAML");
         expect(doc.description.find("This is a folded description") != std::string::npos);
         expect(doc.description.find("Second paragraph.") != std::string::npos);
         expect(doc.literal == "line one\n  line two\nline three");
         expect(doc.multiline_plain ==
                "meta.statement.conditional.case.python keyword.control.conditional.case.python");
         expect(doc.quoted == "beta: colon");

         expect(doc.flags.enabled);
         expect(!doc.flags.archived);
         expect(doc.counts.retries == 3);
         expect(doc.counts.timeout_ms == 1500);
         expect(std::abs(doc.counts.ratio - 0.75) < 0.0001);

         expect(doc.list.size() == 3);
         expect(doc.list[2] == "gamma # not comment");

         expect(doc.flow.values.size() == 3);
         expect(doc.flow.values[0] == 1);
         expect(doc.flow.mapping.at("b") == "two");

         expect(doc.nested.name == "sample");
         expect(doc.nested.ids.size() == 3);
         expect(doc.nested.labels.at("env") == "dev");
         expect(doc.nested.labels.at("tier") == "backend");

         expect(!doc.note.has_value());
      };

      roundtrip_yaml<advanced_doc>(yaml, check);
   };
};

suite yaml_large_writer_document_tests = [] {
   "write_large_generic_document_with_many_features"_test = [] {
      glz::generic doc{};
      doc["apiVersion"] = "v2";
      doc["kind"] = "ApplicationBundle";
      doc["description"] = "Large generated writer test document\nWith nested maps and sequences";
      doc["runbook"] = "step one\nstep two\n";
      doc["audit_log"] = "entry-a\nentry-b\n\n\n";

      doc["metadata"]["name"] = "platform-core";
      doc["metadata"]["labels"]["app"] = "platform";
      doc["metadata"]["labels"]["tier"] = "backend";
      doc["metadata"]["annotations"]["owner"] = "platform-team";
      doc["metadata"]["annotations"]["source"] = "generated/test";

      doc["quoted_examples"]["bool_like"] = "true";
      doc["quoted_examples"]["num_like"] = "123";
      doc["quoted_examples"]["contains_colon"] = "alpha: beta";
      doc["quoted_examples"]["contains_hash"] = "value # literal";

      doc["limits"]["max_connections"] = 5000;
      doc["limits"]["burst"] = 250;
      doc["flags"]["enabled"] = true;
      doc["flags"]["maintenance_mode"] = false;
      doc["note"] = nullptr;

      doc["deployments"].data = glz::generic::array_t{};
      auto& deployments = std::get<glz::generic::array_t>(doc["deployments"].data);
      for (int i = 0; i < 16; ++i) {
         glz::generic service{};
         service["name"] = "svc-" + std::to_string(i);
         service["image"] = "registry.example.com/app:" + std::to_string(100 + i);
         service["replicas"] = (i % 4) + 1;
         service["enabled"] = (i % 2 == 0);
         service["startup_script"] = "echo start\n./run --port=8080";
         service["notes"] = "release\nnotes\n";
         service["ports"].data = glz::generic::array_t{};
         auto& ports = std::get<glz::generic::array_t>(service["ports"].data);
         for (int p = 0; p < 3; ++p) {
            glz::generic port{};
            port["name"] = "p" + std::to_string(p);
            port["port"] = 8000 + p;
            port["protocol"] = "TCP";
            ports.emplace_back(std::move(port));
         }
         deployments.emplace_back(std::move(service));
      }

      std::string yaml{};
      auto wec = glz::write_yaml(doc, yaml);
      expect(!wec);
      expect(yaml.size() > 4000);
      expect(yaml.find("description: |-") != std::string::npos);
      expect(yaml.find("runbook: |") != std::string::npos);
      expect(yaml.find("audit_log: |+") != std::string::npos);
      expect(yaml.find("'true'") != std::string::npos);
      expect(yaml.find("'123'") != std::string::npos);
      expect(yaml.find("'alpha: beta'") != std::string::npos);
      expect(yaml.find("'value # literal'") != std::string::npos);

      glz::generic parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(root.at("kind").data) == "ApplicationBundle");
      expect(std::get<std::string>(root.at("description").data) ==
             "Large generated writer test document\nWith nested maps and sequences");
      expect(std::get<std::string>(root.at("runbook").data) == "step one\nstep two\n");
      expect(std::get<std::string>(root.at("audit_log").data) == "entry-a\nentry-b\n\n\n\n");
      expect(std::holds_alternative<std::nullptr_t>(root.at("note").data));

      auto& parsed_deployments = std::get<glz::generic::array_t>(root.at("deployments").data);
      expect(parsed_deployments.size() == 16);
      auto& d7 = std::get<glz::generic::object_t>(parsed_deployments[7].data);
      expect(std::get<std::string>(d7.at("name").data) == "svc-7");
      expect(std::get<double>(d7.at("replicas").data) == 4.0);
      expect(!std::get<bool>(d7.at("enabled").data));
      expect(std::get<std::string>(d7.at("startup_script").data) == "echo start\n./run --port=8080");
      expect(std::get<std::string>(d7.at("notes").data) == "release\nnotes\n");

      auto& q = std::get<glz::generic::object_t>(root.at("quoted_examples").data);
      expect(std::get<std::string>(q.at("bool_like").data) == "true");
      expect(std::get<std::string>(q.at("num_like").data) == "123");
   };

   "write_large_struct_document_with_many_features"_test = [] {
      advanced_doc original{};
      original.title = "Writer Stress Document";
      original.description = "Structured writer test document\nWith many nested features";
      original.literal = "line one\n  line two\nline three\n\n\n";
      original.multiline_plain = "alpha: beta # comment-like";
      original.quoted = "beta: colon # hash";
      original.flags = {true, false};
      original.counts = {7, 4500, 0.875};
      original.flow.values = {1, 2, 3, 4, 5, 6};
      original.flow.mapping = {{"a", "one"}, {"b", "two"}, {"c", "three"}, {"d", "four"}};
      original.nested.name = "writer-nested";
      original.nested.labels = {{"env", "prod"}, {"tier", "backend"}, {"owner", "platform"}};
      for (int i = 0; i < 64; ++i) {
         original.list.push_back("item-" + std::to_string(i));
         original.nested.ids.push_back(1000 + i);
      }
      original.list.push_back("true");
      original.list.push_back("123");
      original.list.push_back("contains: colon");
      original.list.push_back("contains # hash");
      original.note = "operator note line 1\noperator note line 2\n";

      std::string yaml{};
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.size() > 1800);
      expect(yaml.find("description: |-") != std::string::npos);
      expect(yaml.find("literal: |+") != std::string::npos);
      expect(yaml.find("note: |") != std::string::npos);
      expect(yaml.find("'true'") != std::string::npos);
      expect(yaml.find("'123'") != std::string::npos);
      expect(yaml.find("'contains: colon'") != std::string::npos);
      expect(yaml.find("'contains # hash'") != std::string::npos);

      advanced_doc parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(parsed.title == original.title);
      expect(parsed.description == original.description);
      expect(parsed.literal == (original.literal + "\n"));
      expect(parsed.multiline_plain == original.multiline_plain);
      expect(parsed.quoted == original.quoted);
      expect(parsed.flags.enabled == original.flags.enabled);
      expect(parsed.flags.archived == original.flags.archived);
      expect(parsed.counts.retries == original.counts.retries);
      expect(parsed.counts.timeout_ms == original.counts.timeout_ms);
      expect(std::abs(parsed.counts.ratio - original.counts.ratio) < 0.0001);
      expect(parsed.list.size() == original.list.size());
      expect(parsed.list[65] == "123");
      expect(parsed.flow.mapping.at("d") == "four");
      expect(parsed.nested.ids.size() == original.nested.ids.size());
      expect(parsed.nested.labels.at("owner") == "platform");
      expect(parsed.note.has_value());
      expect(parsed.note.value() == original.note.value());
   };
};

// ============================================================
// Tuple and Pair Tests (Additional)
// ============================================================

suite yaml_tuple_pair_tests = [] {
   "tuple_mixed_types"_test = [] {
      auto original = std::make_tuple(42, 3.14, std::string("hello"));
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      decltype(original) parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::get<0>(parsed) == std::get<0>(original));
      expect(std::abs(std::get<1>(parsed) - std::get<1>(original)) < 0.001);
      expect(std::get<2>(parsed) == std::get<2>(original));
   };

   "tuple_nested"_test = [] {
      auto original = std::make_tuple(1, std::make_tuple(2, 3), 4);
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      decltype(original) parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::get<0>(parsed) == 1);
      expect(std::get<0>(std::get<1>(parsed)) == 2);
      expect(std::get<1>(std::get<1>(parsed)) == 3);
      expect(std::get<2>(parsed) == 4);
   };

   "pair_roundtrip"_test = [] {
      auto original = std::make_pair(std::string("key"), 123);
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      decltype(original) parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.first == original.first);
      expect(parsed.second == original.second);
   };

   "pair_int_int"_test = [] {
      auto original = std::make_pair(1, 2);
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      decltype(original) parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "vector_of_pairs"_test = [] {
      std::vector<std::pair<std::string, int>> original{{"a", 1}, {"b", 2}, {"c", 3}};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      decltype(original) parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

// ============================================================
// Enum Tests (Additional)
// ============================================================

enum class Priority { Low, Medium, High };

template <>
struct glz::meta<Priority>
{
   using enum Priority;
   static constexpr auto value = enumerate(Low, Medium, High);
};

struct priority_container
{
   Priority priority{Priority::Low};
   std::vector<Priority> priorities{};
};

template <>
struct glz::meta<priority_container>
{
   using T = priority_container;
   static constexpr auto value = object("priority", &T::priority, "priorities", &T::priorities);
};

suite yaml_enum_additional_tests = [] {
   "enum_write_read"_test = [] {
      Priority original = Priority::Medium;
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml.find("Medium") != std::string::npos);

      Priority parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "enum_all_values"_test = [] {
      for (auto p : {Priority::Low, Priority::Medium, Priority::High}) {
         std::string yaml;
         auto wec = glz::write_yaml(p, yaml);
         expect(!wec);

         Priority parsed{};
         auto rec = glz::read_yaml(parsed, yaml);
         expect(!rec) << glz::format_error(rec, yaml);
         expect(parsed == p);
      }
   };

   "array_of_enums"_test = [] {
      std::array<Priority, 3> original{Priority::Medium, Priority::Low, Priority::High};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::array<Priority, 3> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "vector_of_enums"_test = [] {
      std::vector<Priority> original{Priority::Low, Priority::Medium, Priority::High, Priority::Low};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::vector<Priority> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "enum_in_struct"_test = [] {
      priority_container original{Priority::High, {Priority::Low, Priority::Medium}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      priority_container parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.priority == original.priority);
      expect(parsed.priorities == original.priorities);
   };

   "invalid_enum"_test = [] {
      Priority parsed{Priority::Low};
      std::string yaml = "InvalidPriority";
      auto ec = glz::read_yaml(parsed, yaml);
      expect(bool(ec)); // Should error
      expect(parsed == Priority::Low); // Should remain unchanged
   };
};

// ============================================================
// Skip Null Members Tests
// ============================================================

struct nullable_struct
{
   std::optional<int> opt{};
   std::shared_ptr<std::string> ptr{};
   int value{42};
};

template <>
struct glz::meta<nullable_struct>
{
   using T = nullable_struct;
   static constexpr auto value = object("opt", &T::opt, "ptr", &T::ptr, "value", &T::value);
};

suite yaml_skip_null_tests = [] {
   "skip_null_members_true"_test = [] {
      nullable_struct obj{};
      std::string yaml;
      // Default is skip_null_members = true
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);
      // Null members should be omitted
      expect(yaml.find("opt") == std::string::npos);
      expect(yaml.find("ptr") == std::string::npos);
      expect(yaml.find("value") != std::string::npos);
      expect(yaml.find("42") != std::string::npos);
   };

   "skip_null_members_false"_test = [] {
      nullable_struct obj{};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.skip_null_members = false};
      auto wec = glz::write<opts>(obj, yaml);
      expect(!wec);
      // Null members should be present
      expect(yaml.find("opt") != std::string::npos);
      expect(yaml.find("ptr") != std::string::npos);
      expect(yaml.find("null") != std::string::npos);
   };

   "skip_null_with_values"_test = [] {
      nullable_struct obj{};
      obj.opt = 99;
      obj.ptr = std::make_shared<std::string>("hello");

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);
      // All members should be present when they have values
      expect(yaml.find("opt") != std::string::npos);
      expect(yaml.find("99") != std::string::npos);
      expect(yaml.find("ptr") != std::string::npos);
      expect(yaml.find("hello") != std::string::npos);
   };
};

// ============================================================
// Reflection and glz::meta Tests
// ============================================================

struct custom_keys_struct
{
   int internal_x{};
   std::string internal_name{};
};

template <>
struct glz::meta<custom_keys_struct>
{
   using T = custom_keys_struct;
   static constexpr auto value = object("x", &T::internal_x, "name", &T::internal_name);
};

struct nested_meta_struct
{
   custom_keys_struct inner{};
   int outer_value{};
};

template <>
struct glz::meta<nested_meta_struct>
{
   using T = nested_meta_struct;
   static constexpr auto value = object("inner", &T::inner, "outer", &T::outer_value);
};

suite yaml_meta_tests = [] {
   "custom_keys"_test = [] {
      custom_keys_struct original{42, "test"};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      // Should use "x" not "internal_x"
      expect(yaml.find("x:") != std::string::npos);
      expect(yaml.find("name:") != std::string::npos);
      expect(yaml.find("internal_x") == std::string::npos);

      custom_keys_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.internal_x == original.internal_x);
      expect(parsed.internal_name == original.internal_name);
   };

   "nested_meta"_test = [] {
      nested_meta_struct original{{10, "inner"}, 20};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      nested_meta_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.inner.internal_x == original.inner.internal_x);
      expect(parsed.inner.internal_name == original.inner.internal_name);
      expect(parsed.outer_value == original.outer_value);
   };
};

// ============================================================
// Edge Cases and Special Values
// ============================================================

suite yaml_edge_cases = [] {
   "empty_string"_test = [] {
      std::string original = "";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::string parsed = "not_empty";
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.empty());
   };

   "string_with_special_chars"_test = [] {
      std::string original = "line1\nline2\ttab\"quote";
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "unicode_string"_test = [] {
      std::string original = "Hello \xe4\xb8\x96\xe7\x95\x8c \xf0\x9f\x8c\x8d"; // "Hello 世界 🌍" in UTF-8
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "very_long_string"_test = [] {
      std::string original(10000, 'x');
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::string parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "deeply_nested_struct"_test = [] {
      nested_struct level1{};
      level1.title = "level1";
      level1.data.x = 1;
      level1.numbers = {1, 2, 3};

      std::string yaml;
      auto wec = glz::write_yaml(level1, yaml);
      expect(!wec);

      nested_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.title == level1.title);
      expect(parsed.data.x == level1.data.x);
      expect(parsed.numbers == level1.numbers);
   };

   "map_with_empty_values"_test = [] {
      std::map<std::string, std::string> original{{"a", ""}, {"b", "value"}, {"c", ""}};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::map<std::string, std::string> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };

   "single_element_vector"_test = [] {
      std::vector<int> original{42};
      std::string yaml;
      constexpr glz::yaml::yaml_opts opts{.flow_style = true};
      auto wec = glz::write<opts>(original, yaml);
      expect(!wec);

      std::vector<int> parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed == original);
   };
};

// ============================================================
// glz::generic YAML Parsing Tests
// ============================================================

suite yaml_generic_parsing_tests = [] {
   // Output formatting - verify proper newlines between entries
   "generic_flow_mapping_output_formatting"_test = [] {
      std::string yaml = R"({"name": "Alice", "age": 30})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      // Write back and verify proper formatting
      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      // Output should have proper newlines - each key:value on separate lines
      // Should NOT have entries running together like "30name:"
      expect(output.find("30name") == std::string::npos) << "Values should be separated by newlines";
      expect(output.find("Aliceage") == std::string::npos) << "Values should be separated by newlines";

      // Verify it can be parsed back
      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);
   };

   "generic_nested_map_output_formatting"_test = [] {
      std::string yaml = R"({"outer": {"inner": 42}, "other": "value"})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      // Verify roundtrip
      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);
      expect(std::holds_alternative<glz::generic::object_t>(reparsed.data));
   };

   // Multi-line flow-style parsing
   "generic_multiline_flow_mapping"_test = [] {
      std::string yaml = R"({"name": "Alice",
"age": 30})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 2u);
      expect(std::holds_alternative<std::string>(obj.at("name").data));
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
      expect(std::holds_alternative<double>(obj.at("age").data));
      expect(std::get<double>(obj.at("age").data) == 30.0);
   };

   "generic_multiline_flow_mapping_multiple_lines"_test = [] {
      std::string yaml = R"({
"name": "Bob",
"age": 25,
"city": "NYC"
})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 3u);
      expect(std::get<std::string>(obj.at("name").data) == "Bob");
      expect(std::get<double>(obj.at("age").data) == 25.0);
      expect(std::get<std::string>(obj.at("city").data) == "NYC");
   };

   "generic_multiline_flow_with_nested"_test = [] {
      std::string yaml = R"({"person": {"name": "Charlie",
"age": 35},
"active": true})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 2u);
      expect(std::holds_alternative<glz::generic::object_t>(obj.at("person").data));
      expect(std::holds_alternative<bool>(obj.at("active").data));
   };

   // Block-style YAML parsing into glz::generic
   "generic_block_mapping_simple"_test = [] {
      std::string yaml = "name: Alice";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1u);
      expect(std::holds_alternative<std::string>(obj.at("name").data));
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   "generic_block_mapping_with_document_marker"_test = [] {
      std::string yaml = "---\nname: Alice";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   "generic_block_mapping_multiple_entries"_test = [] {
      std::string yaml = R"(name: Alice
age: 30
city: NYC)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 3u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
      expect(std::get<double>(obj.at("age").data) == 30.0);
      expect(std::get<std::string>(obj.at("city").data) == "NYC");
   };

   // Nested block-style mappings into glz::generic
   "generic_nested_block_style_mapping"_test = [] {
      std::string yaml = R"(person:
  name: Bob
  age: 25)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("person") == 1u);
      expect(std::holds_alternative<glz::generic::object_t>(obj.at("person").data));

      auto& person = std::get<glz::generic::object_t>(obj.at("person").data);
      expect(std::get<std::string>(person.at("name").data) == "Bob");
      expect(std::get<double>(person.at("age").data) == 25.0);
   };

   // Nested glz::generic member should preserve sibling keys in a nested block mapping.
   "nested_generic_struct_member_keeps_all_nested_mapping_keys"_test = [] {
      std::string yaml = R"(---
b:
  c:
    d: 1
    e: 2
)";

      struct_with_nested_generic parsed{};
      auto rec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string out;
      auto wec = glz::write_yaml(parsed, out);
      expect(!wec);

      auto* obj = parsed.b.c.get_if<glz::generic::object_t>();
      expect(obj != nullptr);
      if (obj != nullptr) {
         expect(obj->size() == 2u) << out;
         expect(obj->count("d") == 1u);
         expect(obj->count("e") == 1u) << out;
         expect(std::get<double>(obj->at("d").data) == 1.0);
         expect(std::get<double>(obj->at("e").data) == 2.0);
      }
   };

   // Deep block mappings inside nested glz::generic members should preserve sibling keys at each depth.
   "nested_generic_struct_member_keeps_deep_nested_mapping_keys"_test = [] {
      std::string yaml = R"(---
b:
  c:
    level1:
      level2:
        d: 1
        e: 2
      sibling2: keep2
    sibling1: keep1
)";

      struct_with_nested_generic parsed{};
      auto rec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string out;
      auto wec = glz::write_yaml(parsed, out);
      expect(!wec);

      auto* root = parsed.b.c.get_if<glz::generic::object_t>();
      expect(root != nullptr);
      if (root != nullptr) {
         expect(root->size() == 2u) << out;
         expect(root->count("level1") == 1u);
         expect(root->count("sibling1") == 1u) << out;
         expect(std::get<std::string>(root->at("sibling1").data) == "keep1");

         auto* level1 = root->at("level1").get_if<glz::generic::object_t>();
         expect(level1 != nullptr);
         if (level1 != nullptr) {
            expect(level1->size() == 2u) << out;
            expect(level1->count("level2") == 1u);
            expect(level1->count("sibling2") == 1u) << out;
            expect(std::get<std::string>(level1->at("sibling2").data) == "keep2");

            auto* level2 = level1->at("level2").get_if<glz::generic::object_t>();
            expect(level2 != nullptr);
            if (level2 != nullptr) {
               expect(level2->size() == 2u) << out;
               expect(level2->count("d") == 1u);
               expect(level2->count("e") == 1u) << out;
               expect(std::get<double>(level2->at("d").data) == 1.0);
               expect(std::get<double>(level2->at("e").data) == 2.0);
            }
         }
      }
   };

   // First verify simple two-key block mapping works
   "generic_two_key_simple"_test = [] {
      std::string yaml = R"(first: 1
second: 2)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("first") == 1u);
      expect(root.count("second") == 1u);
   };

   // Multiple top-level keys, first with nested content
   "generic_nested_then_simple"_test = [] {
      std::string yaml = R"(person:
  name: Bob
other: simple)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("person") == 1u);
      expect(root.count("other") == 1u);
   };

   // Three levels of nesting
   "generic_deeply_nested_block"_test = [] {
      std::string yaml = R"(level1:
  level2:
    level3: deep_value
    another: 42
  sibling2: test
top_sibling: done)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("level1") == 1u);
      expect(root.count("top_sibling") == 1u);

      auto& level1 = std::get<glz::generic::object_t>(root.at("level1").data);
      expect(level1.count("level2") == 1u);
      expect(level1.count("sibling2") == 1u);

      auto& level2 = std::get<glz::generic::object_t>(level1.at("level2").data);
      expect(std::get<std::string>(level2.at("level3").data) == "deep_value");
      expect(std::get<double>(level2.at("another").data) == 42.0);
   };

   // Multiple nested objects at same level
   "generic_multiple_nested_siblings"_test = [] {
      std::string yaml = R"(first:
  a: 1
  b: 2
second:
  c: 3
  d: 4
third:
  e: 5)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("first") == 1u);
      expect(root.count("second") == 1u);
      expect(root.count("third") == 1u);

      auto& first = std::get<glz::generic::object_t>(root.at("first").data);
      expect(std::get<double>(first.at("a").data) == 1.0);
      expect(std::get<double>(first.at("b").data) == 2.0);

      auto& second = std::get<glz::generic::object_t>(root.at("second").data);
      expect(std::get<double>(second.at("c").data) == 3.0);
      expect(std::get<double>(second.at("d").data) == 4.0);
   };

   // Mixed pattern: simple, nested, simple
   "generic_simple_nested_simple"_test = [] {
      std::string yaml = R"(before: start
nested:
  inner: value
after: end)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("before") == 1u);
      expect(root.count("nested") == 1u);
      expect(root.count("after") == 1u);

      expect(std::get<std::string>(root.at("before").data) == "start");
      expect(std::get<std::string>(root.at("after").data) == "end");

      auto& nested = std::get<glz::generic::object_t>(root.at("nested").data);
      expect(std::get<std::string>(nested.at("inner").data) == "value");
   };

   // Nested with various value types
   "generic_nested_mixed_types"_test = [] {
      std::string yaml = R"(config:
  name: test
  count: 100
  enabled: true
  ratio: 3.14
status: ok)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("config") == 1u);
      expect(root.count("status") == 1u);

      auto& config = std::get<glz::generic::object_t>(root.at("config").data);
      expect(std::get<std::string>(config.at("name").data) == "test");
      expect(std::get<double>(config.at("count").data) == 100.0);
      expect(std::get<bool>(config.at("enabled").data) == true);
      expect(std::get<double>(config.at("ratio").data) == 3.14);
   };

   // Nested followed by multiple siblings
   "generic_nested_then_multiple_siblings"_test = [] {
      std::string yaml = R"(nested:
  key: value
sibling1: one
sibling2: two
sibling3: three)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("nested") == 1u);
      expect(root.count("sibling1") == 1u);
      expect(root.count("sibling2") == 1u);
      expect(root.count("sibling3") == 1u);
   };

   // Block array as value in block mapping (was a bug: parsed as string)
   "generic_block_array_as_value"_test = [] {
      std::string yaml = R"(items:
  - first
  - second
other: done)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("items") == 1u);
      expect(root.count("other") == 1u);

      expect(std::holds_alternative<glz::generic::array_t>(root.at("items").data));
      auto& items = std::get<glz::generic::array_t>(root.at("items").data);
      expect(items.size() == 2u);
      expect(std::get<std::string>(items[0].data) == "first");
      expect(std::get<std::string>(items[1].data) == "second");
   };

   // Block array with single item
   "generic_block_array_single_item"_test = [] {
      std::string yaml = R"(items:
  - only)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::array_t>(root.at("items").data));
      auto& items = std::get<glz::generic::array_t>(root.at("items").data);
      expect(items.size() == 1u);
   };

   // Multiple block arrays as values
   "generic_multiple_block_arrays"_test = [] {
      std::string yaml = R"(first:
  - a
  - b
second:
  - c
  - d)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("first") == 1u);
      expect(root.count("second") == 1u);

      auto& first = std::get<glz::generic::array_t>(root.at("first").data);
      auto& second = std::get<glz::generic::array_t>(root.at("second").data);
      expect(first.size() == 2u);
      expect(second.size() == 2u);
   };

   // Block array of objects - each item should retain all keys
   "generic_block_array_of_objects"_test = [] {
      std::string yaml = R"(- name: Alice
  age: 30
- name: Bob
  age: 25)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 2u);

      // First item should have both keys
      expect(std::holds_alternative<glz::generic::object_t>(arr[0].data));
      auto& first = std::get<glz::generic::object_t>(arr[0].data);
      expect(first.size() == 2u);
      expect(first.count("name") == 1u);
      expect(first.count("age") == 1u);
      expect(std::get<std::string>(first.at("name").data) == "Alice");

      // Second item should also have both keys
      expect(std::holds_alternative<glz::generic::object_t>(arr[1].data));
      auto& second = std::get<glz::generic::object_t>(arr[1].data);
      expect(second.size() == 2u);
      expect(second.count("name") == 1u);
      expect(second.count("age") == 1u);
      expect(std::get<std::string>(second.at("name").data) == "Bob");
   };

   // Nested arrays with dash on separate line (value on next line)
   "generic_nested_array_dash_newline"_test = [] {
      std::string yaml = R"(-
  - a
  - b
-
  - c
  - d)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 2u);

      // First item should be an array with 2 elements
      expect(std::holds_alternative<glz::generic::array_t>(arr[0].data));
      auto& first = std::get<glz::generic::array_t>(arr[0].data);
      expect(first.size() == 2u);
      expect(std::get<std::string>(first[0].data) == "a");
      expect(std::get<std::string>(first[1].data) == "b");

      // Second item should be an array with 2 elements
      expect(std::holds_alternative<glz::generic::array_t>(arr[1].data));
      auto& second = std::get<glz::generic::array_t>(arr[1].data);
      expect(second.size() == 2u);
      expect(std::get<std::string>(second[0].data) == "c");
      expect(std::get<std::string>(second[1].data) == "d");
   };

   // Comment before nested content should not break parsing
   "generic_comment_before_nested_content"_test = [] {
      std::string yaml = R"(data:
  # This is a comment
  key: value
end: done)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.count("data") == 1u);
      expect(root.count("end") == 1u);

      // data should be an object, not an empty string
      expect(std::holds_alternative<glz::generic::object_t>(root.at("data").data));
      auto& data = std::get<glz::generic::object_t>(root.at("data").data);
      expect(data.count("key") == 1u);
      expect(std::get<std::string>(data.at("key").data) == "value");
   };

   // Multiple comments before nested content
   "generic_multiple_comments_before_nested"_test = [] {
      std::string yaml = R"(config:
  # First comment
  # Second comment
  setting: enabled
status: ok)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::object_t>(root.at("config").data));
      auto& config = std::get<glz::generic::object_t>(root.at("config").data);
      expect(std::get<std::string>(config.at("setting").data) == "enabled");
   };

   // Indented comment between mapping entries
   "generic_indented_comment_between_entries"_test = [] {
      std::string yaml = R"(name: Alice
  # indented comment
age: 30)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 2u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
      expect(std::get<double>(obj.at("age").data) == 30.0);
   };

   // Leading comment before any content
   "generic_leading_comment"_test = [] {
      std::string yaml = R"(# This is a header comment
name: Alice)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("name") == 1u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   // Leading comment with blank line
   "generic_leading_comment_blank_line"_test = [] {
      std::string yaml = R"(# comment

name: Alice)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   // Leading whitespace then comment
   "generic_leading_whitespace_comment"_test = [] {
      std::string yaml = "  # comment\nname: Alice";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   // Blank lines with whitespace between entries
   "generic_blank_lines_with_whitespace"_test = [] {
      std::string yaml = "name: Alice\n   \nage: 30";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 2u);
   };

   // Indented comment between array items
   "generic_indented_comment_in_array"_test = [] {
      std::string yaml = "- first\n  # comment\n- second";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 2u);
      expect(std::get<std::string>(arr[0].data) == "first");
      expect(std::get<std::string>(arr[1].data) == "second");
   };

   // Comment in nested array
   "generic_comment_in_nested_array"_test = [] {
      std::string yaml = R"(items:
  - first
  # comment
  - second)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::array_t>(obj.at("items").data));
      auto& arr = std::get<glz::generic::array_t>(obj.at("items").data);
      expect(arr.size() == 2u);
   };

   // Quoted keys in block mapping
   "generic_quoted_key_double"_test = [] {
      std::string yaml = R"("name": Alice)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("name") == 1u);
      expect(std::get<std::string>(obj.at("name").data) == "Alice");
   };

   // Quoted key with spaces
   "generic_quoted_key_with_spaces"_test = [] {
      std::string yaml = R"("full name": Alice Smith)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("full name") == 1u);
      expect(std::get<std::string>(obj.at("full name").data) == "Alice Smith");
   };

   // Quoted key containing colon
   "generic_quoted_key_with_colon"_test = [] {
      std::string yaml = R"("key:value": test)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("key:value") == 1u);
      expect(std::get<std::string>(obj.at("key:value").data) == "test");
   };

   // Empty quoted key
   "generic_empty_quoted_key"_test = [] {
      std::string yaml = R"("": value)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("") == 1u);
      expect(std::get<std::string>(obj.at("").data) == "value");
   };

   // Empty array item (dash followed by newline should be null)
   "generic_empty_array_item_first"_test = [] {
      std::string yaml = "- \n- second";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 2u);
      expect(std::holds_alternative<glz::generic::null_t>(arr[0].data));
      expect(std::get<std::string>(arr[1].data) == "second");
   };

   // Multiple empty array items
   "generic_empty_array_items_multiple"_test = [] {
      std::string yaml = "- \n- \n- value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3u);
      expect(std::holds_alternative<glz::generic::null_t>(arr[0].data));
      expect(std::holds_alternative<glz::generic::null_t>(arr[1].data));
      expect(std::get<std::string>(arr[2].data) == "value");
   };

   // Flow-style nested objects also work
   "generic_block_mapping_with_flow_nested_object"_test = [] {
      std::string yaml = R"(person: {name: Bob, age: 25})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("person") == 1u);
      expect(std::holds_alternative<glz::generic::object_t>(obj.at("person").data));

      auto& person = std::get<glz::generic::object_t>(obj.at("person").data);
      expect(std::get<std::string>(person.at("name").data) == "Bob");
      expect(std::get<double>(person.at("age").data) == 25.0);
   };

   // Keys starting with special characters that could be mistaken for other types
   "generic_block_mapping_key_starts_with_t"_test = [] {
      std::string yaml = "title: My Document";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("title").data) == "My Document");
   };

   "generic_block_mapping_key_starts_with_f"_test = [] {
      std::string yaml = "filename: test.txt";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("filename").data) == "test.txt");
   };

   "generic_block_mapping_key_starts_with_n"_test = [] {
      std::string yaml = "number: 42";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<double>(obj.at("number").data) == 42.0);
   };

   "generic_block_mapping_key_starts_with_digit"_test = [] {
      std::string yaml = "123key: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("123key").data) == "value");
   };

   // Actual boolean/null values vs keys that start with same letters
   "generic_block_mapping_true_vs_key"_test = [] {
      // "true" as a value should be boolean
      std::string yaml1 = "flag: true";
      glz::generic parsed1;
      auto rec1 = glz::read_yaml(parsed1, yaml1);
      expect(!rec1) << glz::format_error(rec1, yaml1);
      auto& obj1 = std::get<glz::generic::object_t>(parsed1.data);
      expect(std::holds_alternative<bool>(obj1.at("flag").data));
      expect(std::get<bool>(obj1.at("flag").data) == true);

      // "truthy" as a key should be detected as block mapping
      std::string yaml2 = "truthy: yes";
      glz::generic parsed2;
      auto rec2 = glz::read_yaml(parsed2, yaml2);
      expect(!rec2) << glz::format_error(rec2, yaml2);
      expect(std::holds_alternative<glz::generic::object_t>(parsed2.data));
      auto& obj2 = std::get<glz::generic::object_t>(parsed2.data);
      expect(obj2.count("truthy") == 1u);
   };

   "generic_block_mapping_false_vs_key"_test = [] {
      // "false" as a value should be boolean
      std::string yaml1 = "flag: false";
      glz::generic parsed1;
      auto rec1 = glz::read_yaml(parsed1, yaml1);
      expect(!rec1) << glz::format_error(rec1, yaml1);
      auto& obj1 = std::get<glz::generic::object_t>(parsed1.data);
      expect(std::holds_alternative<bool>(obj1.at("flag").data));
      expect(std::get<bool>(obj1.at("flag").data) == false);

      // "falsy" as a key should be detected as block mapping
      std::string yaml2 = "falsy: no";
      glz::generic parsed2;
      auto rec2 = glz::read_yaml(parsed2, yaml2);
      expect(!rec2) << glz::format_error(rec2, yaml2);
      expect(std::holds_alternative<glz::generic::object_t>(parsed2.data));
      auto& obj2 = std::get<glz::generic::object_t>(parsed2.data);
      expect(obj2.count("falsy") == 1u);
   };

   "generic_block_mapping_null_value"_test = [] {
      // "null" as a value should be null
      std::string yaml1 = "value: null";
      glz::generic parsed1;
      auto rec1 = glz::read_yaml(parsed1, yaml1);
      expect(!rec1) << glz::format_error(rec1, yaml1);
      auto& obj1 = std::get<glz::generic::object_t>(parsed1.data);
      expect(std::holds_alternative<std::nullptr_t>(obj1.at("value").data));
   };

   // For keys that might conflict with reserved words, use flow style
   "generic_flow_mapping_null_like_key"_test = [] {
      std::string yaml = R"({"nullable": "something"})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.count("nullable") == 1u);
   };

   // Mixed flow and block styles
   "generic_block_mapping_with_flow_value"_test = [] {
      std::string yaml = R"(data: {"inner": "value"})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::object_t>(obj.at("data").data));
   };

   "generic_block_mapping_with_flow_array_value"_test = [] {
      std::string yaml = "items: [1, 2, 3]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));

      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::array_t>(obj.at("items").data));

      auto& arr = std::get<glz::generic::array_t>(obj.at("items").data);
      expect(arr.size() == 3u);
   };

   // Roundtrip tests
   "generic_block_roundtrip"_test = [] {
      std::string yaml = R"(name: Test
value: 123
active: true)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);

      // Verify the data matches
      auto& obj1 = std::get<glz::generic::object_t>(parsed.data);
      auto& obj2 = std::get<glz::generic::object_t>(reparsed.data);
      expect(obj1.size() == obj2.size());
   };

   // Use flow style for complex nested structures with glz::generic
   "generic_complex_roundtrip"_test = [] {
      std::string yaml =
         R"({"users": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}], "metadata": {"version": 1, "enabled": true}})";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);
      expect(std::holds_alternative<glz::generic::object_t>(reparsed.data));
   };
};

// ============================================================
// Additional YAML Map Parsing Tests
// ============================================================

suite yaml_map_parsing_tests = [] {
   "map_multiline_flow_parsing"_test = [] {
      std::string yaml = R"({"key1": "value1",
"key2": "value2",
"key3": "value3"})";
      std::map<std::string, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 3u);
      expect(parsed["key1"] == "value1");
      expect(parsed["key2"] == "value2");
      expect(parsed["key3"] == "value3");
   };

   "map_multiline_flow_with_spaces"_test = [] {
      std::string yaml = R"({
   "a": 1,
   "b": 2
})";
      std::map<std::string, int> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 2u);
      expect(parsed["a"] == 1);
      expect(parsed["b"] == 2);
   };

   "map_flow_with_trailing_comma_newline"_test = [] {
      std::string yaml = R"({"x": 10,
"y": 20})";
      std::map<std::string, int> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 2u);
   };

   "unordered_map_multiline_flow"_test = [] {
      std::string yaml = R"({"first": 100,
"second": 200})";
      std::unordered_map<std::string, int> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 2u);
      expect(parsed["first"] == 100);
      expect(parsed["second"] == 200);
   };

   "map_inline_plain_mapping_value_rejected"_test = [] {
      std::string yaml = "outer: inner: value";
      std::map<std::string, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec)) << "Expected error for inline plain mapping indicator in block value";
   };

   "map_inline_plain_mapping_value_quoted_allowed"_test = [] {
      std::string yaml = R"(outer: "inner: value")";
      std::map<std::string, std::string> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 1u);
      expect(parsed["outer"] == "inner: value");
   };

   "map_inline_plain_mapping_value_flow_allowed"_test = [] {
      std::string yaml = R"(outer: {inner: value})";
      std::map<std::string, std::map<std::string, std::string>> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 1u);
      expect(parsed["outer"].size() == 1u);
      expect(parsed["outer"]["inner"] == "value");
   };
};

// ============================================================
// YAML Variant Edge Cases
// ============================================================

suite yaml_variant_edge_cases = [] {
   using test_variant =
      std::variant<std::nullptr_t, bool, double, std::string, std::vector<int>, std::map<std::string, int>>;

   "variant_block_map_key_t"_test = [] {
      // Key starting with 't' but not "true"
      std::string yaml = "test: 42";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::map<std::string, int>>(parsed));
      auto& m = std::get<std::map<std::string, int>>(parsed);
      expect(m["test"] == 42);
   };

   "variant_block_map_key_f"_test = [] {
      // Key starting with 'f' but not "false"
      std::string yaml = "foo: 123";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::map<std::string, int>>(parsed));
      auto& m = std::get<std::map<std::string, int>>(parsed);
      expect(m["foo"] == 123);
   };

   "variant_block_map_key_n"_test = [] {
      // Key starting with 'n' but not "null"
      std::string yaml = "name: 99";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::map<std::string, int>>(parsed));
      auto& m = std::get<std::map<std::string, int>>(parsed);
      expect(m["name"] == 99);
   };

   "variant_actual_true"_test = [] {
      std::string yaml = "true";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed));
      expect(std::get<bool>(parsed) == true);
   };

   "variant_actual_false"_test = [] {
      std::string yaml = "false";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<bool>(parsed));
      expect(std::get<bool>(parsed) == false);
   };

   "variant_actual_null"_test = [] {
      std::string yaml = "null";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::nullptr_t>(parsed));
   };

   "variant_flow_map"_test = [] {
      std::string yaml = R"({"a": 1, "b": 2})";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::map<std::string, int>>(parsed));
   };

   "variant_flow_array"_test = [] {
      std::string yaml = "[1, 2, 3]";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::vector<int>>(parsed));
      auto& v = std::get<std::vector<int>>(parsed);
      expect(v.size() == 3u);
   };

   "variant_number"_test = [] {
      std::string yaml = "42.5";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<double>(parsed));
      expect(std::get<double>(parsed) == 42.5);
   };

   "variant_quoted_string"_test = [] {
      std::string yaml = R"("hello world")";
      test_variant parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed));
      expect(std::get<std::string>(parsed) == "hello world");
   };
};

suite yaml_variant_block_style = [] {
   // Tests for issue #2447: complex variants in sequences should use block style

   "variant_map_in_sequence_block_style"_test = [] {
      using var_t = std::variant<int, std::map<std::string, int>>;
      std::vector<var_t> original;
      original.emplace_back(std::map<std::string, int>{{"a", 1}, {"b", 2}});

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == R"(-
  a: 1
  b: 2
)") << yaml;

      std::vector<var_t> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 1u);
      auto& m = std::get<std::map<std::string, int>>(parsed[0]);
      expect(m["a"] == 1);
      expect(m["b"] == 2);
   };

   "variant_array_in_sequence_block_style"_test = [] {
      using var_t = std::variant<int, std::vector<int>>;
      std::vector<var_t> original;
      original.emplace_back(std::vector<int>{10, 20, 30});

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == R"(-
  - 10
  - 20
  - 30
)") << yaml;

      std::vector<var_t> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& v = std::get<std::vector<int>>(parsed[0]);
      expect(v == std::vector<int>{10, 20, 30});
   };

   "variant_object_in_sequence_block_style"_test = [] {
      using var_t = std::variant<int, simple_struct>;
      std::vector<var_t> original;
      original.emplace_back(simple_struct{.x = 5, .y = 3.14, .name = "test"});

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == R"(- x: 5
  y: 3.14
  name: test
)") << yaml;

      std::vector<var_t> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& s = std::get<simple_struct>(parsed[0]);
      expect(s.x == 5);
      expect(s.y == 3.14);
      expect(s.name == "test");
   };

   "variant_empty_map_in_sequence"_test = [] {
      using var_t = std::variant<int, std::map<std::string, int>>;
      std::vector<var_t> original;
      original.emplace_back(std::map<std::string, int>{});

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "- {}\n") << yaml;
   };

   "variant_empty_array_in_sequence"_test = [] {
      using var_t = std::variant<int, std::vector<int>>;
      std::vector<var_t> original;
      original.emplace_back(std::vector<int>{});

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == "- []\n") << yaml;
   };

   "variant_mixed_simple_and_complex_in_sequence"_test = [] {
      using var_t = std::variant<int, std::string, std::map<std::string, int>>;
      std::vector<var_t> original;
      original.emplace_back(42);
      original.emplace_back(std::map<std::string, int>{{"key", 99}});
      original.emplace_back(std::string("hello"));

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == R"(- 42
-
  key: 99
- hello
)") << yaml;

      std::vector<var_t> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 3u);
      expect(std::get<int>(parsed[0]) == 42);
      expect(std::get<std::map<std::string, int>>(parsed[1])["key"] == 99);
      expect(std::get<std::string>(parsed[2]) == "hello");
   };

   "generic_complex_in_sequence_block_style"_test = [] {
      // glz::generic wrapping a variant - tests the glaze_value_t path
      std::vector<glz::generic> original;
      glz::generic obj;
      obj["name"] = "test";
      obj["value"] = 42.0;
      original.emplace_back(std::move(obj));

      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);
      expect(yaml == R"(-
  name: test
  value: 42
)") << yaml;

      std::vector<glz::generic> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj2 = std::get<glz::generic::object_t>(parsed[0].data);
      expect(std::get<std::string>(obj2.at("name").data) == "test");
      expect(std::get<double>(obj2.at("value").data) == 42.0);
   };

   "variant_multiline_string_in_mapping"_test = [] {
      // Tests write_variant_value indent_level fix for variant values in mappings
      glz::generic doc;
      doc["script"] = "echo hello\n./run --port=8080";
      doc["name"] = "service-1";

      std::string yaml;
      auto wec = glz::write_yaml(doc, yaml);
      expect(!wec);
      expect(yaml == R"(script: |-
  echo hello
  ./run --port=8080

name: service-1
)") << yaml;

      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::get<std::string>(obj.at("script").data) == "echo hello\n./run --port=8080");
      expect(std::get<std::string>(obj.at("name").data) == "service-1");
   };

   "variant_multiline_string_in_nested_mapping"_test = [] {
      // Tests indent_level propagation through nested variant mappings
      glz::generic doc;
      doc["outer"]["script"] = "line one\nline two\nline three";
      doc["outer"]["count"] = 42.0;

      std::string yaml;
      auto wec = glz::write_yaml(doc, yaml);
      expect(!wec);
      expect(yaml == R"(outer:
  script: |-
    line one
    line two
    line three

  count: 42
)") << yaml;

      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& outer = std::get<glz::generic::object_t>(root.at("outer").data);
      expect(std::get<std::string>(outer.at("script").data) == "line one\nline two\nline three");
      expect(std::get<double>(outer.at("count").data) == 42.0);
   };
};

suite generic_colon_in_value_tests = [] {
   "generic_time_format_hhmm"_test = [] {
      // Time format HH:MM should parse as string, not fail as number
      std::string yaml = "time: 12:30";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1u);
      expect(std::holds_alternative<std::string>(obj["time"].data));
      expect(std::get<std::string>(obj["time"].data) == "12:30");
   };

   "generic_time_format_hhmmss"_test = [] {
      // Time format HH:MM:SS should parse as string
      std::string yaml = "time: 12:30:45";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj["time"].data));
      expect(std::get<std::string>(obj["time"].data) == "12:30:45");
   };

   "generic_ip_with_port"_test = [] {
      // IP:port should parse as string
      std::string yaml = "addr: 192.168.1.1:8080";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj["addr"].data));
      expect(std::get<std::string>(obj["addr"].data) == "192.168.1.1:8080");
   };

   "generic_url_http"_test = [] {
      // URLs should parse as strings
      std::string yaml = "url: http://example.com";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj["url"].data));
      expect(std::get<std::string>(obj["url"].data) == "http://example.com");
   };

   "generic_colon_no_space"_test = [] {
      // Colon without following space should be part of string
      std::string yaml = "msg: hello:world";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj["msg"].data));
      expect(std::get<std::string>(obj["msg"].data) == "hello:world");
   };
};

suite generic_malformed_flow_tests = [] {
   "generic_malformed_flow_array_in_value"_test = [] {
      // Unclosed flow array in a block mapping value should produce an error
      std::string yaml = "note: [not closed";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec)) << "Expected error for unclosed flow array";
   };

   "generic_malformed_flow_object_in_value"_test = [] {
      // Unclosed flow object in a block mapping value should produce an error
      std::string yaml = "note: {not closed";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec)) << "Expected error for unclosed flow object";
   };

   "generic_partial_flow_array_in_value"_test = [] {
      // Partially closed flow array should produce an error
      std::string yaml = "note: [a, b";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec)) << "Expected error for partial flow array";
   };

   "generic_wellformed_flow_array_in_value"_test = [] {
      // Well-formed flow array should parse correctly
      std::string yaml = "note: [a, b, c]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::array_t>(obj["note"].data));
      auto& arr = std::get<glz::generic::array_t>(obj["note"].data);
      expect(arr.size() == 3u);
   };

   "generic_wellformed_flow_object_in_value"_test = [] {
      // Well-formed flow object should parse correctly
      std::string yaml = "note: {a: 1, b: 2}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::object_t>(obj["note"].data));
   };
};

// Issue #2379: glz::generic_u64 (and generic_i64) should work with YAML
suite yaml_generic_u64_parsing_tests = [] {
   "generic_u64_block_mapping_multiple_entries"_test = [] {
      std::string yaml = R"(name: Alice
age: 30
city: NYC)";
      glz::generic_u64 parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.holds<glz::generic_u64::object_t>());

      auto& obj = parsed.get<glz::generic_u64::object_t>();
      expect(obj.size() == 3u);
      expect(obj.at("name").get<std::string>() == "Alice");
      expect(obj.at("age").get<uint64_t>() == 30u);
      expect(obj.at("city").get<std::string>() == "NYC");
   };

   "generic_u64_roundtrip"_test = [] {
      std::string yaml = R"(name: Alice
age: 30
active: true)";
      glz::generic_u64 parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      glz::generic_u64 reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);
      expect(reparsed.holds<glz::generic_u64::object_t>());

      auto& obj = reparsed.get<glz::generic_u64::object_t>();
      expect(obj.size() == 3u);
   };

   "generic_u64_negative_numbers"_test = [] {
      std::string yaml = R"(positive: 42
negative: -5
decimal: 3.14)";
      glz::generic_u64 parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& obj = parsed.get<glz::generic_u64::object_t>();
      expect(obj.size() == 3u);
      expect(obj.at("positive").get<uint64_t>() == 42u);
      expect(obj.at("negative").get<int64_t>() == -5);
      expect(obj.at("decimal").get<double>() == 3.14);
   };

   "generic_i64_block_mapping"_test = [] {
      std::string yaml = R"(name: Alice
age: 30
score: -10)";
      glz::generic_i64 parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.holds<glz::generic_i64::object_t>());

      auto& obj = parsed.get<glz::generic_i64::object_t>();
      expect(obj.size() == 3u);
      expect(obj.at("name").get<std::string>() == "Alice");
      expect(obj.at("age").get<int64_t>() == 30);
      expect(obj.at("score").get<int64_t>() == -10);
   };
};

suite generic_boolean_null_key_tests = [] {
   "generic_true_as_key"_test = [] {
      // "true: value" should parse as object with key "true", not as boolean
      std::string yaml = "true: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.size() == 1u);
      expect(obj.contains("true"));
      expect(std::holds_alternative<std::string>(obj["true"].data));
      expect(std::get<std::string>(obj["true"].data) == "value");
   };

   "generic_true_colon_no_space"_test = [] {
      // "true:foo" should parse as a string, not a key or boolean
      std::string yaml = "true:foo";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<std::string>(parsed.data));
      expect(std::get<std::string>(parsed.data) == "true:foo");
   };

   "generic_false_as_key"_test = [] {
      // "false: value" should parse as object with key "false", not as boolean
      std::string yaml = "false: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("false"));
      expect(std::get<std::string>(obj["false"].data) == "value");
   };

   "generic_null_as_key"_test = [] {
      // "null: value" should parse as object with key "null", not as null
      std::string yaml = "null: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("null"));
      expect(std::get<std::string>(obj["null"].data) == "value");
   };

   "generic_true_as_value"_test = [] {
      // "key: true" should parse true as boolean
      std::string yaml = "key: true";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<bool>(obj["key"].data));
      expect(std::get<bool>(obj["key"].data) == true);
   };

   "generic_false_as_value"_test = [] {
      // "key: false" should parse false as boolean
      std::string yaml = "key: false";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<bool>(obj["key"].data));
      expect(std::get<bool>(obj["key"].data) == false);
   };

   "generic_null_as_value"_test = [] {
      // "key: null" should parse null correctly
      std::string yaml = "key: null";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::null_t>(obj["key"].data));
   };

   "generic_TRUE_as_key"_test = [] {
      // "TRUE: value" should parse as object with key "TRUE"
      std::string yaml = "TRUE: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("TRUE"));
   };

   "generic_False_as_key"_test = [] {
      // "False: value" should parse as object with key "False"
      std::string yaml = "False: value";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(obj.contains("False"));
   };
};

suite multiline_flow_sequence_tests = [] {
   "multiline_flow_sequence_basic"_test = [] {
      std::string yaml = "[\n  1,\n  2,\n  3\n]";
      std::vector<int> result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(result.size() == 3u);
      expect(result[0] == 1);
      expect(result[1] == 2);
      expect(result[2] == 3);
   };

   "multiline_flow_sequence_in_map"_test = [] {
      std::string yaml = "items: [\n  a,\n  b,\n  c\n]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(obj["items"].data);
      expect(arr.size() == 3u);
   };

   "multiline_flow_sequence_trailing_newline"_test = [] {
      std::string yaml = "[1, 2, 3\n]";
      std::vector<int> result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(result.size() == 3u);
   };
};

suite infinity_nan_tests = [] {
   "read_positive_infinity"_test = [] {
      std::string yaml = "val: .inf";
      std::map<std::string, double> result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::isinf(result["val"]));
      expect(result["val"] > 0);
   };

   "read_negative_infinity"_test = [] {
      std::string yaml = "val: -.inf";
      std::map<std::string, double> result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::isinf(result["val"]));
      expect(result["val"] < 0);
   };

   "read_nan"_test = [] {
      std::string yaml = "val: .nan";
      std::map<std::string, double> result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::isnan(result["val"]));
   };

   "write_positive_infinity"_test = [] {
      std::map<std::string, double> data{{"val", std::numeric_limits<double>::infinity()}};
      std::string yaml;
      auto rec = glz::write_yaml(data, yaml);
      expect(!rec);
      expect(yaml.find(".inf") != std::string::npos);
      expect(yaml.find("-.inf") == std::string::npos);
   };

   "write_negative_infinity"_test = [] {
      std::map<std::string, double> data{{"val", -std::numeric_limits<double>::infinity()}};
      std::string yaml;
      auto rec = glz::write_yaml(data, yaml);
      expect(!rec);
      expect(yaml.find("-.inf") != std::string::npos);
   };

   "write_nan"_test = [] {
      std::map<std::string, double> data{{"val", std::nan("")}};
      std::string yaml;
      auto rec = glz::write_yaml(data, yaml);
      expect(!rec);
      expect(yaml.find(".nan") != std::string::npos);
   };

   "roundtrip_infinity"_test = [] {
      std::map<std::string, double> original{{"val", std::numeric_limits<double>::infinity()}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::map<std::string, double> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::isinf(parsed["val"]));
      expect(parsed["val"] > 0);
   };

   "roundtrip_nan"_test = [] {
      std::map<std::string, double> original{{"val", std::nan("")}};
      std::string yaml;
      auto wec = glz::write_yaml(original, yaml);
      expect(!wec);

      std::map<std::string, double> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::isnan(parsed["val"]));
   };
};

suite yaml_tag_variant_tests = [] {
   "generic_tag_int"_test = [] {
      std::string yaml = "val: !!int 123";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<double>(obj["val"].data));
      expect(std::get<double>(obj["val"].data) == 123.0);
   };

   "generic_tag_float"_test = [] {
      std::string yaml = "val: !!float 1.5";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<double>(obj["val"].data));
      expect(std::get<double>(obj["val"].data) == 1.5);
   };

   "generic_tag_bool"_test = [] {
      std::string yaml = "val: !!bool true";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<bool>(obj["val"].data));
      expect(std::get<bool>(obj["val"].data) == true);
   };

   "generic_tag_null"_test = [] {
      std::string yaml = "val: !!null ~";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<glz::generic::null_t>(obj["val"].data));
   };

   "generic_tag_str"_test = [] {
      std::string yaml = "val: !!str 123";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      auto& obj = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<std::string>(obj["val"].data));
      expect(std::get<std::string>(obj["val"].data) == "123");
   };

   "generic_tag_seq"_test = [] {
      std::string yaml = "!!seq [1, 2, 3]";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::array_t>(parsed.data));
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3u);
   };

   "generic_tag_map"_test = [] {
      std::string yaml = "!!map {a: 1}";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(std::holds_alternative<glz::generic::object_t>(parsed.data));
   };

   "typed_tag_int"_test = [] {
      std::string yaml = "!!int 456";
      int result = 0;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(result == 456);
   };

   "typed_tag_str_to_string"_test = [] {
      std::string yaml = "!!str 789";
      std::string result;
      auto rec = glz::read_yaml(result, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(result == "789");
   };
};

// ============================================================
// Empty Value Tests
// ============================================================

struct two_strings
{
   std::string a{};
   std::string b{};
};

suite yaml_empty_value_tests = [] {
   "empty_value_followed_by_key"_test = [] {
      // Empty value (just newline after colon) followed by another key
      // This is valid YAML where 'a' should get an empty/default value
      std::string yaml = R"(a:
b: hello)";
      two_strings result;
      result.a = "unchanged";
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // 'a' should be empty (default value) and 'b' should be "hello"
      expect(result.a.empty() || result.a == "unchanged")
         << "a should be empty or unchanged, got: [" << result.a << "]";
      expect(result.b == "hello") << "b should be 'hello', got: [" << result.b << "]";
   };

   "empty_value_with_comment"_test = [] {
      // Empty value with trailing comment
      std::string yaml = R"(a: # this is a comment
b: world)";
      two_strings result;
      result.a = "unchanged";
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.a.empty() || result.a == "unchanged");
      expect(result.b == "world");
   };

   "multiple_empty_values"_test = [] {
      // Multiple consecutive empty values
      std::string yaml = R"(a:
b:
)";
      two_strings result;
      result.a = "x";
      result.b = "y";
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      // Both should be empty or unchanged (default behavior)
   };

   "empty_value_at_end"_test = [] {
      // Empty value at the end of document
      std::string yaml = R"(a: test
b:)";
      two_strings result;
      result.b = "unchanged";
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.a == "test");
      expect(result.b.empty() || result.b == "unchanged");
   };

   "nested_value_properly_indented"_test = [] {
      // When value IS properly indented, it should be parsed
      std::string yaml = R"(a:
  nested_value
b: other)";
      two_strings result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.a == "nested_value");
      expect(result.b == "other");
   };
};

// ============================================================
// glz::generic Write Indentation Tests
// ============================================================

suite yaml_generic_write_indentation_tests = [] {
   "generic_nested_write_indentation"_test = [] {
      // Parse nested YAML into generic
      std::string yaml = R"(level1:
  level2:
    level3: deep_value)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      // Write back and verify indentation
      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      // Output should have proper indentation
      expect(output.find("level1:") != std::string::npos);
      expect(output.find("  level2:") != std::string::npos) << "level2 should be indented under level1";
      expect(output.find("    level3:") != std::string::npos) << "level3 should be indented under level2";
   };

   "generic_complex_nested_write_indentation"_test = [] {
      std::string yaml = R"(contexts:
  prototype:
    - include: scope:source.shell.bash#prototype
  main:
    - include: scope:source.shell.bash)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      // Verify nested structure has proper indentation
      expect(output.find("contexts:") != std::string::npos);
      // The nested keys should be indented
      expect(output.find("  main:") != std::string::npos || output.find("  prototype:") != std::string::npos)
         << "Nested keys should be indented";
   };

   "generic_roundtrip_preserves_structure"_test = [] {
      std::string yaml = R"(root:
  child1:
    grandchild: value1
  child2: value2)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      // Parse the output again
      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);

      // Verify structure is preserved
      auto& root = std::get<glz::generic::object_t>(reparsed.data);
      expect(root.contains("root"));
      auto& rootObj = std::get<glz::generic::object_t>(root.at("root").data);
      expect(rootObj.contains("child1"));
      expect(rootObj.contains("child2"));
   };
};

// ============================================================
// Issue #2291: Strings starting with . or + should not be treated as numbers
// ============================================================

suite yaml_dot_prefix_string_tests = [] {
   // Test for issue #2291: strings starting with '.' should not be treated as numbers
   "generic_dot_prefixed_strings"_test = [] {
      std::string yaml = R"(file_extensions:
  - .c
  - .cpp
  - .h)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("file_extensions"));
      auto& arr = std::get<glz::generic::array_t>(root.at("file_extensions").data);
      expect(arr.size() == 3);
      expect(std::holds_alternative<std::string>(arr[0].data));
      expect(std::get<std::string>(arr[0].data) == ".c");
      expect(std::get<std::string>(arr[1].data) == ".cpp");
      expect(std::get<std::string>(arr[2].data) == ".h");
   };

   // Test that .inf, .nan are still parsed as numbers in generic context
   "generic_special_floats_still_work"_test = [] {
      std::string yaml = R"(values:
  - .inf
  - -.inf
  - .nan)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(root.at("values").data);
      expect(arr.size() == 3);
      // In glz::generic, numbers are stored as double
      expect(std::holds_alternative<double>(arr[0].data));
      expect(std::isinf(std::get<double>(arr[0].data)));
      expect(std::get<double>(arr[0].data) > 0);
      expect(std::holds_alternative<double>(arr[1].data));
      expect(std::isinf(std::get<double>(arr[1].data)));
      expect(std::get<double>(arr[1].data) < 0);
      expect(std::holds_alternative<double>(arr[2].data));
      expect(std::isnan(std::get<double>(arr[2].data)));
   };

   // Test for inline comments after values containing special characters
   "generic_inline_comment_after_value_simple"_test = [] {
      // Simple inline comment test without backslash
      std::string yaml = R"(match: hello|world  # This is a comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "hello|world");
   };

   "generic_inline_comment_with_regex"_test = [] {
      // Test with regex-like value containing backslash
      std::string yaml = R"(match: regex  # comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::get<std::string>(root.at("match").data) == "regex");
   };

   // Test + prefixed strings (similar to . issue)
   "generic_plus_prefixed_strings"_test = [] {
      std::string yaml = R"(items:
  - +foo
  - +bar)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(root.at("items").data);
      expect(arr.size() == 2);
      expect(std::holds_alternative<std::string>(arr[0].data));
      expect(std::get<std::string>(arr[0].data) == "+foo");
      expect(std::get<std::string>(arr[1].data) == "+bar");
   };

   // Test that +5 and .5 are still parsed as numbers
   "generic_plus_and_dot_numbers"_test = [] {
      std::string yaml = R"(values:
  - +5
  - .5
  - +.5)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(root.at("values").data);
      expect(arr.size() == 3);
      expect(std::holds_alternative<double>(arr[0].data));
      expect(std::get<double>(arr[0].data) == 5.0);
      expect(std::holds_alternative<double>(arr[1].data));
      expect(std::get<double>(arr[1].data) == 0.5);
      expect(std::holds_alternative<double>(arr[2].data));
      expect(std::get<double>(arr[2].data) == 0.5);
   };
};

// ============================================================
// Issue #2291: Sublime Text syntax file parsing tests
// ============================================================

suite yaml_sublime_syntax_tests = [] {
   // Test for issue #2291: inline comment after regex-like value
   // From Python.sublime-syntax line 410
   // First, test a simple version without the sequence context
   "sublime_inline_comment_simple"_test = [] {
      // First verify parsing works without backslash
      std::string yaml1 = R"(match: hello|world  # comment)";
      glz::generic parsed1;
      auto rec1 = glz::read_yaml(parsed1, yaml1);
      expect(!rec1) << glz::format_error(rec1, yaml1);
      auto& root1 = std::get<glz::generic::object_t>(parsed1.data);
      expect(root1.contains("match"));
      expect(std::get<std::string>(root1.at("match").data) == "hello|world");

      // Now test with backslash (escaped regex)
      std::string yaml2 = R"(match: test\Svalue  # comment)";
      glz::generic parsed2;
      auto rec2 = glz::read_yaml(parsed2, yaml2);
      expect(!rec2) << glz::format_error(rec2, yaml2);
      auto& root2 = std::get<glz::generic::object_t>(parsed2.data);
      expect(root2.contains("match"));
      // In raw string, \S is backslash-S
      expect(std::get<std::string>(root2.at("match").data) == "test\\Svalue");
   };

   // Test a sequence item with mapping
   "sublime_sequence_mapping"_test = [] {
      std::string yaml = R"(- match: hello|world  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "hello|world");
      expect(item.contains("pop"));
   };

   // Test simpler backslash in sequence
   "sublime_backslash_in_sequence"_test = [] {
      std::string yaml = R"(- match: test\Svalue
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "test\\Svalue");
   };

   // Test backslash with comment in sequence
   "sublime_backslash_comment_sequence"_test = [] {
      std::string yaml = R"(- match: test\S  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "test\\S");
   };

   // Test caret and pipe in sequence
   "sublime_caret_pipe"_test = [] {
      std::string yaml = R"(- match: ^|  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "^|");
   };

   // Test parentheses in sequence
   "sublime_parens"_test = [] {
      std::string yaml = R"(- match: (?=test)  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "(?=test)");
   };

   // Test caret-pipe-parens without backslash
   "sublime_caret_pipe_parens"_test = [] {
      std::string yaml = R"(- match: ^|(?=test)  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "^|(?=test)");
   };

   // Test just parens with backslash
   "sublime_parens_backslash"_test = [] {
      std::string yaml = R"(- match: (?=\S)  # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "(?=\\S)");
   };

   // Test the full pattern without comment
   "sublime_full_pattern_no_comment"_test = [] {
      std::string yaml = R"(- match: ^|(?=\S)
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "^|(?=\\S)");
   };

   // Test reverse order: backslash first, then caret-pipe
   "sublime_backslash_then_caretpipe"_test = [] {
      std::string yaml = R"(- match: (?=\S)|^ # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "(?=\\S)|^");
   };

   // Test separate: caret-pipe-parens plus backslash later
   "sublime_combo_no_backslash_in_parens"_test = [] {
      std::string yaml = R"(- match: ^|(?=X)\S # comment
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      expect(std::get<std::string>(item.at("match").data) == "^|(?=X)\\S");
   };

   // Test as simple key-value (not in sequence)
   "sublime_pattern_simple_kv"_test = [] {
      std::string yaml = R"(match: ^|(?=\S)  # comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::get<std::string>(root.at("match").data) == "^|(?=\\S)");
   };

   // Test the full context with sequence and backslash
   "sublime_inline_comment_with_regex"_test = [] {
      std::string yaml = R"(- match: ^|(?=\S)  # Note: Ensure to highlight shebang
  pop: 1)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("match"));
      // The value should be the regex pattern without the comment
      expect(std::get<std::string>(item.at("match").data) == "^|(?=\\S)");
      expect(item.contains("pop"));
   };

   // Test for issue #2291: file_extensions with dot-prefixed strings
   "sublime_file_extensions"_test = [] {
      std::string yaml = R"(file_extensions:
  - py
  - py3
  - pyw
  - pyi
  - .pyx
  - .pxd)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(root.at("file_extensions").data);
      expect(arr.size() == 6);
      expect(std::get<std::string>(arr[0].data) == "py");
      expect(std::get<std::string>(arr[4].data) == ".pyx");
      expect(std::get<std::string>(arr[5].data) == ".pxd");
   };

   // Test for issue #2291: block scalar with chomping indicator
   "sublime_block_scalar_chomping"_test = [] {
      std::string yaml = R"(first_line_match: |-
  (?xi:
    ^ \#! .* \bpython\b
  ))";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("first_line_match"));
      auto& val = std::get<std::string>(root.at("first_line_match").data);
      // Block scalar with strip chomping - no trailing newline
      expect(val.find("(?xi:") != std::string::npos);
   };

   // Test for YAML directives
   "sublime_yaml_directive"_test = [] {
      std::string yaml = R"(%YAML 1.2
---
name: Python
scope: source.python)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("name"));
      expect(std::get<std::string>(root.at("name").data) == "Python");
   };

   // Test for nested structure similar to sublime-syntax contexts
   "sublime_contexts_structure"_test = [] {
      std::string yaml = R"(contexts:
  prototype:
    - include: scope:source.shell.bash#prototype
  main:
    - include: scope:source.shell.bash)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("contexts"));
      auto& contexts = std::get<glz::generic::object_t>(root.at("contexts").data);
      expect(contexts.contains("prototype"));
      expect(contexts.contains("main"));

      auto& prototype_entries = std::get<glz::generic::array_t>(contexts.at("prototype").data);
      expect(prototype_entries.size() == 1u);
      auto& prototype_entry = std::get<glz::generic::object_t>(prototype_entries[0].data);
      expect(std::get<std::string>(prototype_entry.at("include").data) == "scope:source.shell.bash#prototype");

      auto& main_entries = std::get<glz::generic::array_t>(contexts.at("main").data);
      expect(main_entries.size() == 1u);
      auto& main_entry = std::get<glz::generic::object_t>(main_entries[0].data);
      expect(std::get<std::string>(main_entry.at("include").data) == "scope:source.shell.bash");
   };

   "sublime_shell_unix_generic_roundtrip"_test = [] {
      std::string yaml = R"(---
name: Shell-Unix-Generic
hidden: true
scope: source.shell
contexts:
  prototype:
    - include: scope:source.shell.bash#prototype
  main:
    - include: scope:source.shell.bash)";

      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      std::string output;
      auto wec = glz::write_yaml(parsed, output);
      expect(!wec);

      glz::generic reparsed;
      auto rec2 = glz::read_yaml(reparsed, output);
      expect(!rec2) << glz::format_error(rec2, output);

      auto& root = std::get<glz::generic::object_t>(reparsed.data);
      expect(std::get<std::string>(root.at("name").data) == "Shell-Unix-Generic");
      expect(std::get<bool>(root.at("hidden").data) == true);
      expect(std::get<std::string>(root.at("scope").data) == "source.shell");

      auto& contexts = std::get<glz::generic::object_t>(root.at("contexts").data);
      auto& prototype_entries = std::get<glz::generic::array_t>(contexts.at("prototype").data);
      auto& prototype_entry = std::get<glz::generic::object_t>(prototype_entries[0].data);
      expect(std::get<std::string>(prototype_entry.at("include").data) == "scope:source.shell.bash#prototype");
   };

   "sublime_hash_separator_after_block_scalar"_test = [] {
      std::string yaml = R"(variables:
  magic_variables: |-
    (?x: __(?:
    | class
    )__\b )

##############################################################################

contexts:
  main:
    - match: '')";

      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("variables"));
      expect(root.contains("contexts"));
   };
};

// Tests for multiline plain scalar folding (issue #2291)
suite yaml_multiline_plain_scalar_tests = [] {
   // Test multiline value where content starts on next line after key
   "multiline_scope_value"_test = [] {
      std::string yaml = R"(- match: '(\.)'
  scope:
    meta.statement.conditional.case.python
    keyword.control.conditional.case.python)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1);
      auto& item = std::get<glz::generic::object_t>(arr[0].data);
      expect(item.contains("scope"));
      // The two lines should be folded with a space
      expect(std::get<std::string>(item.at("scope").data) ==
             "meta.statement.conditional.case.python keyword.control.conditional.case.python");
   };

   // Test that sequence items at same indent don't get folded
   "sequence_items_not_folded"_test = [] {
      std::string yaml = R"(- hello
- world
- test)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 3);
      expect(std::get<std::string>(arr[0].data) == "hello");
      expect(std::get<std::string>(arr[1].data) == "world");
      expect(std::get<std::string>(arr[2].data) == "test");
   };

   // Continuation lines with "- " deeper than the sequence dash column are scalar content.
   // This should hold for all items, not just the first one.
   "sequence_dash_continuation_applies_to_all_items"_test = [] {
      std::string yaml = R"(- one
  - keep
- two
  - keep2
)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 2);
      expect(std::get<std::string>(arr[0].data) == "one - keep");
      expect(std::get<std::string>(arr[1].data) == "two - keep2");
   };

   "sequence_dash_continuation_in_mapping_value"_test = [] {
      std::string yaml = R"(k:
  - one
    - keep
  - two
    - keep2
)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      auto& arr = std::get<glz::generic::array_t>(root.at("k").data);
      expect(arr.size() == 2);
      expect(std::get<std::string>(arr[0].data) == "one - keep");
      expect(std::get<std::string>(arr[1].data) == "two - keep2");
   };

   // Test that mapping keys at same indent don't get folded
   "mapping_keys_not_folded"_test = [] {
      std::string yaml = R"(key1: value1
key2: value2)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.size() == 2);
      expect(std::get<std::string>(root.at("key1").data) == "value1");
      expect(std::get<std::string>(root.at("key2").data) == "value2");
   };

   // Test three-line multiline scalar
   "three_line_multiline_scalar"_test = [] {
      std::string yaml = R"(key:
  line one
  line two
  line three)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("key"));
      expect(std::get<std::string>(root.at("key").data) == "line one line two line three");
   };
};

suite yaml_explicit_key_indent_tests = [] {
   // Explicit-key value indicators must be at the key entry indentation.
   "explicit_key_value_indicator_cannot_be_deeper_indented"_test = [] {
      std::string yaml = R"(? key
  : value
)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec));
   };

   // Same rule for anchor-only explicit keys ("? &a").
   "explicit_anchor_key_value_indicator_cannot_be_deeper_indented"_test = [] {
      std::string yaml = R"(? &a
  : value
)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(bool(rec));
   };

   // yaml-test-suite M2N8-00
   "explicit_key_inline_colon_is_mapping_key_node"_test = [] {
      std::string yaml = R"(- ? : x)";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"([{"{\"\":\"x\"}":null}])") << json;
   };

   // yaml-test-suite SM9W-00
   "single_dash_stream_is_sequence_with_null_item"_test = [] {
      std::string yaml = R"(-)";
      glz::generic parsed{};
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto json = glz::write_json(parsed).value_or("WRITE_ERR");
      expect(json == R"([null])") << json;
   };
};

// Tests for boolean-like string values (issue #2291)
suite yaml_boolean_like_string_tests = [] {
   // Test that "False\b" is treated as a string, not a boolean
   "false_with_backslash_b"_test = [] {
      std::string yaml = R"(match: False\b)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "False\\b");
   };

   // Test that "True\b" is treated as a string, not a boolean
   "true_with_backslash_b"_test = [] {
      std::string yaml = R"(match: True\b)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "True\\b");
   };

   // Test that "Null\b" is treated as a string, not null
   "null_with_backslash_b"_test = [] {
      std::string yaml = R"(match: Null\b)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "Null\\b");
   };

   // Test that "true#comment" is treated as a string (not a boolean)
   "true_hash_comment_is_string"_test = [] {
      std::string yaml = R"(match: true#comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "true#comment");
   };

   // Test that "false#comment" is treated as a string (not a boolean)
   "false_hash_comment_is_string"_test = [] {
      std::string yaml = R"(match: false#comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "false#comment");
   };

   // Test that "null#comment" is treated as a string (not null)
   "null_hash_comment_is_string"_test = [] {
      std::string yaml = R"(match: null#comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("match"));
      expect(std::holds_alternative<std::string>(root.at("match").data));
      expect(std::get<std::string>(root.at("match").data) == "null#comment");
   };

   // Test that plain "False" is still treated as a boolean
   "plain_false_is_boolean"_test = [] {
      std::string yaml = R"(value: False)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("value"));
      expect(std::holds_alternative<bool>(root.at("value").data));
      expect(std::get<bool>(root.at("value").data) == false);
   };

   // Test that plain "True" is still treated as a boolean
   "plain_true_is_boolean"_test = [] {
      std::string yaml = R"(value: True)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(root.contains("value"));
      expect(std::holds_alternative<bool>(root.at("value").data));
      expect(std::get<bool>(root.at("value").data) == true);
   };

   // Test "False" followed by comment is still boolean
   "false_with_comment_is_boolean"_test = [] {
      std::string yaml = R"(value: False # comment)";
      glz::generic parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);

      auto& root = std::get<glz::generic::object_t>(parsed.data);
      expect(std::holds_alternative<bool>(root.at("value").data));
      expect(std::get<bool>(root.at("value").data) == false);
   };
};

// Tests for block scalar followed by another key in same mapping
struct block_scalar_sibling_struct
{
   std::string k1{};
   std::string k2{};
};

suite yaml_block_scalar_sibling_tests = [] {
   // Issue: Block scalar followed by another key at same indent level loses k2
   "block_scalar_sibling_key_in_sequence"_test = [] {
      std::string yaml = R"(- k1: |
    a
    b
  k2: c)";
      std::vector<block_scalar_sibling_struct> result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.size() == 1u);
      expect(result[0].k1 == "a\nb\n") << "k1 was: " << result[0].k1;
      expect(result[0].k2 == "c") << "k2 was: " << result[0].k2;
   };

   "block_scalar_sibling_key_in_sequence_generic"_test = [] {
      std::string yaml = R"(- k1: |
    a
    b
  k2: c)";
      glz::generic parsed;
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      auto& arr = std::get<glz::generic::array_t>(parsed.data);
      expect(arr.size() == 1u);
      auto& obj = std::get<glz::generic::object_t>(arr[0].data);
      expect(obj.count("k1") == 1u);
      expect(obj.count("k2") == 1u);
      expect(std::get<std::string>(obj.at("k1").data) == "a\nb\n")
         << "k1 was: " << std::get<std::string>(obj.at("k1").data);
      expect(std::get<std::string>(obj.at("k2").data) == "c") << "k2 was: " << std::get<std::string>(obj.at("k2").data);
   };

   // yaml-test-suite 4WA9: explicit block-scalar indentation in a sequence mapping.
   "block_scalar_explicit_indent_sibling_key_4WA9"_test = [] {
      std::string yaml = R"(- aaa: |2
    xxx
  bbb: |
    xxx
)";
      glz::generic parsed;
      auto ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      std::string json;
      (void)glz::write_json(parsed, json);
      expect(json == R"([{"aaa":"xxx\n","bbb":"xxx\n"}])") << "json was: " << json;
   };

   "block_scalar_sibling_key_simple"_test = [] {
      std::string yaml = R"(k1: |
  a
  b
k2: c)";
      block_scalar_sibling_struct result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.k1 == "a\nb\n") << "k1 was: " << result.k1;
      expect(result.k2 == "c") << "k2 was: " << result.k2;
   };
};

suite yaml_quoted_string_folding_tests = [] {
   // Issue: Quoted strings should fold line breaks
   // Single newline -> space, double newline -> single newline
   // Backslash at end of line (double-quoted only) -> no space
   "double_quoted_line_folding"_test = [] {
      // Note: trailing spaces on some lines are significant
      std::string yaml = R"(- "very \"long\"
  'string' with

  paragraph gap, \n and
  s\
  p\
  a\
  c\
  e\
  s.")";
      std::vector<std::string> result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.size() == 1u);
      // Expected: line breaks fold to spaces, blank line becomes \n, \n is literal newline, \ at end of line means no
      // space
      expect(result[0] == "very \"long\" 'string' with\nparagraph gap, \n and spaces.") << "got: " << result[0];
   };

   "single_quoted_line_folding"_test = [] {
      std::string yaml = R"(- 'very "long"
  ''string'' with

  paragraph gap, \n and
  spaces.')";
      std::vector<std::string> result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.size() == 1u);
      // Expected: line breaks fold to spaces, blank line becomes \n, \n is literal (two chars), trailing spaces trimmed
      expect(result[0] == "very \"long\" 'string' with\nparagraph gap, \\n and spaces.") << "got: " << result[0];
   };

   "double_quoted_simple_folding"_test = [] {
      std::string yaml = R"("hello
  world")";
      std::string result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result == "hello world") << "got: " << result;
   };

   "single_quoted_simple_folding"_test = [] {
      std::string yaml = R"('hello
  world')";
      std::string result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result == "hello world") << "got: " << result;
   };

   "double_quoted_blank_line_becomes_newline"_test = [] {
      std::string yaml = R"("line1

  line2")";
      std::string result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result == "line1\nline2") << "got: " << result;
   };

   "double_quoted_backslash_continuation"_test = [] {
      std::string yaml = R"("no\
  space")";
      std::string result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result == "nospace") << "got: " << result;
   };

   // Test from StackOverflow answer with trailing whitespace on lines
   // Trailing whitespace before a line break is trimmed in YAML quoted strings
   "stackoverflow_example_double_quoted"_test = [] {
      // Note: there are trailing spaces after "and" on line 5 - these get trimmed
      std::string yaml =
         "- \"very \\\"long\\\"\n"
         "  'string' with\n"
         "\n"
         "  paragraph gap, \\n and        \n"
         "  s\\\n"
         "  p\\\n"
         "  a\\\n"
         "  c\\\n"
         "  e\\\n"
         "  s.\"";
      std::vector<std::string> result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.size() == 1u);
      // Trailing spaces are trimmed, backslash continuations should work
      expect(result[0] == "very \"long\" 'string' with\nparagraph gap, \n and spaces.") << "got: " << result[0];
   };

   "yaml_map_multiline_string_indent"_test = [] {
      // Multiline string values in nested maps must be indented deeper than the
      // map key, otherwise the block scalar content merges with sibling entries.
      map_member_struct obj;
      obj.title = "test";
      obj.data["alpha"] = "line1\nline2";
      obj.data["beta"] = "hello";

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = R"(title: test
data:
  alpha: |-
    line1
    line2

  beta: hello
)";
      expect(yaml == expected);

      map_member_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.data["alpha"] == "line1\nline2");
      expect(result.data["beta"] == "hello");
   };

   "yaml_optional_multiline_string_indent"_test = [] {
      // std::optional<std::string> with multiline content in a nested struct
      // must pass the correct indent_level so the block scalar content lines
      // are indented deeper than the key.
      optional_string_outer obj;
      obj.title = "test";
      obj.nested.desc = "line1\nline2";
      obj.nested.count = 42;

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = R"(title: test
nested:
  desc: |-
    line1
    line2

  count: 42
)";
      expect(yaml == expected);

      optional_string_outer result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.nested.desc.has_value());
      expect(result.nested.desc.value() == "line1\nline2");
      expect(result.nested.count == 42);
   };

   "yaml_carriage_return_string_roundtrip"_test = [] {
      // Strings containing \r must use double-quoted style so the \r is escaped.
      // Single-quoted style treats \r as a line break and folds it to a space.
      simple_struct obj;
      obj.name = "hello\rworld";
      obj.x = 1;
      obj.y = 2.0;

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = "x: 1\ny: 2\nname: \"hello\\rworld\"\n";
      expect(yaml == expected);

      simple_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.name == "hello\rworld");
   };

   "yaml_trailing_whitespace_roundtrip"_test = [] {
      // Strings with trailing whitespace must be quoted when written,
      // because the YAML reader trims trailing whitespace from plain scalars.
      simple_struct obj;
      obj.name = "hello ";
      obj.x = 1;
      obj.y = 2.0;

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = R"(x: 1
y: 2
name: 'hello '
)";
      expect(yaml == expected);

      simple_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.name == "hello ");
   };

   "yaml_sequence_multiline_string_indent"_test = [] {
      // Multiline strings inside a vector<string> in a nested struct must
      // use the correct indent_level for block scalar content.
      // write_block_sequence dispatches strings through serialize<YAML>::op
      // which defaults indent_level=0, producing wrong indentation.
      seq_string_struct obj;
      obj.title = "test";
      obj.items = {"line1\nline2", "simple"};

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      // Items are at indent_level=1, so block scalar content should be at 4 spaces
      const std::string expected = R"(title: test
items:
  - |-
    line1
    line2

  - simple
)";
      expect(yaml == expected) << "got:\n" << yaml;

      // Round-trip
      seq_string_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.title == "test");
      expect(result.items.size() == 2u);
      expect(result.items[0] == "line1\nline2");
      expect(result.items[1] == "simple");
   };

   "yaml_multiline_with_carriage_return"_test = [] {
      // A string containing both \n and \r must NOT use block scalar style,
      // because block scalars have no escape mechanism and \r would be
      // treated as a line break by the parser. Must use double-quoted style.
      simple_struct obj;
      obj.x = 1;
      obj.y = 2.0;
      obj.name = "line1\nline2\rline3";

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = "x: 1\ny: 2\nname: \"line1\\nline2\\rline3\"\n";
      expect(yaml == expected) << "got:\n" << yaml;

      // Round-trip
      simple_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.name == "line1\nline2\rline3");
   };

   "yaml_empty_map_roundtrip"_test = [] {
      // An empty map field in a struct must serialize as {} (flow style),
      // not as a bare "key:" with no value, which YAML treats as null.
      map_member_struct obj;
      obj.title = "test";
      // obj.data is default-constructed (empty map)

      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);

      const std::string expected = R"(title: test
data: {}
)";
      expect(yaml == expected) << "got:\n" << yaml;

      // Round-trip
      map_member_struct result{};
      ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.title == "test");
      expect(result.data.empty());
   };

   "stackoverflow_example_single_quoted"_test = [] {
      // Note: there are trailing spaces after "and" on line 5 - these get trimmed
      std::string yaml =
         "- 'very \"long\"\n"
         "  ''string'' with\n"
         "\n"
         "  paragraph gap, \\n and        \n"
         "  spaces.'";
      std::vector<std::string> result;
      auto ec = glz::read_yaml(result, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(result.size() == 1u);
      // In single-quoted, \n is literal two chars, trailing spaces trimmed
      expect(result[0] == "very \"long\" 'string' with\nparagraph gap, \\n and spaces.") << "got: " << result[0];
   };
};

suite optional_vector_round_trip_tests = [] {
   "optional vector round trip"_test = [] {
      optional_vector_struct obj{};
      obj.x = 42;
      obj.items = std::vector<int>{1, 2, 3};
      obj.name = "hello";

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      optional_vector_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.x == 42);
      expect(parsed.items.has_value());
      expect(parsed.items->size() == 3u);
      if (parsed.items && parsed.items->size() == 3) {
         expect((*parsed.items)[0] == 1);
         expect((*parsed.items)[1] == 2);
         expect((*parsed.items)[2] == 3);
      }
      expect(parsed.name == "hello");
   };
};

struct optional_map_struct
{
   int x{};
   std::optional<std::map<std::string, int>> m{};
};

template <>
struct glz::meta<optional_map_struct>
{
   using T = optional_map_struct;
   static constexpr auto value = object("x", &T::x, "m", &T::m);
};

suite nullable_in_collections_tests = [] {
   "vector of optional string round trip"_test = [] {
      std::vector<std::optional<std::string>> obj{"hello", "line1\nline2", std::nullopt, "world"};

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      std::vector<std::optional<std::string>> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 4u);
      if (parsed.size() == 4) {
         expect(parsed[0].has_value() && *parsed[0] == "hello");
         expect(parsed[1].has_value() && *parsed[1] == "line1\nline2");
         expect(!parsed[2].has_value());
         expect(parsed[3].has_value() && *parsed[3] == "world");
      }
   };

   "map of optional string round trip"_test = [] {
      std::map<std::string, std::optional<std::string>> obj{
         {"a", "line1\nline2"}, {"b", std::nullopt}, {"c", "simple"}};

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      std::map<std::string, std::optional<std::string>> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 3u);
      expect(parsed["a"].has_value() && *parsed["a"] == "line1\nline2");
      expect(!parsed["b"].has_value());
      expect(parsed["c"].has_value() && *parsed["c"] == "simple");
   };

   "optional empty map in struct round trip"_test = [] {
      optional_map_struct obj{};
      obj.x = 42;
      obj.m = std::map<std::string, int>{}; // engaged but empty

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      optional_map_struct parsed{};
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.x == 42);
      expect(parsed.m.has_value()) << "engaged empty map should round-trip as engaged";
   };
};

suite nullable_empty_container_in_collections_tests = [] {
   "map of optional empty map round trip"_test = [] {
      std::map<std::string, std::optional<std::map<std::string, int>>> obj{{"a", std::map<std::string, int>{}}};

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      std::map<std::string, std::optional<std::map<std::string, int>>> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.count("a") == 1u);
      expect(parsed["a"].has_value()) << "engaged empty map inside map should round-trip as engaged";
   };

   "vector of optional empty map round trip"_test = [] {
      std::vector<std::optional<std::map<std::string, int>>> obj{std::map<std::string, int>{}};

      std::string yaml;
      auto wec = glz::write_yaml(obj, yaml);
      expect(!wec);

      std::vector<std::optional<std::map<std::string, int>>> parsed;
      auto rec = glz::read_yaml(parsed, yaml);
      expect(!rec) << glz::format_error(rec, yaml);
      expect(parsed.size() == 1u);
      if (parsed.size() == 1u) {
         expect(parsed[0].has_value()) << "engaged empty map inside vector should round-trip as engaged";
      }
   };
};

// Test that glz::read with opts{.format = YAML} works (issue #2380)
suite generic_read_yaml_format = [] {
   "glz::read with format YAML"_test = [] {
      constexpr auto options = glz::opts{.format = glz::YAML};

      std::string yaml = R"(name: John
age: 30)";

      std::map<std::string, glz::generic> obj;
      auto ec = glz::read<options>(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.size() == 2u);
   };

   "glz::read generic with format YAML"_test = [] {
      constexpr auto options = glz::opts{.format = glz::YAML};

      std::string yaml = "hello";

      glz::generic obj;
      auto ec = glz::read<options>(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
   };

   "glz::read with format YAML vector"_test = [] {
      constexpr auto options = glz::opts{.format = glz::YAML};

      std::string yaml = R"(- 1
- 2
- 3)";

      std::vector<int> obj;
      auto ec = glz::read<options>(obj, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(obj.size() == 3u);
      expect(obj == std::vector<int>{1, 2, 3});
   };
};

suite yaml_compact_sequence_tests = [] {
   "write_compact_sequence_of_objects"_test = [] {
      std::vector<simple_struct> vec{{1, 2.0, "a"}, {3, 4.0, "b"}};
      std::string yaml;
      auto ec = glz::write_yaml(vec, yaml);
      expect(!ec);
      // First key should be inline after dash: "- x:" not "-\n  x:"
      expect(yaml.find("- x:") != std::string::npos) << yaml;
      expect(yaml.find("-\n") == std::string::npos) << "should not have expanded dash";
   };

   "write_compact_sequence_roundtrip"_test = [] {
      std::vector<simple_struct> original{{1, 2.0, "a"}, {3, 4.0, "b"}};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      std::vector<simple_struct> parsed;
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.size() == 2u);
      expect(parsed[0].x == 1);
      expect(parsed[0].name == "a");
      expect(parsed[1].x == 3);
      expect(parsed[1].name == "b");
   };

   "write_compact_nested_sequence_of_objects"_test = [] {
      nested_struct obj{"hello", {1, 2.0, "inner"}, {10, 20}};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      // numbers sequence should have simple scalars (no compaction needed)
      expect(yaml.find("- 10") != std::string::npos);
   };

   "write_compact_sequence_in_struct_roundtrip"_test = [] {
      // nested_struct has a vector<int> (simple sequence) and nested object
      nested_struct original{"eng", {1, 2.0, "Alice"}, {10, 20, 30}};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      nested_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.title == "eng");
      expect(parsed.data.x == 1);
      expect(parsed.data.name == "Alice");
      expect(parsed.numbers == std::vector<int>{10, 20, 30});
   };

   "write_compact_optional_objects_in_sequence"_test = [] {
      std::vector<std::optional<simple_struct>> vec{simple_struct{1, 2.0, "a"}, std::nullopt};
      std::string yaml;
      auto ec = glz::write_yaml(vec, yaml);
      expect(!ec);
      expect(yaml.find("- x:") != std::string::npos) << yaml;
      expect(yaml.find("- null") != std::string::npos) << yaml;

      std::vector<std::optional<simple_struct>> parsed;
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.size() == 2u);
      expect(parsed[0].has_value());
      expect(parsed[0]->x == 1);
      expect(!parsed[1].has_value());
   };
};

suite yaml_skip_tests = [] {
   "yaml_write_skip_excludes_field"_test = [] {
      yaml_skip_struct obj{"abc", "top_secret", 42};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml.find("id: abc") != std::string::npos);
      expect(yaml.find("count: 42") != std::string::npos);
      expect(yaml.find("secret") == std::string::npos) << "secret field should be skipped";
   };

   "yaml_write_skip_if_excludes_default_value"_test = [] {
      yaml_skip_if_struct obj{"Alice", 0, "NYC"};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml.find("name: Alice") != std::string::npos);
      expect(yaml.find("city: NYC") != std::string::npos);
      expect(yaml.find("age") == std::string::npos) << "age should be skipped when 0";
   };

   "yaml_write_skip_if_includes_nondefault_value"_test = [] {
      yaml_skip_if_struct obj{"Bob", 30, "LA"};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml.find("name: Bob") != std::string::npos);
      expect(yaml.find("age: 30") != std::string::npos);
      expect(yaml.find("city: LA") != std::string::npos);
   };
};

suite yaml_custom_write_tests = [] {
   "yaml_custom_lambda_write_inline"_test = [] {
      yaml_custom_lambda_struct obj{"hello", 99};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      // Custom type should be written inline (key: value), not on next line
      expect(yaml.find("data: hello|99") != std::string::npos) << yaml;
   };

   "yaml_custom_lambda_roundtrip"_test = [] {
      yaml_custom_lambda_struct original{"test", 42};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      yaml_custom_lambda_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == original);
   };

   "yaml_custom_mixed_struct_roundtrip"_test = [] {
      yaml_custom_mixed_struct original{"widget", {"fast", 10}, 3};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);
      // The custom field inside nested struct should be inline
      expect(yaml.find("data: fast|10") != std::string::npos) << yaml;

      yaml_custom_mixed_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.name == original.name);
      expect(parsed.item == original.item);
      expect(parsed.count == original.count);
   };

   "yaml_custom_read_struct_roundtrip"_test = [] {
      // Existing custom read struct: write outputs int, read parses string to int
      yaml_custom_read_struct original{};
      original.value = 77;
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      yaml_custom_read_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.value == 77);
   };

   "yaml_custom_scalar_sequence_inline"_test = [] {
      std::vector<yaml_custom_scalar_struct> vec{{"a", 1}, {"b", 2}, {"c", 3}};
      std::string yaml;
      auto ec = glz::write_yaml(vec, yaml);
      expect(!ec);
      // Values should be inline after dash, not at column 0
      expect(yaml.find("- 'a:1'") != std::string::npos) << yaml;
      expect(yaml.find("- 'b:2'") != std::string::npos) << yaml;
      // Should NOT have value at column 0 after newline
      expect(yaml.find("\n'") == std::string::npos) << "value should not be at column 0";
   };

   "yaml_custom_scalar_sequence_roundtrip"_test = [] {
      std::vector<yaml_custom_scalar_struct> original{{"x", 10}, {"y", 20}};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      std::vector<yaml_custom_scalar_struct> parsed;
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed.size() == 2u);
      expect(parsed[0] == original[0]);
      expect(parsed[1] == original[1]);
   };

   "yaml_custom_scalar_sequence_in_struct_roundtrip"_test = [] {
      yaml_custom_mixed_struct outer{"container", {"fast", 10}, 5};
      std::string yaml;
      auto ec = glz::write_yaml(outer, yaml);
      expect(!ec);

      yaml_custom_mixed_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == outer);
   };
};

suite yaml_empty_array_tests = [] {
   "empty_array_field_inline"_test = [] {
      yaml_empty_array_struct obj{};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml == "name: hello\nitems: []\n") << yaml;
   };

   "empty_array_field_roundtrip"_test = [] {
      yaml_empty_array_struct original{};
      std::string yaml;
      auto ec = glz::write_yaml(original, yaml);
      expect(!ec);

      yaml_empty_array_struct parsed{};
      ec = glz::read_yaml(parsed, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(parsed == original);
   };

   "non_empty_array_field_unchanged"_test = [] {
      yaml_empty_array_struct obj{"hello", {1, 2, 3}};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml == "name: hello\nitems:\n  - 1\n  - 2\n  - 3\n") << yaml;
   };

   "multiple_empty_arrays"_test = [] {
      yaml_multi_empty_arrays_struct obj{};
      std::string yaml;
      auto ec = glz::write_yaml(obj, yaml);
      expect(!ec);
      expect(yaml == "a: []\nb: []\nx: 42\n") << yaml;
   };
};

struct yaml_missing_keys_two
{
   int a{};
   std::string b{};
};

struct yaml_missing_keys_three
{
   int i{};
   double d{};
   std::string hello{};
};

struct yaml_nullable_keys
{
   double req{};
   std::optional<double> opt{};
   double req2{};
   std::optional<double> opt2{};
};

struct yaml_inner
{
   int x{};
   int y{};
};

struct yaml_outer
{
   std::string name{};
   yaml_inner inner{};
};

struct yaml_with_shared_ptr
{
   int a{};
   std::shared_ptr<int> b{};
};

suite yaml_error_on_missing_keys_block = [] {
   "block_missing_one_key"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 101
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "b");
   };

   "block_all_keys_present"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 42
b: hello
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 42);
      expect(data.b == "hello");
   };

   "block_all_keys_present_reversed_order"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(b: world
a: 99
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 99);
      expect(data.b == "world");
   };

   "block_three_fields_missing_first"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"(d: 3.14
hello: world
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "i");
   };

   "block_three_fields_missing_middle"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"(i: 42
hello: world
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "d");
   };

   "block_three_fields_missing_last"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"(i: 42
d: 3.14
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "hello");
   };

   "block_three_fields_all_present"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"(i: 287
d: 3.14
hello: Hello World
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.i == 287);
      expect(data.d == 3.14);
      expect(data.hello == "Hello World");
   };

   "block_disabled_does_not_error"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 101
)";
      auto err = glz::read_yaml(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 101);
   };
};

suite yaml_error_on_missing_keys_flow = [] {
   "flow_missing_one_key"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({a: 101})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "b");
   };

   "flow_all_keys_present"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({a: 42, b: hello})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 42);
      expect(data.b == "hello");
   };

   "flow_all_keys_present_reversed"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({b: world, a: 99})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 99);
      expect(data.b == "world");
   };

   "flow_empty_mapping"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "a");
   };

   "flow_three_fields_missing_middle"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"({i: 42, hello: world})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "d");
   };

   "flow_three_fields_all_present"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"({i: 287, d: 3.14, hello: Hello World})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.i == 287);
      expect(data.d == 3.14);
      expect(data.hello == "Hello World");
   };
};

suite yaml_error_on_missing_keys_nullable = [] {
   "optional_not_required_block"_test = [] {
      yaml_nullable_keys data{};
      std::string yaml = R"(req: 1
req2: 2
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.req == 1.0);
      expect(data.req2 == 2.0);
      expect(!data.opt.has_value());
      expect(!data.opt2.has_value());
   };

   "optional_not_required_flow"_test = [] {
      yaml_nullable_keys data{};
      std::string yaml = R"({req: 1, req2: 2})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
   };

   "required_missing_with_optional_present"_test = [] {
      yaml_nullable_keys data{};
      std::string yaml = R"(opt: 1
req2: 2
opt2: 3
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "req");
   };

   "all_present_including_optional"_test = [] {
      yaml_nullable_keys data{};
      std::string yaml = R"(req: 10
opt: 20
req2: 30
opt2: 40
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.req == 10.0);
      expect(data.opt.value() == 20.0);
      expect(data.req2 == 30.0);
      expect(data.opt2.value() == 40.0);
   };

   "shared_ptr_not_required"_test = [] {
      yaml_with_shared_ptr data{};
      std::string yaml = R"(a: 42
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 42);
      expect(data.b == nullptr);
   };
};

suite yaml_error_on_missing_keys_nested = [] {
   "nested_inner_key_missing"_test = [] {
      yaml_outer data{};
      std::string yaml = R"(name: test
inner:
  x: 1
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "y");
   };

   "nested_all_present"_test = [] {
      yaml_outer data{};
      std::string yaml = R"(name: test
inner:
  x: 1
  y: 2
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.name == "test");
      expect(data.inner.x == 1);
      expect(data.inner.y == 2);
   };

   "nested_outer_key_missing"_test = [] {
      yaml_outer data{};
      std::string yaml = R"(inner:
  x: 1
  y: 2
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "name");
   };

   "nested_flow_inner"_test = [] {
      yaml_outer data{};
      std::string yaml = R"(name: test
inner: {x: 1, y: 2}
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.inner.x == 1);
      expect(data.inner.y == 2);
   };

   "nested_flow_inner_missing"_test = [] {
      yaml_outer data{};
      std::string yaml = R"(name: test
inner: {x: 1}
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "y");
   };
};

suite yaml_error_on_missing_keys_unknown_keys = [] {
   "block_unknown_key_with_missing"_test = [] {
      yaml_inner data{};
      std::string yaml = R"(x: 1
z: 99
)";
      auto err = glz::read_yaml<glz::opts{.error_on_unknown_keys = false, .error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "y");
   };

   "block_unknown_key_all_present"_test = [] {
      yaml_inner data{};
      std::string yaml = R"(x: 1
y: 2
z: 99
)";
      auto err = glz::read_yaml<glz::opts{.error_on_unknown_keys = false, .error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.x == 1);
      expect(data.y == 2);
   };

   "flow_unknown_key_with_missing"_test = [] {
      yaml_inner data{};
      std::string yaml = R"({x: 1, z: 99})";
      auto err = glz::read_yaml<glz::opts{.error_on_unknown_keys = false, .error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "y");
   };

   "flow_unknown_key_all_present"_test = [] {
      yaml_inner data{};
      std::string yaml = R"({x: 1, y: 2, z: 99})";
      auto err = glz::read_yaml<glz::opts{.error_on_unknown_keys = false, .error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
   };
};

suite yaml_error_on_missing_keys_vector = [] {
   "vector_all_elements_complete"_test = [] {
      std::vector<yaml_inner> data{};
      std::string yaml = R"(- x: 1
  y: 2
- x: 3
  y: 4
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.size() == 2);
      expect(data[0].x == 1);
      expect(data[0].y == 2);
      expect(data[1].x == 3);
      expect(data[1].y == 4);
   };

   "vector_second_element_missing_key"_test = [] {
      std::vector<yaml_inner> data{};
      std::string yaml = R"(- x: 1
  y: 2
- x: 3
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "y");
   };
};

suite yaml_error_on_missing_keys_yaml_opts = [] {
   "yaml_opts_block"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 101
)";
      auto err = glz::read_yaml<glz::yaml::yaml_opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "b");
   };

   "yaml_opts_flow"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({a: 101})";
      auto err = glz::read_yaml<glz::yaml::yaml_opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      expect(std::string_view{err.custom_error_message} == "b");
   };

   "yaml_opts_success"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 42
b: hello
)";
      auto err = glz::read_yaml<glz::yaml::yaml_opts{.error_on_missing_keys = true}>(data, yaml);
      expect(!err) << glz::format_error(err, yaml);
      expect(data.a == 42);
      expect(data.b == "hello");
   };
};

suite yaml_error_on_missing_keys_format_error = [] {
   "format_error_block_missing_b"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"(a: 101
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      auto msg = glz::format_error(err, yaml);
      expect(msg == R"(index 7: missing_key b)") << msg;
   };

   "format_error_block_missing_hello"_test = [] {
      yaml_missing_keys_three data{};
      std::string yaml = R"(i: 1
d: 2.0
)";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      auto msg = glz::format_error(err, yaml);
      expect(msg == R"(index 12: missing_key hello)") << msg;
   };

   "format_error_flow_missing_b"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({a: 101})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      auto msg = glz::format_error(err, yaml);
      expect(msg == R"(index 8: missing_key b)") << msg;
   };

   "format_error_flow_empty"_test = [] {
      yaml_missing_keys_two data{};
      std::string yaml = R"({})";
      auto err = glz::read_yaml<glz::opts{.error_on_missing_keys = true}>(data, yaml);
      expect(err.ec == glz::error_code::missing_key);
      auto msg = glz::format_error(err, yaml);
      expect(msg == R"(index 2: missing_key a)") << msg;
   };
};

// merge-in-meta YAML roundtrip

namespace merge_meta_yaml_test
{
   struct Species
   {
      std::string name{};
      int legs{};
   };

   struct Appearance
   {
      double weight{};
      std::string color{};
   };

   struct BearRecord
   {
      Species species{};
      Appearance appearance{};
   };
}

template <>
struct glz::meta<merge_meta_yaml_test::BearRecord>
{
   using T = merge_meta_yaml_test::BearRecord;
   static constexpr auto value = glz::merge{&T::species, &T::appearance};
};

suite merge_meta_yaml_tests = [] {
   using namespace merge_meta_yaml_test;

   "merge_meta_yaml_roundtrip"_test = [] {
      BearRecord original{};
      original.species.name = "Sloth";
      original.species.legs = 4;
      original.appearance.weight = 120.0;
      original.appearance.color = "tan";

      std::string yaml{};
      expect(not glz::write_yaml(original, yaml));

      BearRecord restored{};
      expect(not glz::read_yaml(restored, yaml));
      expect(restored.species.name == original.species.name);
      expect(restored.species.legs == original.species.legs);
      expect(restored.appearance.weight == original.appearance.weight);
      expect(restored.appearance.color == original.appearance.color);
   };
};

namespace yaml_skip_marker_tests
{
   struct marker
   {
      struct glaze
      {
         static constexpr auto value = glz::skip{};
      };
   };

   struct settings
   {
      marker m{};
      bool active{true};
      int count{42};
      std::string name{"hello"};
   };
}

// Issue #2539: types opted out of serialization via meta::value = glz::skip{}
// must round-trip correctly in YAML.
suite yaml_skip_marker_suite = [] {
   using namespace yaml_skip_marker_tests;
   "yaml skip-marker roundtrip"_test = [] {
      settings original{.active = false, .count = 7, .name = "world"};
      std::string yaml{};
      expect(not glz::write_yaml(original, yaml));
      // Marker key must not appear in the output.
      expect(yaml.find("m:") == std::string::npos) << yaml;

      settings decoded{};
      expect(not glz::read_yaml(decoded, yaml));
      expect(decoded.active == false);
      expect(decoded.count == 7);
      expect(decoded.name == "world");
   };
};

// Tagged variants: a meta::tag discriminator key selects the alternative (meta::ids names each
// type). Mirrors the JSON behavior so the same definitions round-trip across both formats.
namespace yaml_tagged_variant_tests
{
   struct put_action
   {
      std::map<std::string, int> data{};
      bool operator==(const put_action&) const = default;
   };
   struct delete_action
   {
      std::string data{};
      bool operator==(const delete_action&) const = default;
   };

   using tagged_variant = std::variant<put_action, delete_action>;

   // Automatic ids (default to glz::name_v) plus a monostate "none" alternative.
   using tagged_variant_auto = std::variant<put_action, delete_action, std::monostate>;

   // The discriminator name is also a member of each alternative.
   struct option_a
   {
      std::string tag{};
      int a{};
      bool operator==(const option_a&) const = default;
   };
   struct option_b
   {
      std::string tag{};
      int a{};
      bool operator==(const option_b&) const = default;
   };
   using tagged_object = std::variant<option_a, option_b>;

   // Integral discriminator ids.
   struct event_open
   {
      int fd{};
      bool operator==(const event_open&) const = default;
   };
   struct event_close
   {
      std::string reason{};
      bool operator==(const event_close&) const = default;
   };
   using int_tagged = std::variant<event_open, event_close>;

   struct holder
   {
      tagged_variant v{};
      bool operator==(const holder&) const = default;
   };
}

template <>
struct glz::meta<yaml_tagged_variant_tests::put_action>
{
   using T = yaml_tagged_variant_tests::put_action;
   static constexpr auto value = object("data", &T::data);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::delete_action>
{
   using T = yaml_tagged_variant_tests::delete_action;
   static constexpr auto value = object("data", &T::data);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::tagged_variant>
{
   static constexpr std::string_view tag = "action";
   static constexpr auto ids = std::array{"PUT", "DELETE"};
};
template <>
struct glz::meta<yaml_tagged_variant_tests::tagged_variant_auto>
{
   static constexpr std::string_view tag = "type";
   static constexpr auto ids = std::array{"PUT", "DELETE", "NONE"};
};
template <>
struct glz::meta<yaml_tagged_variant_tests::option_a>
{
   using T = yaml_tagged_variant_tests::option_a;
   static constexpr auto value = object("tag", &T::tag, "a", &T::a);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::option_b>
{
   using T = yaml_tagged_variant_tests::option_b;
   static constexpr auto value = object("tag", &T::tag, "a", &T::a);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::tagged_object>
{
   static constexpr std::string_view tag = "tag";
   static constexpr auto ids = std::array{"A", "B"};
};
template <>
struct glz::meta<yaml_tagged_variant_tests::event_open>
{
   using T = yaml_tagged_variant_tests::event_open;
   static constexpr auto value = object("fd", &T::fd);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::event_close>
{
   using T = yaml_tagged_variant_tests::event_close;
   static constexpr auto value = object("reason", &T::reason);
};
template <>
struct glz::meta<yaml_tagged_variant_tests::int_tagged>
{
   static constexpr std::string_view tag = "code";
   static constexpr auto ids = std::array{10, 20};
};
template <>
struct glz::meta<yaml_tagged_variant_tests::holder>
{
   using T = yaml_tagged_variant_tests::holder;
   static constexpr auto value = object("v", &T::v);
};

suite yaml_tagged_variant_suite = [] {
   using namespace yaml_tagged_variant_tests;

   "tagged read: tag first"_test = [] {
      tagged_variant v{};
      const std::string yaml = "action: DELETE\ndata: the_internet\n";
      expect(!glz::read_yaml(v, yaml));
      expect(std::holds_alternative<delete_action>(v));
      expect(std::get<delete_action>(v).data == "the_internet");
   };

   "tagged read: tag at end"_test = [] {
      tagged_variant v{};
      const std::string yaml = "data: the_internet\naction: DELETE\n";
      expect(!glz::read_yaml(v, yaml));
      expect(std::holds_alternative<delete_action>(v));
      expect(std::get<delete_action>(v).data == "the_internet");
   };

   "tagged read: nested mapping value"_test = [] {
      tagged_variant v{};
      const std::string yaml = "action: PUT\ndata:\n  x: 100\n  y: 200\n";
      expect(!glz::read_yaml(v, yaml));
      expect(std::holds_alternative<put_action>(v));
      expect(std::get<put_action>(v).data.at("x") == 100);
      expect(std::get<put_action>(v).data.at("y") == 200);
   };

   "tagged read: flow style"_test = [] {
      tagged_variant v{};
      expect(!glz::read_yaml(v, std::string("{action: DELETE, data: the_internet}")));
      expect(std::holds_alternative<delete_action>(v));
      expect(std::get<delete_action>(v).data == "the_internet");

      tagged_variant v2{};
      expect(!glz::read_yaml(v2, std::string("{data: the_internet, action: DELETE}")));
      expect(std::holds_alternative<delete_action>(v2));
   };

   "tagged read: automatic ids with monostate"_test = [] {
      tagged_variant_auto v = put_action{};
      expect(!glz::read_yaml(v, std::string("type: NONE\n")));
      expect(std::holds_alternative<std::monostate>(v));

      tagged_variant_auto v2{};
      expect(!glz::read_yaml(v2, std::string("type: PUT\ndata:\n  x: 1\n")));
      expect(std::holds_alternative<put_action>(v2));
      expect(std::get<put_action>(v2).data.at("x") == 1);
   };

   "tagged read: tag is also a member"_test = [] {
      tagged_object v{};
      expect(!glz::read_yaml(v, std::string("tag: A\na: 2\n")));
      expect(std::holds_alternative<option_a>(v));
      expect(std::get<option_a>(v).a == 2);
      // The discriminator value is also stored in the matching member.
      expect(std::get<option_a>(v).tag == "A");
   };

   "tagged read: integral ids"_test = [] {
      int_tagged v{};
      expect(!glz::read_yaml(v, std::string("code: 20\nreason: bye\n")));
      expect(std::holds_alternative<event_close>(v));
      expect(std::get<event_close>(v).reason == "bye");

      int_tagged v2{};
      expect(!glz::read_yaml(v2, std::string("code: 10\nfd: 7\n")));
      expect(std::holds_alternative<event_open>(v2));
      expect(std::get<event_open>(v2).fd == 7);
   };

   "tagged read: unknown id errors"_test = [] {
      tagged_variant v{};
      const auto ec = glz::read_yaml(v, std::string("action: NOPE\ndata: x\n"));
      expect(ec == glz::error_code::no_matching_variant_type);
   };

   "tagged write: block emits discriminator"_test = [] {
      tagged_variant v = delete_action{{"the_internet"}};
      std::string yaml;
      expect(!glz::write_yaml(v, yaml));
      expect(yaml == "action: DELETE\ndata: the_internet\n") << yaml;
   };

   "tagged write: flow emits discriminator"_test = [] {
      tagged_variant v = delete_action{{"the_internet"}};
      std::string yaml;
      expect(!glz::write<glz::yaml::yaml_opts{.flow_style = true}>(v, yaml));
      expect(yaml == "{action: DELETE, data: the_internet}") << yaml;
   };

   "tagged write: integral id"_test = [] {
      int_tagged v = event_close{{"bye"}};
      std::string yaml;
      expect(!glz::write_yaml(v, yaml));
      expect(yaml == "code: 20\nreason: bye\n") << yaml;
   };

   "tagged roundtrip: block and flow"_test = [] {
      const std::vector<tagged_variant> values{put_action{{{"x", 1}, {"y", 2}}}, delete_action{{"net"}}};
      for (const auto& original : values) {
         std::string block;
         expect(!glz::write_yaml(original, block));
         tagged_variant from_block{};
         expect(!glz::read_yaml(from_block, block)) << block;
         expect(from_block == original);

         std::string flow;
         expect(!glz::write<glz::yaml::yaml_opts{.flow_style = true}>(original, flow));
         tagged_variant from_flow{};
         expect(!glz::read_yaml(from_flow, flow)) << flow;
         expect(from_flow == original);
      }
   };

   "tagged roundtrip: nested as struct member"_test = [] {
      const holder original{delete_action{{"member"}}};
      std::string yaml;
      expect(!glz::write_yaml(original, yaml));
      holder decoded{};
      expect(!glz::read_yaml(decoded, yaml)) << yaml;
      expect(decoded == original);
   };

   "tagged roundtrip: sequence of variants"_test = [] {
      const std::vector<tagged_variant> original{put_action{{{"a", 1}}}, delete_action{{"x"}}};
      std::string yaml;
      expect(!glz::write_yaml(original, yaml));
      std::vector<tagged_variant> decoded;
      expect(!glz::read_yaml(decoded, yaml)) << yaml;
      expect(decoded == original);
   };

   "tagged read: discriminator after other members"_test = [] {
      // The discriminator may appear after other members, including within sequence items.
      const std::string yaml = "- data: alpha\n  action: DELETE\n- data: beta\n  action: DELETE\n";
      std::vector<tagged_variant> decoded;
      const auto ec = glz::read_yaml(decoded, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(decoded.size() == 2);
      expect(std::holds_alternative<delete_action>(decoded.at(0)));
      expect(std::holds_alternative<delete_action>(decoded.at(1)));
      expect(std::get<delete_action>(decoded.at(0)).data == "alpha");
      expect(std::get<delete_action>(decoded.at(1)).data == "beta");
   };

   "tagged read: tag first with extra dash spacing"_test = [] {
      // Extra spaces after the dash put the first key (the discriminator) at a column that is not
      // dash_indent + 1. The variant op recovers that column from the buffer and parses the
      // alternative at it, so the tag's inline value does not fold the following sibling entry, and
      // the next sequence item is still recognized as a dedent.
      const std::string yaml =
         "-   action: PUT\n"
         "    data:\n"
         "      x: 7\n"
         "-   action: DELETE\n"
         "    data: gone\n";
      std::vector<tagged_variant> decoded;
      const auto ec = glz::read_yaml(decoded, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(decoded.size() == 2);
      expect(std::holds_alternative<put_action>(decoded.at(0)));
      // A regression here over-folds `data` into the tag's value, leaving the map empty; check the
      // key is present first so the failure reports cleanly instead of throwing from at().
      const auto& put_data = std::get<put_action>(decoded.at(0)).data;
      expect(put_data.contains("x")) << "data folded into the discriminator value";
      if (put_data.contains("x")) {
         expect(put_data.at("x") == 7);
      }
      expect(std::holds_alternative<delete_action>(decoded.at(1)));
      expect(std::get<delete_action>(decoded.at(1)).data == "gone");
   };

   "tagged read: tag skipped but other unknown keys still error"_test = [] {
      // error_on_unknown_keys is true by default. The discriminator key is skipped (not a field of
      // delete_action), but a genuinely unknown key must still be rejected.
      tagged_variant ok{};
      expect(!glz::read_yaml(ok, std::string("action: DELETE\ndata: kept\n")));
      expect(std::holds_alternative<delete_action>(ok));

      tagged_variant bad{};
      const auto ec = glz::read_yaml(bad, std::string("action: DELETE\ndata: kept\nbogus: 1\n"));
      expect(ec == glz::error_code::unknown_key);
   };
};

// Stress tests for tagged variants: nesting, containers, irregular indentation, comments, quoting,
// block scalars, sparse/auto ids, and round-trips through less common parent contexts.
namespace yaml_tagged_variant_stress_tests
{
   using namespace yaml_tagged_variant_tests;

   // Structurally identical multi-field alternatives: only the discriminator can distinguish them
   // (not field-based deduction), and the multiple fields let the tag sit before/between/after them.
   struct rec_a
   {
      int x{};
      int y{};
      bool operator==(const rec_a&) const = default;
   };
   struct rec_b
   {
      int x{};
      int y{};
      bool operator==(const rec_b&) const = default;
   };
   using multi_tagged = std::variant<rec_a, rec_b>;

   // An alternative that itself holds a tagged variant - exercises the indent-column recovery and
   // push recursively (outer variant -> envelope object -> inner variant).
   struct envelope
   {
      tagged_variant payload{};
      int seq{};
      bool operator==(const envelope&) const = default;
   };
   using nested_tagged = std::variant<envelope, delete_action>;

   // Sparse, negative integral discriminator ids.
   struct sa
   {
      int v{};
      bool operator==(const sa&) const = default;
   };
   struct sb
   {
      int w{};
      bool operator==(const sb&) const = default;
   };
   using sparse_tagged = std::variant<sa, sb>;

   // A tag with no explicit ids: ids default to glz::name_v of each alternative. The alternatives are
   // structurally identical, so only the name-derived discriminator can select the right one.
   struct auto_x
   {
      int a{};
      bool operator==(const auto_x&) const = default;
   };
   struct auto_y
   {
      int a{};
      bool operator==(const auto_y&) const = default;
   };
   using auto_tagged = std::variant<auto_x, auto_y>;
}

template <>
struct glz::meta<yaml_tagged_variant_stress_tests::rec_a>
{
   using T = yaml_tagged_variant_stress_tests::rec_a;
   static constexpr auto value = object("x", &T::x, "y", &T::y);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::rec_b>
{
   using T = yaml_tagged_variant_stress_tests::rec_b;
   static constexpr auto value = object("x", &T::x, "y", &T::y);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::multi_tagged>
{
   static constexpr std::string_view tag = "kind";
   static constexpr auto ids = std::array{"A", "B"};
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::envelope>
{
   using T = yaml_tagged_variant_stress_tests::envelope;
   static constexpr auto value = object("payload", &T::payload, "seq", &T::seq);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::nested_tagged>
{
   static constexpr std::string_view tag = "otype";
   static constexpr auto ids = std::array{"ENV", "DEL"};
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::sa>
{
   using T = yaml_tagged_variant_stress_tests::sa;
   static constexpr auto value = object("v", &T::v);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::sb>
{
   using T = yaml_tagged_variant_stress_tests::sb;
   static constexpr auto value = object("w", &T::w);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::sparse_tagged>
{
   static constexpr std::string_view tag = "id";
   static constexpr auto ids = std::array{-5, 1000};
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::auto_x>
{
   using T = yaml_tagged_variant_stress_tests::auto_x;
   static constexpr auto value = object("a", &T::a);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::auto_y>
{
   using T = yaml_tagged_variant_stress_tests::auto_y;
   static constexpr auto value = object("a", &T::a);
};
template <>
struct glz::meta<yaml_tagged_variant_stress_tests::auto_tagged>
{
   static constexpr std::string_view tag = "t";
};

suite yaml_tagged_variant_stress_suite = [] {
   using namespace yaml_tagged_variant_stress_tests;

   "stress: variant as map value"_test = [] {
      const std::string yaml =
         "first:\n"
         "  action: PUT\n"
         "  data:\n"
         "    x: 1\n"
         "second:\n"
         "  action: DELETE\n"
         "  data: bye\n";
      std::map<std::string, tagged_variant> m;
      const auto ec = glz::read_yaml(m, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      const std::map<std::string, tagged_variant> expected{{"first", put_action{{{"x", 1}}}},
                                                           {"second", delete_action{{"bye"}}}};
      expect(m == expected);
   };

   "stress: optional<variant> read and round-trip"_test = [] {
      std::optional<tagged_variant> o;
      const auto ec = glz::read_yaml(o, std::string("action: DELETE\ndata: x\n"));
      expect(!ec);
      expect(o == std::optional<tagged_variant>{delete_action{{"x"}}});

      std::string s;
      expect(!glz::write_yaml(o, s));
      std::optional<tagged_variant> back;
      expect(!glz::read_yaml(back, s)) << s;
      expect(back == o);
   };

   "stress: variant alternative holding a tagged variant"_test = [] {
      const std::string yaml =
         "otype: ENV\n"
         "seq: 5\n"
         "payload:\n"
         "  action: DELETE\n"
         "  data: inner\n";
      nested_tagged v;
      const auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == nested_tagged{envelope{tagged_variant{delete_action{{"inner"}}}, 5}});

      std::string s;
      expect(!glz::write_yaml(v, s));
      nested_tagged back;
      expect(!glz::read_yaml(back, s)) << s;
      expect(back == v);
   };

   "stress: discriminator before, between, and after members"_test = [] {
      // rec_a and rec_b are identical, so resolution is purely by the tag, at any position.
      const multi_tagged expected{rec_a{1, 2}};
      for (const std::string yaml : {"kind: A\nx: 1\ny: 2\n", "x: 1\nkind: A\ny: 2\n", "x: 1\ny: 2\nkind: A\n"}) {
         multi_tagged v;
         const auto ec = glz::read_yaml(v, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
         expect(v == expected) << yaml;
      }
      // The other id selects the other (identical-shaped) alternative.
      multi_tagged b;
      expect(!glz::read_yaml(b, std::string("x: 3\nkind: B\ny: 4\n")));
      expect(b == multi_tagged{rec_b{3, 4}});
   };

   "stress: sparse and negative integral ids"_test = [] {
      sparse_tagged v;
      expect(!glz::read_yaml(v, std::string("id: -5\nv: 7\n")));
      expect(v == sparse_tagged{sa{7}});

      sparse_tagged v2;
      expect(!glz::read_yaml(v2, std::string("id: 1000\nw: 9\n")));
      expect(v2 == sparse_tagged{sb{9}});

      // Round-trip both.
      for (const sparse_tagged original : {sparse_tagged{sa{3}}, sparse_tagged{sb{4}}}) {
         std::string s;
         expect(!glz::write_yaml(original, s));
         sparse_tagged back;
         expect(!glz::read_yaml(back, s)) << s;
         expect(back == original);
      }
   };

   "stress: auto ids (no explicit ids array) round-trip"_test = [] {
      // Identical shapes and identical field values: the type survives the round-trip only because
      // the name-derived discriminator is written and read back.
      for (const auto_tagged original : {auto_tagged{auto_x{42}}, auto_tagged{auto_y{42}}}) {
         std::string s;
         expect(!glz::write_yaml(original, s));
         auto_tagged back;
         expect(!glz::read_yaml(back, s)) << s;
         expect(back.index() == original.index()) << s;
         expect(back == original);
      }
   };

   "stress: comments and blank lines within the mapping"_test = [] {
      const std::string yaml =
         "action: DELETE  # the discriminator\n"
         "\n"
         "data: kept  # value\n";
      tagged_variant v;
      const auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == tagged_variant{delete_action{{"kept"}}});
   };

   "stress: quoted discriminator value"_test = [] {
      tagged_variant v;
      expect(!glz::read_yaml(v, std::string("action: \"DELETE\"\ndata: x\n")));
      expect(v == tagged_variant{delete_action{{"x"}}});

      tagged_variant v2;
      expect(!glz::read_yaml(v2, std::string("action: 'DELETE'\ndata: y\n")));
      expect(v2 == tagged_variant{delete_action{{"y"}}});
   };

   "stress: flow with nested flow value"_test = [] {
      tagged_variant v;
      const auto ec = glz::read_yaml(v, std::string("{action: PUT, data: {x: 1, y: 2}}"));
      expect(!ec);
      expect(v == tagged_variant{put_action{{{"x", 1}, {"y", 2}}}});
   };

   "stress: block scalar member value"_test = [] {
      const std::string yaml =
         "action: DELETE\n"
         "data: |\n"
         "  line one\n"
         "  line two\n";
      tagged_variant v;
      const auto ec = glz::read_yaml(v, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      expect(v == tagged_variant{delete_action{{"line one\nline two\n"}}});
   };

   "stress: sequence of structs each holding a variant"_test = [] {
      const std::string yaml =
         "- v:\n"
         "    action: DELETE\n"
         "    data: a\n"
         "- v:\n"
         "    action: PUT\n"
         "    data:\n"
         "      x: 1\n";
      std::vector<holder> vec;
      const auto ec = glz::read_yaml(vec, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      const std::vector<holder> expected{holder{delete_action{{"a"}}}, holder{put_action{{{"x", 1}}}}};
      expect(vec == expected);
   };

   "stress: monostate round-trips through null"_test = [] {
      tagged_variant_auto original = std::monostate{};
      std::string s;
      expect(!glz::write_yaml(original, s));
      tagged_variant_auto back = put_action{};
      const auto ec = glz::read_yaml(back, s);
      expect(!ec) << s;
      expect(std::holds_alternative<std::monostate>(back)) << "wrote: " << s;
   };

   "stress: monostate via tag in flow"_test = [] {
      tagged_variant_auto v = put_action{};
      const auto ec = glz::read_yaml(v, std::string("{type: NONE}"));
      expect(!ec);
      expect(std::holds_alternative<std::monostate>(v));
   };

   "stress: unknown integral id is rejected"_test = [] {
      sparse_tagged v;
      const auto ec = glz::read_yaml(v, std::string("id: 7\n"));
      expect(ec == glz::error_code::no_matching_variant_type) << glz::format_error(ec, std::string("id: 7\n"));
   };

   "stress: unterminated flow mapping errors"_test = [] {
      tagged_variant v;
      const auto ec = glz::read_yaml(v, std::string("{action: PUT, data: {x: 1"));
      expect(bool(ec));
   };
};

// A std::variant whose own meta opts into custom_read/custom_write (with full from/to
// specializations) must not be ambiguous with the built-in YAML variant handler.
// Parity with the JSON fix in #2591.
struct yaml_fc_a
{};
struct yaml_fc_b
{};
using yaml_fc_variant = std::variant<yaml_fc_a, yaml_fc_b>;

template <>
struct glz::meta<yaml_fc_variant>
{
   static constexpr auto custom_read = true;
   static constexpr auto custom_write = true;
};

template <uint32_t Format>
struct glz::from<Format, yaml_fc_variant>
{
   template <auto Opts>
   static void op(yaml_fc_variant&, is_context auto&&, auto&&, auto&&)
   {}
};

template <uint32_t Format>
struct glz::to<Format, yaml_fc_variant>
{
   template <auto Opts>
   static void op(auto&&, is_context auto&& ctx, auto&&... args)
   {
      glz::serialize<Format>::template op<Opts>(42, ctx, args...);
   }
};

suite yaml_fully_custom_variant_tests = [] {
   "fully custom variant specialization is unambiguous"_test = [] {
      yaml_fc_variant v{};
      std::string s{};
      expect(not glz::write_yaml(v, s));
      expect(s == "42") << s;
   };
};

// A tagged-variant alternative that uses custom_read/custom_write and serializes an object body
// should merge the variant tag into that body and round-trip in block YAML, across root, sequence,
// struct-field and map-value contexts. Flow style is reported as unsupported.
namespace yaml_custom_alt_tests
{
   struct put_action
   {
      std::map<std::string, int>& data() { return m_data; }
      const std::map<std::string, int>& data() const { return m_data; }
      bool operator==(const put_action&) const = default;

     private:
      std::map<std::string, int> m_data{};
   };

   struct delete_action
   {
      std::string note{};
      bool operator==(const delete_action&) const = default;
   };

   using action_variant = std::variant<put_action, delete_action>;

   struct action_holder
   {
      int id{};
      action_variant act{};
      bool operator==(const action_holder&) const = default;
   };
}

template <>
struct glz::meta<yaml_custom_alt_tests::put_action>
{
   static constexpr auto custom_read = true;
   static constexpr auto custom_write = true;
};

template <uint32_t Format>
struct glz::from<Format, yaml_custom_alt_tests::put_action>
{
   template <auto Opts>
   static void op(yaml_custom_alt_tests::put_action& value, is_context auto&& ctx, auto&&... args)
   {
      glz::parse<Format>::template op<Opts>(value.data(), ctx, args...);
   }
};

template <uint32_t Format>
struct glz::to<Format, yaml_custom_alt_tests::put_action>
{
   template <auto Opts>
   static void op(auto&& value, is_context auto&& ctx, auto&&... args)
   {
      glz::serialize<Format>::template op<Opts>(value.data(), ctx, args...);
   }
};

template <>
struct glz::meta<yaml_custom_alt_tests::delete_action>
{
   using T = yaml_custom_alt_tests::delete_action;
   static constexpr auto value = object("note", &T::note);
};

template <>
struct glz::meta<yaml_custom_alt_tests::action_variant>
{
   static constexpr std::string_view tag = "action";
   static constexpr auto ids = std::array{"PUT", "DELETE"};
};

template <>
struct glz::meta<yaml_custom_alt_tests::action_holder>
{
   using T = yaml_custom_alt_tests::action_holder;
   static constexpr auto value = object("id", &T::id, "act", &T::act);
};

suite yaml_custom_alternative_variant_tests = [] {
   using namespace yaml_custom_alt_tests;
   auto put = [](std::map<std::string, int> m) {
      put_action p{};
      p.data() = std::move(m);
      return p;
   };

   "custom alternative block round-trips"_test = [&] {
      action_variant v = put({{"a", 1}, {"b", 2}});
      std::string s{};
      expect(not glz::write_yaml(v, s));
      expect(s == "action: PUT\na: 1\nb: 2\n") << s;
      action_variant r{};
      expect(not glz::read_yaml(r, s));
      expect(r == v);
   };

   "custom alternative empty body"_test = [&] {
      action_variant v = put({});
      std::string s{};
      expect(not glz::write_yaml(v, s));
      expect(s == "action: PUT\n") << s;
      action_variant r{};
      expect(not glz::read_yaml(r, s));
      expect(r == v);
   };

   "custom alternative in a sequence"_test = [&] {
      std::vector<action_variant> v{put({{"x", 9}}), delete_action{"bye"}, put({})};
      std::string s{};
      expect(not glz::write_yaml(v, s));
      std::vector<action_variant> r{};
      expect(not glz::read_yaml(r, s));
      expect(r == v);
   };

   "custom alternative as a struct field"_test = [&] {
      action_holder v{5, put({{"k", 7}})};
      std::string s{};
      expect(not glz::write_yaml(v, s));
      action_holder r{};
      expect(not glz::read_yaml(r, s));
      expect(r == v);
   };

   "custom alternative as a map value"_test = [&] {
      std::map<std::string, action_variant> v{{"first", put({{"a", 1}})}, {"second", delete_action{"hi"}}};
      std::string s{};
      expect(not glz::write_yaml(v, s));
      std::map<std::string, action_variant> r{};
      expect(not glz::read_yaml(r, s));
      expect(r == v);
   };

   "custom alternative requires the tag first"_test = [&] {
      action_variant r{};
      const auto ec = glz::read_yaml(r, std::string("a: 1\naction: PUT\n"));
      expect(ec == glz::error_code::feature_not_supported);
   };

   "custom alternative errors in flow style"_test = [&] {
      action_variant v = put({{"a", 1}});
      std::string s{};
      const auto ec = glz::write_yaml<glz::yaml::yaml_opts{.flow_style = true}>(v, s);
      expect(ec == glz::error_code::feature_not_supported);
   };
};

// Issue #2595: a field exposed through a transparent write wrapper - a mimic glaze_value_t
// (meta whose value is a single member pointer) or a glz::custom getter/setter - must be laid
// out by the shape it resolves to, identical to the equivalent plain field, rather than being
// mistaken for a scalar and emitted on the same line as its parent key.
namespace i2595
{
   struct leaf
   {
      std::string name{};
      int id{};
      bool operator==(const leaf&) const = default;
   };

   // mimic: meta value is a single member pointer, so this serializes exactly as `leaf`.
   struct mimic_leaf
   {
      leaf v{};
      bool operator==(const mimic_leaf&) const = default;
   };
   struct mimic_pair
   {
      mimic_leaf x{};
      mimic_leaf y{};
   };
   struct mimic_doc
   {
      mimic_pair mid{};
   };
   // Plain equivalents used to confirm the wrapped output matches a plain field exactly.
   struct plain_pair
   {
      leaf x{};
      leaf y{};
   };
   struct plain_doc
   {
      plain_pair mid{};
   };

   // glz::custom getter/setter exposing a nested object.
   struct custom_obj
   {
      leaf inner{};
      const leaf& get_inner() const { return inner; }
      void set_inner(leaf l) { inner = std::move(l); }
      bool operator==(const custom_obj&) const = default;
   };
   struct plain_obj
   {
      leaf inner{};
   };

   // glz::custom getter/setter exposing a sequence of objects.
   struct custom_seq
   {
      std::vector<leaf> items{};
      const std::vector<leaf>& get_items() const { return items; }
      void set_items(std::vector<leaf> v) { items = std::move(v); }
      bool operator==(const custom_seq&) const = default;
   };
   struct plain_seq
   {
      std::vector<leaf> items{};
   };
}

template <>
struct glz::meta<i2595::leaf>
{
   using T = i2595::leaf;
   static constexpr auto value = object("name", &T::name, "id", &T::id);
};
template <>
struct glz::meta<i2595::mimic_leaf>
{
   using mimic = i2595::leaf;
   static constexpr auto value = &i2595::mimic_leaf::v;
};
template <>
struct glz::meta<i2595::mimic_pair>
{
   using T = i2595::mimic_pair;
   static constexpr auto value = object("x", &T::x, "y", &T::y);
};
template <>
struct glz::meta<i2595::mimic_doc>
{
   using T = i2595::mimic_doc;
   static constexpr auto value = object("mid", &T::mid);
};
template <>
struct glz::meta<i2595::plain_pair>
{
   using T = i2595::plain_pair;
   static constexpr auto value = object("x", &T::x, "y", &T::y);
};
template <>
struct glz::meta<i2595::plain_doc>
{
   using T = i2595::plain_doc;
   static constexpr auto value = object("mid", &T::mid);
};
template <>
struct glz::meta<i2595::custom_obj>
{
   using T = i2595::custom_obj;
   static constexpr auto value = object("inner", glz::custom<&T::set_inner, &T::get_inner>);
};
template <>
struct glz::meta<i2595::plain_obj>
{
   using T = i2595::plain_obj;
   static constexpr auto value = object("inner", &T::inner);
};
template <>
struct glz::meta<i2595::custom_seq>
{
   using T = i2595::custom_seq;
   static constexpr auto value = object("items", glz::custom<&T::set_items, &T::get_items>);
};
template <>
struct glz::meta<i2595::plain_seq>
{
   using T = i2595::plain_seq;
   static constexpr auto value = object("items", &T::items);
};

suite issue_2595_transparent_wrappers = [] {
   using namespace i2595;

   "mimic nested objects match plain layout"_test = [] {
      mimic_doc w{};
      w.mid.x.v = {"asdf", 123};
      w.mid.y.v = {"qwer", 456};
      plain_doc p{};
      p.mid.x = {"asdf", 123};
      p.mid.y = {"qwer", 456};

      const auto ws = glz::write_yaml(w);
      const auto ps = glz::write_yaml(p);
      expect(ws.has_value());
      expect(ps.has_value());
      expect(ws.value() == ps.value()) << ws.value();

      mimic_doc r{};
      expect(not glz::read_yaml(r, ws.value()));
      expect(r.mid.x == w.mid.x);
      expect(r.mid.y == w.mid.y);
   };

   "custom getter object matches plain layout"_test = [] {
      custom_obj c{};
      c.inner = {"asdf", 123};
      plain_obj p{};
      p.inner = {"asdf", 123};

      const auto cs = glz::write_yaml(c);
      const auto ps = glz::write_yaml(p);
      expect(cs.has_value());
      expect(ps.has_value());
      expect(cs.value() == ps.value()) << cs.value();

      custom_obj r{};
      expect(not glz::read_yaml(r, cs.value()));
      expect(r == c);
   };

   "custom getter sequence matches plain layout"_test = [] {
      custom_seq c{};
      c.items = {{"a", 1}, {"b", 2}};
      plain_seq p{};
      p.items = {{"a", 1}, {"b", 2}};

      const auto cs = glz::write_yaml(c);
      const auto ps = glz::write_yaml(p);
      expect(cs.has_value());
      expect(ps.has_value());
      expect(cs.value() == ps.value()) << cs.value();

      custom_seq r{};
      expect(not glz::read_yaml(r, cs.value()));
      expect(r == c);
   };
};

struct skip_depth_probe
{
   int known{};
};

template <>
struct glz::meta<skip_depth_probe>
{
   using T = skip_depth_probe;
   static constexpr auto value = object("known", &T::known);
};

suite recursion_depth_tests = [] {
   "deeply nested flow sequence is bounded"_test = [] {
      const std::string yaml(100000, '[');
      glz::generic value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(ec.ec == glz::error_code::exceeded_max_recursive_depth);
   };

   "deeply nested flow mapping is bounded"_test = [] {
      const std::string yaml(100000, '{');
      glz::generic value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(ec.ec == glz::error_code::exceeded_max_recursive_depth);
   };

   "nesting within the limit still parses"_test = [] {
      const std::string yaml = "[1, 2, [3, [4, 5]]]";
      glz::generic value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      std::string json{};
      expect(!glz::write_json(value, json));
      expect(json == "[1,2,[3,[4,5]]]") << json;
   };

   "flow nesting at the depth limit boundary"_test = [] {
      // Pin the exact contract against the named constant: a generic value nested exactly to the
      // limit parses, one level deeper is rejected. The bracket-count-based deep tests above sit far
      // from the boundary and would not catch an off-by-one in the guard.
      constexpr size_t limit = glz::max_recursive_depth_limit;
      {
         const std::string yaml = std::string(limit, '[') + std::string(limit, ']');
         glz::generic value{};
         auto ec = glz::read_yaml(value, yaml);
         expect(!ec) << glz::format_error(ec, yaml);
      }
      {
         const std::string yaml = std::string(limit + 1, '[') + std::string(limit + 1, ']');
         glz::generic value{};
         auto ec = glz::read_yaml(value, yaml);
         expect(ec.ec == glz::error_code::exceeded_max_recursive_depth);
      }
   };

   "deeply nested value under a block mapping is bounded"_test = [] {
      // The deep flow tests above take the single-category direct branch and never touch the
      // speculative block-mapping probe (try_parse_block_mapping_into_variant -> make_speculative).
      // A block-mapping value routes through that probe; confirm the descent stays bounded there too.
      const std::string yaml = "k:\n  " + std::string(100000, '[');
      glz::generic value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(ec.ec == glz::error_code::exceeded_max_recursive_depth);
   };

   "block mapping value within the limit still parses"_test = [] {
      const std::string yaml = "k:\n  [1, [2, [3]]]";
      glz::generic value{};
      auto ec = glz::read_yaml(value, yaml);
      expect(!ec) << glz::format_error(ec, yaml);
      std::string json{};
      expect(!glz::write_json(value, json));
      expect(json == R"({"k":[1,[2,[3]]]})") << json;
   };

   "skipped alternating flow content is bounded"_test = [] {
      // Skipping an unknown key routes through skip_flow_content; alternating delimiters "[{[{..."
      // recurse one frame per delimiter (unlike same-delimiter nesting, which loops). The descent
      // must stay bounded rather than overflow the stack.
      std::string yaml = "unknown: ";
      for (int i = 0; i < 100000; ++i) yaml += "[{";
      yaml += "\nknown: 1";
      skip_depth_probe value{};
      auto ec = glz::read_yaml<glz::opts{.error_on_unknown_keys = false}>(value, yaml);
      expect(ec.ec == glz::error_code::exceeded_max_recursive_depth);
   };
};

int main() { return 0; }
