///|
/// A MoonBit-owned schema for the rkyv 0.8 default archive profile. It is a
/// small, explicit host-side alternative to the Rust layout derive. `Struct`
/// uses field order as its contract; generated Rust writers use `StructLayout`
/// with compiler-provided offsets and archived size instead.
pub(all) enum Schema {
  U8
  U16
  U32
  U64
  I8
  I16
  I32
  I64
  F32
  F64
  Bool
  String
  VecU32
  Vec(Schema)
  Option(Schema)
  Struct(Array[Field])
  StructLayout(Array[Field], Array[Int], Int)
  TaggedUnion(Array[Variant], Int, Int, Int)
}

///|
/// A named field in a host-defined archived struct.
pub(all) struct Field {
  name : String
  schema : Schema
}

///|
/// One variant in a host-defined `#[repr(u8)]` archived enum. `tag_offset`,
/// `payload_offset`, and `archived_size` are supplied by `TaggedUnion`, so the
/// union's native Rust layout is always an explicit part of the contract.
pub(all) struct Variant {
  name : String
  tag : Byte
  schema : Schema
}

///|
/// A dynamic value accepted by a `Schema` encoder.
pub(all) enum Value {
  U8(Byte)
  U16(UInt)
  U32(UInt)
  U64(UInt64)
  I8(Int)
  I16(Int)
  I32(Int)
  I64(Int64)
  F32(Float)
  F64(Double)
  Bool(Bool)
  String(String)
  VecU32(Array[UInt])
  Vec(Array[Value])
  Option(Value?)
  Struct(Array[ValueField])
  Tagged(Byte, Value?)
}

///|
/// A named field value. Names make accidental schema/value ordering mistakes
/// fail before any root archive object is written.
pub(all) struct ValueField {
  name : String
  value : Value
}

///|
/// Errors raised by the host schema encoder before it emits an invalid archive.
pub(all) suberror SchemaError {
  TypeMismatch(expected~ : String)
  FieldCountMismatch(expected~ : Int, actual~ : Int)
  FieldMismatch(expected~ : String, actual~ : String)
} derive(Debug, Eq)

///|
/// A schema-directed, zero-copy view over a host-defined archived value.
/// Field lookup stays dynamic because the schema is a MoonBit value rather than
/// source generated from Rust's compiler layout.
pub struct View {
  schema : Schema
  reader : Reader
  offset : Int
}

///|
/// A schema-directed mutable view over a caller-owned archive buffer. It can
/// update only fixed-width fields, so no relative pointer or collection length
/// can become invalid.
pub struct MutView {
  schema : Schema
  bytes : MutArrayView[Byte]
  offset : Int
}

///|
/// A mutable view of an existing `ArchivedVec`. It can replace elements
/// in place, but cannot change the vector length or move its data.
pub struct MutU32VecView {
  bytes : MutArrayView[Byte]
  data_offset : Int
  length : Int
}

///|
/// The size and alignment of one archived value under the default rkyv
/// profile. Struct offsets are retained so nested values can be written in one
/// contiguous root representation after their dependencies have been emitted.
priv struct SchemaLayout {
  size : Int
  alignment : Int
  field_offsets : Array[Int]
}

///|
/// An encoder-ready value. Out-of-line dependencies are emitted during
/// preparation, before the enclosing root representation is allocated.
priv enum PreparedValue {
  U8(Byte)
  U16(UInt)
  U32(UInt)
  U64(UInt64)
  I8(Int)
  I16(Int)
  I32(Int)
  I64(Int64)
  F32(Float)
  F64(Double)
  Bool(Bool)
  InlineString(Bytes)
  OutOfLineString(Int, Int)
  VecU32(Array[UInt], Int)
  Vec(Array[PreparedValue], Int)
  Option(PreparedValue?)
  Struct(Array[PreparedValue])
  Tagged(Byte, PreparedValue?)
}

///|
/// Rounds an offset up to an archive alignment boundary.
fn schema_align_up(offset : Int, alignment : Int) -> Int {
  if alignment <= 1 {
    offset
  } else {
    (offset + alignment - 1) / alignment * alignment
  }
}

