Rebrand TypeDef to AlkType in code, keyword strings, and docs

Rename all 19 JSON Schema custom keyword strings from "TypeDef:*"
to "AlkType:*" (e.g., "TypeDef:Struct" -> "AlkType:Struct")
across source, tests, and docs. This is a breaking change to the
schema format itself — existing schemas using the old keywords
must be updated.

Rename the Rust identifiers:
- TypedefEngine -> AlkTypeEngine
- TypedefError -> AlkTypeError
- TypeDefKind -> AlkTypeKind
- TYPEDEF_PREFIX -> ALKTYPE_PREFIX
- get_typedef_kind{,_loose,_loose_enum,_enum} ->
  get_alktype_kind{,_loose,_loose_enum,_enum}

Update error message strings ("unknown TypeDef kind" ->
"unknown AlkType kind"), 11 test function names containing
typedef_kind/to_typedef_error, and doc-comment prose ("TypeDef
kind" -> "AlkType kind", "typedef engine" -> "alktype
engine", "typedef schema" -> "alktype schema"). Fix the broken
docs/architecture/crates/typedef/ path references in source doc
comments to point at docs/architecture/ directly. Rebrand the
typedef:annotation test fixture and the "not-a-typedef" test
string to their alktype equivalents.

Update ~20 generic "typedef" prose references in the architecture
docs ("typedef is the binary struct engine", "use typedef",
"typedef limitation", "replaced by typedef", etc.) to alktype.
Rename TypedefEngine in the ADR-007 code example to AlkTypeEngine.

Preserve as provenance per the prior prose-rebrand decision:
typedef.ts references (external TypeBox source file),
docs/research/alknet-typedef/findings.md research citations,
/workspace/alknet-typedef-poc/ POC path, and the
"alknet-typedef:" research section headers in findings.

Build, 295 tests, and clippy all pass clean.
This commit is contained in:
glm-5.2 committed 2026-08-02 07:05:53 +00:00
1 parent 1cfb3638d1
commit 5e268e8f47
31 files changed
+1851 -1851

No files matched your search

+137 -137
View File
@@ -1,19 +1,19 @@
//! `TypedefEngine` — the compiled form of a schema.
//! `AlkTypeEngine` — the compiled form of a schema.
//!
//! Combines the layout engine (both packed and aligned modes) and the
//! jsonschema validator into a single struct. Built once at schema load
//! time via [`TypedefEngine::compile`]. Used for repeated read/write/
//! time via [`AlkTypeEngine::compile`]. Used for repeated read/write/
//! validate operations at access time.
//!
//! See [validation.md](../../docs/architecture/crates/typedef/validation.md)
//! §"The TypedefEngine struct" and
//! [overview.md](../../docs/architecture/crates/typedef/overview.md).
//! See [validation.md](../../docs/architecture/validation.md)
//! §"The AlkTypeEngine struct" and
//! [overview.md](../../docs/architecture/overview.md).
use crate::data_access;
use crate::error::TypedefError;
use crate::error::AlkTypeError;
use crate::layout_builder::LayoutBuilder;
use crate::offset_map::OffsetMap;
use crate::schema::{self, get_typedef_kind_loose_enum, Endian, TypeDefKind};
use crate::schema::{self, get_alktype_kind_loose_enum, Endian, AlkTypeKind};
use crate::sequential_reader::{FieldValue, SequentialReader};
use crate::validation;
use serde_json::Value;
@@ -32,7 +32,7 @@ pub enum LayoutMode {
///
/// Carries the layout-specific handles needed for read/write access in
/// the selected mode. The consumer chooses the mode at construction time
/// via [`TypedefEngine::compile`]; the engine then exposes only the
/// via [`AlkTypeEngine::compile`]; the engine then exposes only the
/// APIs that make sense for that mode.
#[derive(Debug)]
enum Layout {
@@ -48,26 +48,26 @@ enum Layout {
Aligned { offset_map: OffsetMap },
}
/// The compiled form of a typedef schema. Combines the layout engine
/// The compiled form of a alktype schema. Combines the layout engine
/// (both packed and aligned modes) and the jsonschema validator.
///
/// Built once at schema load time via [`TypedefEngine::compile`].
/// Built once at schema load time via [`AlkTypeEngine::compile`].
/// Used for repeated read/write/validate operations at access time.
///
/// The consumer selects the layout mode at construction time. The engine
/// then exposes mode-appropriate accessors: [`TypedefEngine::offset_map`]
/// for aligned mode, [`TypedefEngine::layout_builder`] and
/// [`TypedefEngine::sequential_reader`] for packed mode. The
/// then exposes mode-appropriate accessors: [`AlkTypeEngine::offset_map`]
/// for aligned mode, [`AlkTypeEngine::layout_builder`] and
/// [`AlkTypeEngine::sequential_reader`] for packed mode. The
/// jsonschema validator is mode-agnostic and always available.
pub struct TypedefEngine {
pub struct AlkTypeEngine {
layout: Layout,
validator: jsonschema::Validator,
endian: Endian,
schema: Value,
}
impl TypedefEngine {
/// Compile a schema into a [`TypedefEngine`].
impl AlkTypeEngine {
/// Compile a schema into a [`AlkTypeEngine`].
///
/// This is the expensive operation — it parses the schema, normalizes
/// `$ref` values, computes the layout, and builds the jsonschema
@@ -79,11 +79,11 @@ impl TypedefEngine {
///
/// # Errors
///
/// Returns [`TypedefError::Schema`] if the schema is malformed or the
/// Returns [`AlkTypeError::Schema`] if the schema is malformed or the
/// underlying layout/validator construction fails. The error is
/// propagated from [`LayoutBuilder::new`], [`SequentialReader::new`],
/// [`OffsetMap::compute`], or [`validation::build_validator`].
pub fn compile(schema: &mut Value, mode: LayoutMode) -> Result<Self, TypedefError> {
pub fn compile(schema: &mut Value, mode: LayoutMode) -> Result<Self, AlkTypeError> {
schema::normalize_refs(schema);
let endian = Endian::from_schema(schema);
let layout = match mode {
@@ -152,12 +152,12 @@ impl TypedefEngine {
/// Validate a JSON value against the schema. The jsonschema validator
/// is already compiled — this is a fast check.
///
/// Returns `Ok(())` if valid, `Err(TypedefError::Validation(...))` if
/// Returns `Ok(())` if valid, `Err(AlkTypeError::Validation(...))` if
/// invalid.
pub fn validate_json(&self, instance: &Value) -> Result<(), TypedefError> {
pub fn validate_json(&self, instance: &Value) -> Result<(), AlkTypeError> {
self.validator
.validate(instance)
.map_err(|e| TypedefError::Validation(e.to_owned()))
.map_err(|e| AlkTypeError::Validation(e.to_owned()))
}
/// Check if a JSON value is valid against the schema.
@@ -173,25 +173,25 @@ impl TypedefEngine {
/// `Bytes`/`Timestamp` fields.
///
/// Returns an error if compiled in packed mode — use
/// [`TypedefEngine::sequential_reader`] for packed mode. Also
/// [`AlkTypeEngine::sequential_reader`] for packed mode. Also
/// returns an error for composite kinds (`Struct`, `Union`, `Array`,
/// `Record`) — those are better handled via the layout-specific APIs.
///
/// # Errors
///
/// - [`TypedefError::Access`] if compiled in packed mode.
/// - [`TypedefError::Offset`] if `field_path` is not in the offset map.
/// - [`TypedefError::Access`] for buffer-too-short or invalid data,
/// - [`AlkTypeError::Access`] if compiled in packed mode.
/// - [`AlkTypeError::Offset`] if `field_path` is not in the offset map.
/// - [`AlkTypeError::Access`] for buffer-too-short or invalid data,
/// propagated from [`crate::data_access`].
pub fn read_field<'a>(
&self,
buffer: &'a [u8],
field_path: &str,
) -> Result<FieldValue<'a>, TypedefError> {
) -> Result<FieldValue<'a>, AlkTypeError> {
let offset_map = match &self.layout {
Layout::Aligned { offset_map } => offset_map,
Layout::Packed { .. } => {
return Err(TypedefError::Access {
return Err(AlkTypeError::Access {
field_path: field_path.to_string(),
reason: "read_field is only available in aligned mode; \
use sequential_reader() for packed mode"
@@ -201,87 +201,87 @@ impl TypedefEngine {
};
let range = offset_map
.get(field_path)
.ok_or_else(|| TypedefError::Offset {
.ok_or_else(|| AlkTypeError::Offset {
field_path: field_path.to_string(),
reason: "field not found in offset map".to_string(),
})?;
let field_schema =
lookup_field_schema(&self.schema, field_path).ok_or_else(|| TypedefError::Offset {
lookup_field_schema(&self.schema, field_path).ok_or_else(|| AlkTypeError::Offset {
field_path: field_path.to_string(),
reason: "field schema not found in schema tree".to_string(),
})?;
let kind = get_typedef_kind_loose_enum(field_schema).ok_or_else(|| TypedefError::Offset {
let kind = get_alktype_kind_loose_enum(field_schema).ok_or_else(|| AlkTypeError::Offset {
field_path: field_path.to_string(),
reason: "field schema has no TypeDef:* kind".to_string(),
reason: "field schema has no AlkType:* kind".to_string(),
})?;
let endian = self.endian;
match kind {
TypeDefKind::Int8 => {
AlkTypeKind::Int8 => {
let v = data_access::read_i8(buffer, range.start, field_path)?;
Ok(FieldValue::I8(v))
}
TypeDefKind::Int16 => {
AlkTypeKind::Int16 => {
let v = data_access::read_i16(buffer, range.start, field_path, endian)?;
Ok(FieldValue::I16(v))
}
TypeDefKind::Int32 => {
AlkTypeKind::Int32 => {
let v = data_access::read_i32(buffer, range.start, field_path, endian)?;
Ok(FieldValue::I32(v))
}
TypeDefKind::Int64 => {
AlkTypeKind::Int64 => {
let v = data_access::read_i64(buffer, range.start, field_path, endian)?;
Ok(FieldValue::I64(v))
}
TypeDefKind::Uint8 => {
AlkTypeKind::Uint8 => {
let v = data_access::read_u8(buffer, range.start, field_path)?;
Ok(FieldValue::U8(v))
}
TypeDefKind::Uint16 => {
AlkTypeKind::Uint16 => {
let v = data_access::read_u16(buffer, range.start, field_path, endian)?;
Ok(FieldValue::U16(v))
}
TypeDefKind::Uint32 => {
AlkTypeKind::Uint32 => {
let v = data_access::read_u32(buffer, range.start, field_path, endian)?;
Ok(FieldValue::U32(v))
}
TypeDefKind::Uint64 => {
AlkTypeKind::Uint64 => {
let v = data_access::read_u64(buffer, range.start, field_path, endian)?;
Ok(FieldValue::U64(v))
}
TypeDefKind::Float32 => {
AlkTypeKind::Float32 => {
let v = data_access::read_f32(buffer, range.start, field_path, endian)?;
Ok(FieldValue::F32(v))
}
TypeDefKind::Float64 => {
AlkTypeKind::Float64 => {
let v = data_access::read_f64(buffer, range.start, field_path, endian)?;
Ok(FieldValue::F64(v))
}
TypeDefKind::Boolean => {
AlkTypeKind::Boolean => {
let v = data_access::read_bool(buffer, range.start, field_path)?;
Ok(FieldValue::Bool(v))
}
TypeDefKind::Enum => {
AlkTypeKind::Enum => {
let v = data_access::read_enum(buffer, range.start, field_path, endian)?;
Ok(FieldValue::Enum(v))
}
TypeDefKind::String => {
AlkTypeKind::String => {
let v = data_access::read_string(buffer, range.start, field_path, endian)?;
Ok(FieldValue::String(v))
}
TypeDefKind::Bytes => {
AlkTypeKind::Bytes => {
let v = data_access::read_bytes(buffer, range.start, field_path, endian)?;
Ok(FieldValue::Bytes(v))
}
TypeDefKind::Timestamp => {
AlkTypeKind::Timestamp => {
let v = data_access::read_string(buffer, range.start, field_path, endian)?;
Ok(FieldValue::String(v))
}
TypeDefKind::Struct => Ok(FieldValue::Struct {
AlkTypeKind::Struct => Ok(FieldValue::Struct {
start: range.start,
end: range.end,
}),
TypeDefKind::Union | TypeDefKind::Array | TypeDefKind::Record => {
Err(TypedefError::Access {
AlkTypeKind::Union | AlkTypeKind::Array | AlkTypeKind::Record => {
Err(AlkTypeError::Access {
field_path: field_path.to_string(),
reason: "read_field does not support composite types; \
use the layout-specific APIs"
@@ -299,25 +299,25 @@ impl TypedefEngine {
/// `Bytes`/`Timestamp` fields.
///
/// Returns an error if compiled in packed mode — use
/// [`TypedefEngine::layout_builder`] for packed mode. Also returns an
/// [`AlkTypeEngine::layout_builder`] for packed mode. Also returns an
/// error for composite kinds (`Struct`, `Union`, `Array`, `Record`).
///
/// # Errors
///
/// - [`TypedefError::Access`] if compiled in packed mode.
/// - [`TypedefError::Offset`] if `field_path` is not in the offset map.
/// - [`TypedefError::Access`] for buffer-too-short or invalid data,
/// - [`AlkTypeError::Access`] if compiled in packed mode.
/// - [`AlkTypeError::Offset`] if `field_path` is not in the offset map.
/// - [`AlkTypeError::Access`] for buffer-too-short or invalid data,
/// propagated from [`crate::data_access`].
pub fn write_field(
&self,
buffer: &mut [u8],
field_path: &str,
value: &FieldValue<'_>,
) -> Result<(), TypedefError> {
) -> Result<(), AlkTypeError> {
let offset_map = match &self.layout {
Layout::Aligned { offset_map } => offset_map,
Layout::Packed { .. } => {
return Err(TypedefError::Access {
return Err(AlkTypeError::Access {
field_path: field_path.to_string(),
reason: "write_field is only available in aligned mode; \
use layout_builder() for packed mode"
@@ -327,7 +327,7 @@ impl TypedefEngine {
};
let range = offset_map
.get(field_path)
.ok_or_else(|| TypedefError::Offset {
.ok_or_else(|| AlkTypeError::Offset {
field_path: field_path.to_string(),
reason: "field not found in offset map".to_string(),
})?;
@@ -372,7 +372,7 @@ impl TypedefEngine {
Ok(())
}
FieldValue::Struct { .. } | FieldValue::Union { .. } | FieldValue::Array { .. } => {
Err(TypedefError::Access {
Err(AlkTypeError::Access {
field_path: field_path.to_string(),
reason: "write_field does not support composite types; \
use the layout-specific APIs"
@@ -383,9 +383,9 @@ impl TypedefEngine {
}
}
impl fmt::Debug for TypedefEngine {
impl fmt::Debug for AlkTypeEngine {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("TypedefEngine")
f.debug_struct("AlkTypeEngine")
.field("layout", &self.layout)
.field("validator", &"<jsonschema::Validator>")
.field("endian", &self.endian)
@@ -416,13 +416,13 @@ mod tests {
fn fixed_struct_schema() -> Value {
json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"endian": "little",
"properties": {
"flag": { "TypeDef:Uint8": true },
"id": { "TypeDef:Uint32": true },
"score": { "TypeDef:Float32": true },
"tag": { "TypeDef:String": true }
"flag": { "AlkType:Uint8": true },
"id": { "AlkType:Uint32": true },
"score": { "AlkType:Float32": true },
"tag": { "AlkType:String": true }
}
})
}
@@ -430,7 +430,7 @@ mod tests {
#[test]
fn compile_aligned_builds_offset_map() {
let mut schema = fixed_struct_schema();
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
assert_eq!(engine.mode(), LayoutMode::Aligned);
assert!(engine.offset_map().is_some());
assert!(engine.layout_builder().is_none());
@@ -440,7 +440,7 @@ mod tests {
#[test]
fn compile_packed_builds_builder_and_reader() {
let mut schema = fixed_struct_schema();
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
assert_eq!(engine.mode(), LayoutMode::Packed);
assert!(engine.layout_builder().is_some());
assert!(engine.sequential_reader().is_some());
@@ -450,18 +450,18 @@ mod tests {
#[test]
fn compile_normalizes_refs() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"child": { "$ref": "Child" }
},
"$defs": {
"Child": {
"TypeDef:Struct": true,
"properties": { "x": { "TypeDef:Uint8": true } }
"AlkType:Struct": true,
"properties": { "x": { "AlkType:Uint8": true } }
}
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
assert_eq!(
engine.schema["properties"]["child"]["$ref"],
json!("#/$defs/Child")
@@ -471,64 +471,64 @@ mod tests {
#[test]
fn endian_parsed_from_schema() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"endian": "big",
"properties": { "id": { "TypeDef:Uint32": true } }
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
assert_eq!(engine.endian(), Endian::Big);
}
#[test]
fn endian_defaults_to_little() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
assert_eq!(engine.endian(), Endian::Little);
}
#[test]
fn validate_json_accepts_valid_instance() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"type": "object",
"properties": {
"id": { "TypeDef:Uint32": true, "type": "integer" }
"id": { "AlkType:Uint32": true, "type": "integer" }
},
"required": ["id"]
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
assert!(engine.validate_json(&json!({"id": 42})).is_ok());
}
#[test]
fn validate_json_rejects_invalid_instance() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"type": "object",
"properties": {
"id": { "TypeDef:Uint32": true, "type": "integer" }
"id": { "AlkType:Uint32": true, "type": "integer" }
},
"required": ["id"]
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let err = engine.validate_json(&json!({"id": -1})).unwrap_err();
assert!(matches!(err, TypedefError::Validation(_)), "got {err:?}");
assert!(matches!(err, AlkTypeError::Validation(_)), "got {err:?}");
}
#[test]
fn is_valid_json_returns_bool() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"type": "object",
"properties": {
"id": { "TypeDef:Uint32": true, "type": "integer" }
"id": { "AlkType:Uint32": true, "type": "integer" }
},
"required": ["id"]
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
assert!(engine.is_valid_json(&json!({"id": 42})));
assert!(!engine.is_valid_json(&json!({"id": -1})));
}
@@ -536,14 +536,14 @@ mod tests {
#[test]
fn read_field_aligned_reads_fixed_fields() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"endian": "little",
"properties": {
"flag": { "TypeDef:Uint8": true },
"id": { "TypeDef:Uint32": true }
"flag": { "AlkType:Uint8": true },
"id": { "AlkType:Uint32": true }
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = vec![0u8; 8];
buf[0] = 0xAB;
buf[4..8].copy_from_slice(&0x01020304u32.to_le_bytes());
@@ -560,12 +560,12 @@ mod tests {
#[test]
fn read_field_aligned_reads_string_length_prefixed() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"name": { "TypeDef:String": true }
"name": { "AlkType:String": true }
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = vec![0u8; 32];
let len_bytes = 5u32.to_le_bytes();
buf[0..4].copy_from_slice(&len_bytes);
@@ -579,55 +579,55 @@ mod tests {
#[test]
fn read_field_returns_access_error_in_packed_mode() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let buf = [0u8; 4];
let err = engine.read_field(&buf, "id").unwrap_err();
assert!(matches!(err, TypedefError::Access { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Access { .. }), "got {err:?}");
}
#[test]
fn read_field_returns_offset_error_for_missing_field() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let buf = [0u8; 4];
let err = engine.read_field(&buf, "missing").unwrap_err();
assert!(matches!(err, TypedefError::Offset { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Offset { .. }), "got {err:?}");
}
#[test]
fn read_field_returns_error_for_composite_types() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"vals": {
"TypeDef:Array": true,
"items": { "TypeDef:Uint32": true }
"AlkType:Array": true,
"items": { "AlkType:Uint32": true }
}
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let buf = [0u8; 8];
let err = engine.read_field(&buf, "vals").unwrap_err();
assert!(matches!(err, TypedefError::Access { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Access { .. }), "got {err:?}");
}
#[test]
fn write_field_aligned_writes_fixed_fields() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"endian": "little",
"properties": {
"flag": { "TypeDef:Uint8": true },
"id": { "TypeDef:Uint32": true }
"flag": { "AlkType:Uint8": true },
"id": { "AlkType:Uint32": true }
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = vec![0u8; 8];
engine
.write_field(&mut buf, "flag", &FieldValue::U8(0xAB))
@@ -650,12 +650,12 @@ mod tests {
#[test]
fn write_field_round_trips_string() {
let mut schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"name": { "TypeDef:String": true }
"name": { "AlkType:String": true }
}
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = vec![0u8; 32];
engine
.write_field(&mut buf, "name", &FieldValue::String("hello"))
@@ -669,86 +669,86 @@ mod tests {
#[test]
fn write_field_returns_access_error_in_packed_mode() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).expect("compile");
let mut buf = [0u8; 4];
let err = engine
.write_field(&mut buf, "id", &FieldValue::U32(1))
.unwrap_err();
assert!(matches!(err, TypedefError::Access { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Access { .. }), "got {err:?}");
}
#[test]
fn write_field_returns_offset_error_for_missing_field() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = [0u8; 4];
let err = engine
.write_field(&mut buf, "missing", &FieldValue::U32(1))
.unwrap_err();
assert!(matches!(err, TypedefError::Offset { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Offset { .. }), "got {err:?}");
}
#[test]
fn write_field_returns_error_for_composite_value() {
let mut schema = json!({
"TypeDef:Struct": true,
"properties": { "id": { "TypeDef:Uint32": true } }
"AlkType:Struct": true,
"properties": { "id": { "AlkType:Uint32": true } }
});
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let mut buf = [0u8; 8];
let err = engine
.write_field(&mut buf, "id", &FieldValue::Struct { start: 0, end: 4 })
.unwrap_err();
assert!(matches!(err, TypedefError::Access { .. }), "got {err:?}");
assert!(matches!(err, AlkTypeError::Access { .. }), "got {err:?}");
}
#[test]
fn compile_returns_schema_error_for_invalid_top_level() {
let mut schema = json!({ "type": "object", "properties": {} });
let err = TypedefEngine::compile(&mut schema, LayoutMode::Packed).unwrap_err();
assert!(matches!(err, TypedefError::Schema(_)), "got {err:?}");
let err = AlkTypeEngine::compile(&mut schema, LayoutMode::Packed).unwrap_err();
assert!(matches!(err, AlkTypeError::Schema(_)), "got {err:?}");
}
#[test]
fn debug_formats_without_panicking() {
let mut schema = fixed_struct_schema();
let engine = TypedefEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let engine = AlkTypeEngine::compile(&mut schema, LayoutMode::Aligned).expect("compile");
let s = format!("{engine:?}");
assert!(s.contains("TypedefEngine"));
assert!(s.contains("AlkTypeEngine"));
assert!(s.contains("Aligned"));
}
#[test]
fn lookup_field_schema_walks_dotted_path() {
let schema = json!({
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"header": {
"TypeDef:Struct": true,
"AlkType:Struct": true,
"properties": {
"version": { "TypeDef:Uint8": true }
"version": { "AlkType:Uint8": true }
}
}
}
});
let node = lookup_field_schema(&schema, "header.version").expect("found");
assert_eq!(node, &json!({ "TypeDef:Uint8": true }));
assert_eq!(node, &json!({ "AlkType:Uint8": true }));
assert!(lookup_field_schema(&schema, "header.missing").is_none());
assert!(lookup_field_schema(&schema, "missing").is_none());
}
#[test]
fn typedef_kind_loose_recognizes_object_form() {
let node = json!({ "TypeDef:String": { "encoding": "offset-indirect" } });
fn alktype_kind_loose_recognizes_object_form() {
let node = json!({ "AlkType:String": { "encoding": "offset-indirect" } });
assert_eq!(
get_typedef_kind_loose_enum(&node),
Some(TypeDefKind::String)
get_alktype_kind_loose_enum(&node),
Some(AlkTypeKind::String)
);
}
}