Skip to main content

gdscript_scene/
lib.rs

1//! `gdscript-scene` — a `.tscn`/`.tres` **text** parser for scene-aware analysis (Phase 4).
2//!
3//! > **Internal layer (not a stable API).** Depend on [`gdscript-ide`](https://docs.rs/gdscript-ide) (the public surface); the items here
4//! > may change between releases.
5//!
6//! Godot's text scene format is INI-like: bracketed section headers (`[node …]`, `[ext_resource …]`,
7//! …) followed by `key = value` property lines. This crate parses that structure — node names,
8//! types, parent paths, attached scripts, `unique_name_in_owner`, and instanced sub-scenes — into a
9//! [`SceneModel`] **with byte spans**, so the type layer (Phase-4 M1+) can resolve `$Path` /
10//! `%Unique` / `get_node("…")` to a node's real `Control`/`Node` subclass instead of bare `Node` —
11//! intelligence the Godot editor's own LSP produces only in-editor and never flows into inference.
12//!
13//! **M0 scope:** the pure, wasm-clean [`parse_scene`] (`&str -> SceneModel`) + the model + byte
14//! spans. It **records** the typing inputs (`type=`/`script=`/`instance=`); it does **not** resolve
15//! a `Ty` (M1), recurse into instanced sub-scenes, build the project-wide script↔scene index, or
16//! cache via salsa (M1+). See `plans/PHASE-4-M0-PLAYBOOK.md`.
17//!
18//! **Invariant:** the parser is strictly additive and **never fails** — every binary/malformed/
19//! unknown form degrades to an empty-or-partial model + a [`SceneProblem`], never a panic or `Err`.
20//! The floor is always parity with the engine's `Node`-everywhere baseline.
21//!
22//! **Portability:** a core crate — wasm32-clean (no `std::fs`, no `Instant`, no threads); `.tscn`
23//! text is injected via the VFS exactly like `.gd`.
24#![cfg_attr(docsrs, feature(doc_cfg))]
25#![deny(missing_docs)]
26
27mod model;
28mod parse;
29
30pub use model::{
31    ExtId, ExtResource, NodeIdx, NodePathResolution, NodeProp, SceneConnection, SceneKind,
32    SceneModel, SceneNode, SceneProblem, SubResource,
33};
34pub use parse::parse_scene;
35
36#[cfg(test)]
37mod tests;