///|
/// Computes the host-declared archived layout. `Struct` follows declaration
/// order, while `StructLayout` retains the exact offsets and archived size
/// supplied by Rust layout code generation.
fn Schema::layout(self : Schema) -> SchemaLayout {
  match self {
    Schema::U8 | Schema::I8 | Schema::Bool =>
      { size: 1, alignment: 1, field_offsets: [] }
    Schema::U16 | Schema::I16 => { size: 2, alignment: 2, field_offsets: [] }
    Schema::U32 => { size: 4, alignment: 4, field_offsets: [] }
    Schema::I32 | Schema::F32 => { size: 4, alignment: 4, field_offsets: [] }
    Schema::U64 | Schema::I64 | Schema::F64 =>
      { size: 8, alignment: 8, field_offsets: [] }
    Schema::String => { size: 8, alignment: 4, field_offsets: [] }
    Schema::VecU32 => { size: 8, alignment: 4, field_offsets: [] }
    Schema::Vec(_) => { size: 8, alignment: 4, field_offsets: [] }
    Schema::Option(value_schema) => {
      let value_layout = value_schema.layout()
      let value_offset = schema_align_up(1, value_layout.alignment)
      {
        size: schema_align_up(
          value_offset + value_layout.size,
          value_layout.alignment,
        ),
        alignment: value_layout.alignment,
        field_offsets: [],
      }
    }
    Schema::Struct(fields) => {
      let mut size = 0
      let mut alignment = 1
      let offsets : Array[Int] = []
      for field in fields {
        let field_layout = field.schema.layout()
        size = schema_align_up(size, field_layout.alignment)
        offsets.push(size)
        size = size + field_layout.size
        if field_layout.alignment > alignment {
          alignment = field_layout.alignment
        }
      }
      {
        size: schema_align_up(size, alignment),
        alignment,
        field_offsets: offsets,
      }
    }
    Schema::StructLayout(fields, offsets, archived_size) => {
      if fields.length() != offsets.length() {
        abort(
          "explicit host struct layout has a different field and offset count",
        )
      }
      if archived_size < 0 {
        abort("explicit host struct layout has a negative archived size")
      }
      let mut alignment = 1
      for index in 0.. archived_size {
          abort("explicit host struct field does not fit in its archived size")
        }
        if field_layout.alignment > alignment {
          alignment = field_layout.alignment
        }
      }
      { size: archived_size, alignment, field_offsets: offsets }
    }
    Schema::TaggedUnion(variants, tag_offset, payload_offset, archived_size) => {
      if tag_offset < 0 ||
        tag_offset >= archived_size ||
        payload_offset < 0 ||
        archived_size < 0 {
        abort("invalid explicit tagged union layout")
      }
      let mut alignment = 1
      for variant in variants {
        let payload_layout = variant.schema.layout()
        if payload_offset + payload_layout.size > archived_size {
          abort(
            "explicit tagged union payload does not fit in its archived size",
          )
        }
        if payload_layout.alignment > alignment {
          alignment = payload_layout.alignment
        }
      }
      { size: archived_size, alignment, field_offsets: [] }
    }
  }
}

///|
/// Writes zero bytes for archive padding or for an inline struct allocation.
fn schema_append_zeroes(out : Array[Byte], count : Int) -> Unit {
  for _ in 0.. Unit {
  out[offset] = (value & 0xffU).to_byte()
  out[offset + 1] = ((value >> 8) & 0xffU).to_byte()
  out[offset + 2] = ((value >> 16) & 0xffU).to_byte()
  out[offset + 3] = ((value >> 24) & 0xffU).to_byte()
}

///|
/// Writes a little-endian `u16` into an already allocated archive span.
fn schema_write_u16_le(out : Array[Byte], offset : Int, value : UInt) -> Unit {
  out[offset] = (value & 0xffU).to_byte()
  out[offset + 1] = ((value >> 8) & 0xffU).to_byte()
}

///|
/// Writes a little-endian `u64` into an already allocated archive span.
fn schema_write_u64_le(out : Array[Byte], offset : Int, value : UInt64) -> Unit {
  for index in 0..<8 {
    out[offset + index] = ((value >> (index * 8)) & 0xffUL).to_byte()
  }
}

///|
/// Writes a little-endian `u32` into a caller-owned mutable archive buffer.
fn schema_write_mut_u32_le(
  out : MutArrayView[Byte],
  offset : Int,
  value : UInt,
) -> Unit {
  out[offset] = (value & 0xffU).to_byte()
  out[offset + 1] = ((value >> 8) & 0xffU).to_byte()
  out[offset + 2] = ((value >> 16) & 0xffU).to_byte()
  out[offset + 3] = ((value >> 24) & 0xffU).to_byte()
}

///|
/// Writes a relative pointer using rkyv's little-endian i32 representation.
fn schema_write_rel_ptr(out : Array[Byte], offset : Int, target : Int) -> Unit {
  schema_write_u32_le(out, offset, (target - offset).reinterpret_as_uint())
}

///|
/// Emits dependencies recursively and returns the representation that will be
/// placed inside the final root object.
fn Schema::prepare(
  self : Schema,
  value : Value,
  out : Array[Byte],
) -> PreparedValue raise SchemaError {
  match self {
    Schema::U8 =>
      match value {
        Value::U8(value) => PreparedValue::U8(value)
        _ => raise SchemaError::TypeMismatch(expected="u8")
      }
    Schema::U16 =>
      match value {
        Value::U16(value) => PreparedValue::U16(value)
        _ => raise SchemaError::TypeMismatch(expected="u16")
      }
    Schema::U32 =>
      match value {
        Value::U32(value) => PreparedValue::U32(value)
        _ => raise SchemaError::TypeMismatch(expected="u32")
      }
    Schema::U64 =>
      match value {
        Value::U64(value) => PreparedValue::U64(value)
        _ => raise SchemaError::TypeMismatch(expected="u64")
      }
    Schema::I8 =>
      match value {
        Value::I8(value) => PreparedValue::I8(value)
        _ => raise SchemaError::TypeMismatch(expected="i8")
      }
    Schema::I16 =>
      match value {
        Value::I16(value) => PreparedValue::I16(value)
        _ => raise SchemaError::TypeMismatch(expected="i16")
      }
    Schema::I32 =>
      match value {
        Value::I32(value) => PreparedValue::I32(value)
        _ => raise SchemaError::TypeMismatch(expected="i32")
      }
    Schema::I64 =>
      match value {
        Value::I64(value) => PreparedValue::I64(value)
        _ => raise SchemaError::TypeMismatch(expected="i64")
      }
    Schema::F32 =>
      match value {
        Value::F32(value) => PreparedValue::F32(value)
        _ => raise SchemaError::TypeMismatch(expected="f32")
      }
    Schema::F64 =>
      match value {
        Value::F64(value) => PreparedValue::F64(value)
        _ => raise SchemaError::TypeMismatch(expected="f64")
      }
    Schema::Bool =>
      match value {
        Value::Bool(value) => PreparedValue::Bool(value)
        _ => raise SchemaError::TypeMismatch(expected="bool")
      }
    Schema::String =>
      match value {
        Value::String(value) => {
          let bytes = @utf8.encode(value)
          let length = bytes.length()
          if length <= 8 {
            PreparedValue::InlineString(bytes)
          } else {
            pad_to(out, 4)
            let data_offset = out.length()
            for index in 0.. raise SchemaError::TypeMismatch(expected="String")
      }
    Schema::VecU32 =>
      match value {
        Value::VecU32(values) => {
          pad_to(out, 4)
          let data_offset = out.length()
          for value in values {
            append_u32_le(out, value)
          }
          PreparedValue::VecU32(values, data_offset)
        }
        _ => raise SchemaError::TypeMismatch(expected="Vec")
      }
    Schema::Vec(element_schema) =>
      match value {
        Value::Vec(values) => {
          let prepared : Array[PreparedValue] = []
          for value in values {
            prepared.push(element_schema.prepare(value, out))
          }
          let element_layout = element_schema.layout()
          pad_to(out, element_layout.alignment)
          let data_offset = out.length()
          schema_append_zeroes(out, element_layout.size * prepared.length())
          PreparedValue::Vec(prepared, data_offset)
        }
        _ => raise SchemaError::TypeMismatch(expected="Vec")
      }
    Schema::Option(value_schema) =>
      match value {
        Value::Option(None) => PreparedValue::Option(None)
        Value::Option(Some(value)) =>
          PreparedValue::Option(Some(value_schema.prepare(value, out)))
        _ => raise SchemaError::TypeMismatch(expected="Option")
      }
    Schema::Struct(fields) | Schema::StructLayout(fields, _, _) =>
      match value {
        Value::Struct(values) => {
          let expected = fields.length()
          let actual = values.length()
          if expected != actual {
            raise SchemaError::FieldCountMismatch(expected~, actual~)
          }
          let prepared : Array[PreparedValue] = []
          for index in 0.. raise SchemaError::TypeMismatch(expected="struct")
      }
    Schema::TaggedUnion(variants, _, _, _) =>
      match value {
        Value::Tagged(tag, payload) => {
          let mut found : Variant? = None
          for variant in variants {
            if variant.tag == tag {
              found = Some(variant)
            }
          }
          match found {
            None =>
              raise SchemaError::TypeMismatch(
                expected="known tagged union variant",
              )
            Some(variant) =>
              match payload {
                None =>
                  if variant.schema.layout().size == 0 {
                    PreparedValue::Tagged(tag, None)
                  } else {
                    raise SchemaError::TypeMismatch(
                      expected="tagged union payload",
                    )
                  }
                Some(payload) =>
                  PreparedValue::Tagged(
                    tag,
                    Some(variant.schema.prepare(payload, out)),
                  )
              }
          }
        }
        _ => raise SchemaError::TypeMismatch(expected="tagged union")
      }
  }
}

///|
/// Fills one already allocated inline representation. The schema and prepared
/// value always originate from the same `prepare` call.
fn Schema::write_prepared(
  self : Schema,
  prepared : PreparedValue,
  out : Array[Byte],
  offset : Int,
) -> Unit {
  match self {
    Schema::U8 =>
      match prepared {
        PreparedValue::U8(value) => out[offset] = value
        _ => abort("host schema and prepared value diverged")
      }
    Schema::U16 =>
      match prepared {
        PreparedValue::U16(value) => schema_write_u16_le(out, offset, value)
        _ => abort("host schema and prepared value diverged")
      }
    Schema::U32 =>
      match prepared {
        PreparedValue::U32(value) => schema_write_u32_le(out, offset, value)
        _ => abort("host schema and prepared value diverged")
      }
    Schema::U64 =>
      match prepared {
        PreparedValue::U64(value) => schema_write_u64_le(out, offset, value)
        _ => abort("host schema and prepared value diverged")
      }
    Schema::I8 =>
      match prepared {
        PreparedValue::I8(value) =>
          out[offset] = value.reinterpret_as_uint().to_byte()
        _ => abort("host schema and prepared value diverged")
      }
    Schema::I16 =>
      match prepared {
        PreparedValue::I16(value) =>
          schema_write_u16_le(out, offset, value.reinterpret_as_uint())
        _ => abort("host schema and prepared value diverged")
      }
    Schema::I32 =>
      match prepared {
        PreparedValue::I32(value) =>
          schema_write_u32_le(out, offset, value.reinterpret_as_uint())
        _ => abort("host schema and prepared value diverged")
      }
    Schema::I64 =>
      match prepared {
        PreparedValue::I64(value) =>
          schema_write_u64_le(out, offset, value.reinterpret_as_uint64())
        _ => abort("host schema and prepared value diverged")
      }
    Schema::F32 =>
      match prepared {
        PreparedValue::F32(value) =>
          schema_write_u32_le(out, offset, value.reinterpret_as_uint())
        _ => abort("host schema and prepared value diverged")
      }
    Schema::F64 =>
      match prepared {
        PreparedValue::F64(value) =>
          schema_write_u64_le(out, offset, value.reinterpret_as_uint64())
        _ => abort("host schema and prepared value diverged")
      }
    Schema::Bool =>
      match prepared {
        PreparedValue::Bool(value) =>
          if value {
            out[offset] = b'\x01'
          } else {
            out[offset] = b'\x00'
          }
        _ => abort("host schema and prepared value diverged")
      }
    Schema::String =>
      match prepared {
        PreparedValue::InlineString(bytes) => {
          for index in 0..<8 {
            out[offset + index] = b'\xff'
          }
          for index in 0.. {
          let low_six_bits = length % 64
          let encoded_length = low_six_bits.reinterpret_as_uint() |
            0x80U |
            ((length - low_six_bits).reinterpret_as_uint() << 2)
          schema_write_u32_le(out, offset, encoded_length)
          schema_write_u32_le(
            out,
            offset + 4,
            (data_offset - offset).reinterpret_as_uint(),
          )
        }
        _ => abort("host schema and prepared value diverged")
      }
    Schema::VecU32 =>
      match prepared {
        PreparedValue::VecU32(values, data_offset) => {
          schema_write_rel_ptr(out, offset, data_offset)
          schema_write_u32_le(
            out,
            offset + 4,
            values.length().reinterpret_as_uint(),
          )
        }
        _ => abort("host schema and prepared value diverged")
      }
    Schema::Vec(element_schema) =>
      match prepared {
        PreparedValue::Vec(values, data_offset) => {
          schema_write_rel_ptr(out, offset, data_offset)
          schema_write_u32_le(
            out,
            offset + 4,
            values.length().reinterpret_as_uint(),
          )
          let element_layout = element_schema.layout()
          for index in 0.. abort("host schema and prepared value diverged")
      }
    Schema::Option(value_schema) =>
      match prepared {
        PreparedValue::Option(None) => out[offset] = b'\x00'
        PreparedValue::Option(Some(value)) => {
          out[offset] = b'\x01'
          let value_offset = schema_align_up(1, value_schema.layout().alignment)
          value_schema.write_prepared(value, out, offset + value_offset)
        }
        _ => abort("host schema and prepared value diverged")
      }
    Schema::Struct(fields) | Schema::StructLayout(fields, _, _) =>
      match prepared {
        PreparedValue::Struct(values) => {
          let layout = self.layout()
          for index in 0.. abort("host schema and prepared value diverged")
      }
    Schema::TaggedUnion(variants, tag_offset, payload_offset, _) =>
      match prepared {
        PreparedValue::Tagged(tag, payload) => {
          out[offset + tag_offset] = tag
          match payload {
            None => ()
            Some(payload) => {
              let mut found : Variant? = None
              for variant in variants {
                if variant.tag == tag {
                  found = Some(variant)
                }
              }
              match found {
                None => abort("prepared tagged union has an unknown tag")
                Some(variant) =>
                  variant.schema.write_prepared(
                    payload,
                    out,
                    offset + payload_offset,
                  )
              }
            }
          }
        }
        _ => abort("host schema and prepared value diverged")
      }
  }
}

///|
/// Encodes a host-defined value into a caller-owned mutable rkyv archive. This
/// function is target-independent, so `moon build --target js` produces the
/// same bytes without Rust.
pub fn Schema::encode_mut(
  self : Schema,
  value : Value,
) -> Array[Byte] raise SchemaError {
  let out : Array[Byte] = []
  let prepared = self.prepare(value, out)
  let layout = self.layout()
  pad_to(out, layout.alignment)
  let root_offset = out.length()
  schema_append_zeroes(out, layout.size)
  self.write_prepared(prepared, out, root_offset)
  out
}

///|
/// Encodes a value into an immutable rkyv archive. Use `encode_mut` when the
/// caller intends to apply later fixed-width in-place updates.
pub fn Schema::encode(self : Schema, value : Value) -> Bytes raise SchemaError {
  Bytes::from_array(self.encode_mut(value))
}

///|
/// Opens the root representation described by this host schema. The complete
/// inline span is validated immediately; out-of-line values are validated by
/// their respective reader accessors.
pub fn Schema::root(self : Schema, bytes : Bytes) -> View raise RkyvError {
  let reader = Reader::new(bytes)
  let layout = self.layout()
  let offset = reader.root_offset(layout.size)
  { schema: self, reader, offset }
}

///|
/// Fully validates a host-defined archive before it is exposed to an
/// application. This checks every reachable relative pointer, string, vector
/// extent, option tag, boolean discriminant, and tagged-union discriminant.
pub fn Schema::validate(self : Schema, bytes : Bytes) -> Unit raise RkyvError {
  let root = self.root(bytes)
  self.validate_at(root.reader, root.offset, 256)
}

///|
/// Validates one value at a known in-range inline archive offset.
fn Schema::validate_at(
  self : Schema,
  reader : Reader,
  offset : Int,
  remaining_depth : Int,
) -> Unit raise RkyvError {
  require_validation_depth(remaining_depth)
  match self {
    Schema::U8 => {
      let _ = reader.read_u8(offset)
    }
    Schema::U16 => {
      let _ = reader.read_u16(offset)
    }
    Schema::U32 => {
      let _ = reader.read_u32(offset)
    }
    Schema::U64 => {
      let _ = reader.read_u64(offset)
    }
    Schema::I8 => {
      let _ = reader.read_i8(offset)
    }
    Schema::I16 => {
      let _ = reader.read_i16(offset)
    }
    Schema::I32 => {
      let _ = reader.read_i32(offset)
    }
    Schema::I64 => {
      let _ = reader.read_i64(offset)
    }
    Schema::F32 => {
      let _ = reader.read_f32(offset)
    }
    Schema::F64 => {
      let _ = reader.read_f64(offset)
    }
    Schema::Bool => {
      let _ = reader.read_bool_strict(offset)
    }
    Schema::String => {
      let _ = reader.read_string(offset)
    }
    Schema::VecU32 => {
      let _ = reader.read_vec_u32(offset)
    }
    Schema::Vec(element_schema) => {
      let element_layout = element_schema.layout()
      let header = reader.read_vec_header_with_element_size(
        offset,
        element_layout.size,
      )
      for index in 0..
      match
        reader.read_option_value_offset_strict(
          offset,
          value_schema.layout().alignment,
        ) {
        None => ()
        Some(value_offset) =>
          value_schema.validate_at(reader, value_offset, remaining_depth - 1)
      }
    Schema::Struct(fields) | Schema::StructLayout(fields, _, _) => {
      let layout = self.layout()
      for index in 0.. {
      let tag = reader.read_u8(offset + tag_offset)
      let mut found : Variant? = None
      for variant in variants {
        if variant.tag == tag {
          found = Some(variant)
        }
      }
      match found {
        None => raise RkyvError::InvalidUnionTag(tag)
        Some(variant) =>
          variant.schema.validate_at(
            reader,
            offset + payload_offset,
            remaining_depth - 1,
          )
      }
    }
  }
}

///|
/// Opens a mutable root over caller-owned archive bytes. The inline root span
/// is validated before the view is returned; collection fields are additionally
/// validated when `vec_u32_mut` is requested.
pub fn Schema::root_mut(
  self : Schema,
  bytes : MutArrayView[Byte],
) -> MutView raise RkyvError {
  let reader = Reader::new(Bytes::from_array(bytes.view()))
  let layout = self.layout()
  let offset = reader.root_offset(layout.size)
  { schema: self, bytes, offset }
}

///|
/// Returns a nested struct field by name. `None` means this view is not a
/// struct or that the requested field does not exist in its host schema.
pub fn View::field(self : View, name : String) -> View? {
  match self.schema {
    Schema::Struct(fields) | Schema::StructLayout(fields, _, _) => {
      let layout = self.schema.layout()
      let mut found = None
      for index in 0.. None
  }
}

///|
/// Opens the present value of a host-defined `Option`. `None` means either
/// this view is not optional or the archived value is absent.
pub fn View::option_value(self : View) -> View? raise RkyvError {
  match self.schema {
    Schema::Option(value_schema) => {
      let value_layout = value_schema.layout()
      match
        self.reader.read_option_value_offset(
          self.offset,
          value_layout.alignment,
        ) {
        None => None
        Some(offset) =>
          Some({ schema: value_schema, reader: self.reader, offset })
      }
    }
    _ => None
  }
}

///|
/// Reads an explicit tagged-union discriminant without resolving its payload.
pub fn View::read_tag(self : View) -> Byte? raise RkyvError {
  match self.schema {
    Schema::TaggedUnion(_, tag_offset, _, _) =>
      Some(self.reader.read_u8(self.offset + tag_offset))
    _ => None
  }
}

///|
/// Opens the active explicit tagged-union payload. Unknown tags are rejected
/// rather than treated as absent, which keeps untrusted validation strict.
pub fn View::tagged_value(self : View) -> View? raise RkyvError {
  match self.schema {
    Schema::TaggedUnion(variants, tag_offset, payload_offset, _) => {
      let tag = self.reader.read_u8(self.offset + tag_offset)
      let mut found : Variant? = None
      for variant in variants {
        if variant.tag == tag {
          found = Some(variant)
        }
      }
      match found {
        None => raise RkyvError::InvalidUnionTag(tag)
        Some(variant) =>
          if variant.schema.layout().size == 0 {
            None
          } else {
            Some({
              schema: variant.schema,
              reader: self.reader,
              offset: self.offset + payload_offset,
            })
          }
      }
    }
    _ => None
  }
}

///|
/// Returns a nested mutable struct field by name. `None` means this view is
/// not a struct or that the requested field does not exist.
pub fn MutView::field(self : MutView, name : String) -> MutView? {
  match self.schema {
    Schema::Struct(fields) | Schema::StructLayout(fields, _, _) => {
      let layout = self.schema.layout()
      let mut found = None
      for index in 0.. None
  }
}

///|
/// Replaces a `u32` field in place. Returns `false` if this view's schema is
/// not `Schema::U32`.
pub fn MutView::set_u32(self : MutView, value : UInt) -> Bool {
  match self.schema {
    Schema::U32 => {
      schema_write_mut_u32_le(self.bytes, self.offset, value)
      true
    }
    _ => false
  }
}

///|
/// Replaces a boolean field in place. Returns `false` if this view's schema is
/// not `Schema::Bool`.
pub fn MutView::set_bool(self : MutView, value : Bool) -> Bool {
  match self.schema {
    Schema::Bool => {
      self.bytes[self.offset] = if value { b'\x01' } else { b'\x00' }
      true
    }
    _ => false
  }
}

///|
/// Replaces a string only when its UTF-8 byte length is unchanged. The archive
/// representation, relative pointer, and inline/out-of-line choice therefore
/// remain valid. Returns `false` for a different-length string or a non-string
/// schema; malformed archived strings raise `RkyvError` before any write.
pub fn MutView::set_string(
  self : MutView,
  value : String,
) -> Bool raise RkyvError {
  match self.schema {
    Schema::String => {
      let snapshot = Bytes::from_array(self.bytes.view())
      let reader = Reader::new(snapshot)
      let current = reader.read_string(self.offset)
      let replacement = @utf8.encode(value)
      if replacement.length() != @utf8.encode(current).length() {
        false
      } else {
        let first = self.bytes[self.offset].to_int()
        let data_offset = if (first & 0xc0) != 0x80 {
          self.offset
        } else {
          self.offset + reader.read_rel_ptr_offset(self.offset + 4)
        }
        for index in 0.. false
  }
}

///|
/// Opens a mutable view of an existing `Vec`. The header and full element
/// span are checked before returning the view. The snapshot used for validation
/// is discarded; writes always target the caller-owned mutable buffer.
pub fn MutView::vec_u32_mut(self : MutView) -> MutU32VecView? raise RkyvError {
  match self.schema {
    Schema::VecU32 => {
      let reader = Reader::new(Bytes::from_array(self.bytes.view()))
      let view = reader.read_vec_u32(self.offset)
      Some({
        bytes: self.bytes,
        data_offset: view.data_offset,
        length: view.length,
      })
    }
    _ => None
  }
}

///|
/// Returns the fixed archived element count of this mutable vector view.
pub fn MutU32VecView::length(self : MutU32VecView) -> Int {
  self.length
}

///|
/// Replaces one existing vector element in place. Returns `false` for an
/// out-of-range index; this API never resizes or relocates the vector.
pub fn MutU32VecView::set(
  self : MutU32VecView,
  index : Int,
  value : UInt,
) -> Bool {
  if index < 0 || index >= self.length {
    false
  } else {
    schema_write_mut_u32_le(self.bytes, self.data_offset + index * 4, value)
    true
  }
}

///|
/// Reads a `u8` when this view's schema is `Schema::U8`.
pub fn View::read_u8(self : View) -> Byte? raise RkyvError {
  match self.schema {
    Schema::U8 => Some(self.reader.read_u8(self.offset))
    _ => None
  }
}

///|
/// Reads a `u16` when this view's schema is `Schema::U16`.
pub fn View::read_u16(self : View) -> UInt? raise RkyvError {
  match self.schema {
    Schema::U16 => Some(self.reader.read_u16(self.offset))
    _ => None
  }
}

///|
/// Reads a `u32` when this view's schema is `Schema::U32`.
pub fn View::read_u32(self : View) -> UInt? raise RkyvError {
  match self.schema {
    Schema::U32 => Some(self.reader.read_u32(self.offset))
    _ => None
  }
}

///|
/// Reads a `u64` when this view's schema is `Schema::U64`.
pub fn View::read_u64(self : View) -> UInt64? raise RkyvError {
  match self.schema {
    Schema::U64 => Some(self.reader.read_u64(self.offset))
    _ => None
  }
}

///|
/// Reads an `i8` when this view's schema is `Schema::I8`.
pub fn View::read_i8(self : View) -> Int? raise RkyvError {
  match self.schema {
    Schema::I8 => Some(self.reader.read_i8(self.offset))
    _ => None
  }
}

///|
/// Reads an `i16` when this view's schema is `Schema::I16`.
pub fn View::read_i16(self : View) -> Int? raise RkyvError {
  match self.schema {
    Schema::I16 => Some(self.reader.read_i16(self.offset))
    _ => None
  }
}

///|
/// Reads an `i32` when this view's schema is `Schema::I32`.
pub fn View::read_i32(self : View) -> Int? raise RkyvError {
  match self.schema {
    Schema::I32 => Some(self.reader.read_i32(self.offset))
    _ => None
  }
}

///|
/// Reads an `i64` when this view's schema is `Schema::I64`.
pub fn View::read_i64(self : View) -> Int64? raise RkyvError {
  match self.schema {
    Schema::I64 => Some(self.reader.read_i64(self.offset))
    _ => None
  }
}

///|
/// Reads an `f32` when this view's schema is `Schema::F32`.
pub fn View::read_f32(self : View) -> Float? raise RkyvError {
  match self.schema {
    Schema::F32 => Some(self.reader.read_f32(self.offset))
    _ => None
  }
}

///|
/// Reads an `f64` when this view's schema is `Schema::F64`.
pub fn View::read_f64(self : View) -> Double? raise RkyvError {
  match self.schema {
    Schema::F64 => Some(self.reader.read_f64(self.offset))
    _ => None
  }
}

///|
/// Reads a boolean when this view's schema is `Schema::Bool`.
pub fn View::read_bool(self : View) -> Bool? raise RkyvError {
  match self.schema {
    Schema::Bool => Some(self.reader.read_bool(self.offset))
    _ => None
  }
}

///|
/// Reads a string when this view's schema is `Schema::String`.
pub fn View::read_string(self : View) -> String? raise RkyvError {
  match self.schema {
    Schema::String => Some(self.reader.read_string(self.offset))
    _ => None
  }
}

///|
/// Opens a zero-copy `ArchivedVec` view when this schema declares one.
pub fn View::read_vec_u32(self : View) -> U32VecView? raise RkyvError {
  match self.schema {
    Schema::VecU32 | Schema::Vec(Schema::U32) =>
      Some(self.reader.read_vec_u32(self.offset))
    _ => None
  }
}

///|
/// Materializes a generic `ArchivedVec` after validating its complete
/// span. The dedicated lazy `U32VecView` remains available for the hot u32
/// path; other primitive vectors favor a compact general implementation.
pub fn View::read_vec_i16(self : View) -> Array[Int]? raise RkyvError {
  match self.schema {
    Schema::Vec(Schema::I16) => {
      let header = self.reader.read_vec_header_with_element_size(self.offset, 2)
      let values : Array[Int] = []
      for index in 0.. None
  }
}

///|
/// Materializes a generic `ArchivedVec` after validating its complete
/// span. It is useful for host-side inspection and test conformance; generated
/// bindings use lazy per-field views for all primitive vectors.
pub fn View::read_vec_u64(self : View) -> Array[UInt64]? raise RkyvError {
  match self.schema {
    Schema::Vec(Schema::U64) => {
      let header = self.reader.read_vec_header_with_element_size(self.offset, 8)
      let values : Array[UInt64] = []
      for index in 0.. None
  }
}