pub struct Ast { /* private fields */ }Expand description
Arena-backed mutable AST used by transform-oriented code.
Public mutation APIs intentionally avoid exposing &mut Node so parent links
and detached subtree tracking cannot be bypassed accidentally.
Implementations§
Source§impl Ast
impl Ast
Sourcepub fn with_root_mode(mode: ContentMode) -> Self
pub fn with_root_mode(mode: ContentMode) -> Self
Create an empty AST whose root uses the given content mode.
Sourcepub fn from_syntax_root(node: &SyntaxNode) -> Self
pub fn from_syntax_root(node: &SyntaxNode) -> Self
Convert a parsed SyntaxNode tree into a mutable Ast.
Conversion preserves shape:
- content argument variants are converted directly to the referenced node
- single-node content is not wrapped in an implicit group
Delimiter::Control(&'static str)becomesDelimiter::Controlwith ownedStringdataSyntaxNode::Erroris preserved losslessly asNode::Error; the resulting tree is structurally valid but semantically incomplete
§Panics
Panics if the converted tree violates AST invariants, such as an environment body that is not a group.
Sourcepub fn to_syntax_root(&self) -> SyntaxNode
pub fn to_syntax_root(&self) -> SyntaxNode
Convert this AST back into a SyntaxNode tree.
Sourcepub fn node_opt(&self, id: NodeId) -> Option<&Node>
pub fn node_opt(&self, id: NodeId) -> Option<&Node>
Non-panicking node borrow; returns None if id is invalid.
Sourcepub fn node_opt_mut(&mut self, id: NodeId) -> Option<&mut Node>
pub fn node_opt_mut(&mut self, id: NodeId) -> Option<&mut Node>
Non-panicking mutable node borrow; returns None if id is invalid.
Direct mutation through this helper must not change a node’s edges. Structural changes must keep using the edge-aware AST methods.
Sourcepub fn is_detached_root(&self, id: NodeId) -> bool
pub fn is_detached_root(&self, id: NodeId) -> bool
Whether id is currently tracked as a detached root.
Sourcepub fn subtree_contains_node(&self, root: NodeId, target: NodeId) -> bool
pub fn subtree_contains_node(&self, root: NodeId, target: NodeId) -> bool
Whether target lies in the subtree rooted at root, inclusive.
Sourcepub fn parent(&self, id: NodeId) -> Option<ParentLink>
pub fn parent(&self, id: NodeId) -> Option<ParentLink>
Return the parent link for id, if the node is attached.
Root, detached roots, and invalid or removed IDs return None. Callers
that need to distinguish a valid detached root from an invalid ID should
check Ast::contains first.
Sourcepub fn parent_id(&self, id: NodeId) -> Option<NodeId>
pub fn parent_id(&self, id: NodeId) -> Option<NodeId>
Return the parent node ID for id, if attached.
See Ast::parent for the None cases.
Sourcepub fn slot(&self, id: NodeId) -> Option<Slot>
pub fn slot(&self, id: NodeId) -> Option<Slot>
Return the slot occupied by id in its parent, if attached.
See Ast::parent for the None cases.
Sourcepub fn children(&self, id: NodeId) -> &[NodeId]
pub fn children(&self, id: NodeId) -> &[NodeId]
Return the direct children of a root/group node.
Other node kinds return an empty slice.
§Panics
Panics if id is invalid.
Sourcepub fn arg_slots(&self, id: NodeId) -> &[ArgumentSlot] ⓘ
pub fn arg_slots(&self, id: NodeId) -> &[ArgumentSlot] ⓘ
Return the argument slots owned by a command-like node.
Non-command-like nodes return an empty slice.
§Panics
Panics if id is invalid.
Sourcepub fn edges(&self, id: NodeId) -> Vec<(NodeId, Slot)>
pub fn edges(&self, id: NodeId) -> Vec<(NodeId, Slot)>
Return every direct tree edge of id as (child, slot) pairs.
Returned order matches the AST’s direct traversal order. Only Content argument entries are exposed as argument edges.
§Panics
Panics if id is invalid.
Sourcepub fn clone_subtree(&mut self, id: NodeId) -> NodeId
pub fn clone_subtree(&mut self, id: NodeId) -> NodeId
Deep-copy the subtree rooted at id and return the copied detached root.
The cloned tree preserves node shape and scalar argument values, but every
copied node receives a fresh NodeId. The returned root is detached, so
callers can attach it with Ast::new_node, Ast::replace_node, or
group insertion helpers.
§Panics
Panics if id is invalid or points at the main AST root.
Sourcepub fn next_sibling(&self, id: NodeId) -> Option<NodeId>
pub fn next_sibling(&self, id: NodeId) -> Option<NodeId>
Return the next sibling of id when it is attached as a group child.
Nodes in non-GroupChild slots and invalid or removed IDs return
None.
Sourcepub fn prev_sibling(&self, id: NodeId) -> Option<NodeId>
pub fn prev_sibling(&self, id: NodeId) -> Option<NodeId>
Return the previous sibling of id when it is attached as a group child.
Nodes in non-GroupChild slots and invalid or removed IDs return
None.
Sourcepub fn find<F>(&self, start: NodeId, predicate: F) -> Option<NodeId>
pub fn find<F>(&self, start: NodeId, predicate: F) -> Option<NodeId>
Depth-first search starting at start, returning the first matching node.
§Panics
Panics if start is invalid.
Sourcepub fn find_all<F>(&self, start: NodeId, predicate: F) -> Vec<NodeId>
pub fn find_all<F>(&self, start: NodeId, predicate: F) -> Vec<NodeId>
Collect all matching nodes reachable from start in depth-first order.
The returned vector is a snapshot of NodeIds at collection time.
Later mutations may delete or move those nodes, so callers should use
Ast::contains and, when necessary, re-check parent / slot state
before mutating.
§Panics
Panics if start is invalid.
Sourcepub fn subtree_contains_command(&self, start: NodeId, name: &str) -> bool
pub fn subtree_contains_command(&self, start: NodeId, name: &str) -> bool
Check whether the subtree rooted at start contains a command named name.
§Panics
Panics if start is invalid.
Sourcepub fn new_node(&mut self, node: Node) -> NodeId
pub fn new_node(&mut self, node: Node) -> NodeId
Insert a new detached node into the arena and return its NodeId.
If node references child IDs, those children must already exist as
detached roots. They are adopted by the new node immediately.
§Panics
These panics indicate a caller-side structural invariant violation. The AST is not guaranteed to be reusable after such a panic.
Panics if:
- the same child is referenced more than once
- a referenced child does not exist
- a referenced child is not a detached root
- adopting a child would introduce a cycle
- an environment body is not a group
Sourcepub fn append_child(&mut self, parent: NodeId, child: NodeId)
pub fn append_child(&mut self, parent: NodeId, child: NodeId)
Append child to the end of a root/group child list.
child must currently be a detached root.
§Panics
Panics if:
parentis not a root/group nodechildis invalidchildis already attachedchildis not tracked as a detached root- attaching
childwould introduce a cycle
Sourcepub fn insert_child(&mut self, parent: NodeId, index: usize, child: NodeId)
pub fn insert_child(&mut self, parent: NodeId, index: usize, child: NodeId)
Insert child at index within a root/group child list.
child must currently be a detached root.
§Panics
Panics if:
parentis not a root/group nodeindexis out of bounds forVec::insertchildis invalidchildis already attachedchildis not tracked as a detached root- attaching
childwould introduce a cycle
Sourcepub fn detach(&mut self, id: NodeId) -> NodeId
pub fn detach(&mut self, id: NodeId) -> NodeId
Detach id from its parent and return the same node ID.
This version only supports detaching nodes that occupy Slot::GroupChild.
Detached nodes remain in the arena and become detached roots until they
are reattached or explicitly removed with Ast::remove_detached.
§Panics
Panics if:
idis the main rootidis already detachedidis attached through a non-GroupChildslot
Sourcepub fn replace_children(
&mut self,
parent: NodeId,
children: Vec<NodeId>,
) -> Vec<NodeId>
pub fn replace_children( &mut self, parent: NodeId, children: Vec<NodeId>, ) -> Vec<NodeId>
Replace all direct children of a root/group node.
New children may be detached roots or existing direct children of the same parent. Removed children are preserved as detached roots.
Sourcepub fn detach_children_range(
&mut self,
parent: NodeId,
range: Range<usize>,
) -> Vec<NodeId>
pub fn detach_children_range( &mut self, parent: NodeId, range: Range<usize>, ) -> Vec<NodeId>
Detach a contiguous range of direct children from a root/group node.
§Panics
Panics if parent is not a root/group node or range is out of bounds
for Vec::drain.
Sourcepub fn replace_content_child(&mut self, old: NodeId, replacement: NodeId)
pub fn replace_content_child(&mut self, old: NodeId, replacement: NodeId)
Replace a content child or another single-child slot.
The replacement must be a detached root. The old child becomes detached.
Sourcepub fn remove_node(&mut self, id: NodeId)
pub fn remove_node(&mut self, id: NodeId)
Remove an attached node and its entire subtree from the arena.
This is implemented as Ast::detach followed by
Ast::remove_detached.
§Panics
Panics under the same conditions as Ast::detach or
Ast::remove_detached.
Sourcepub fn replace_node(&mut self, id: NodeId, new_node: Node) -> Node
pub fn replace_node(&mut self, id: NodeId, new_node: Node) -> Node
Replace the node data stored at id while preserving the same NodeId.
The new node may:
- reuse direct children already owned by
id - adopt detached roots
Direct children removed by the replacement are not deleted. They become detached roots so transforms can keep or inspect them explicitly.
§Panics
These panics indicate a caller-side structural invariant violation. The AST is not guaranteed to be reusable after such a panic.
Panics if:
idis the main root or invalid- the new node references the same child more than once
- the new node is a root variant
- a reused child is not a direct child of
id - a newly introduced child is not a detached root
- adopting a child would introduce a cycle
- an environment body is not a group
Sourcepub fn append_cloned_math_content(
&mut self,
out: &mut Vec<NodeId>,
source: NodeId,
)
pub fn append_cloned_math_content( &mut self, out: &mut Vec<NodeId>, source: NodeId, )
Appends cloned math content into out, flattening implicit math groups.
Parser-created content arguments often wrap multiple items in an
implicit math group. Flattening that wrapper lets transforms compose
output such as \partial f without introducing extra braces around f.
Sourcepub fn implicit_math_group(&mut self, children: Vec<NodeId>) -> NodeId
pub fn implicit_math_group(&mut self, children: Vec<NodeId>) -> NodeId
Creates an implicit math group containing children.
Sourcepub fn superscript(&mut self, base: NodeId, superscript: NodeId) -> NodeId
pub fn superscript(&mut self, base: NodeId, superscript: NodeId) -> NodeId
Creates a scripted node with only a superscript.
Sourcepub fn replace_node_drop_detached_children(
&mut self,
id: NodeId,
replacement: Node,
)
pub fn replace_node_drop_detached_children( &mut self, id: NodeId, replacement: Node, )
Replaces id and removes any old child subtrees detached by the replacement.
Sourcepub fn replace_with_math_sequence(
&mut self,
id: NodeId,
before: Vec<NodeId>,
replacement: NodeId,
after: Vec<NodeId>,
)
pub fn replace_with_math_sequence( &mut self, id: NodeId, before: Vec<NodeId>, replacement: NodeId, after: Vec<NodeId>, )
Replaces a node with a math-mode sequence.
Every node in before, replacement, and after must be a unique
detached root. If id is a group child, before and after are
inserted as real siblings around the replacement payload, and
replacement is consumed into id. In single-child slots, the sequence
is wrapped in an implicit math group because those slots cannot hold
siblings.
Sourcepub fn replace_with_math_sequence_preserving_scripts(
&mut self,
id: NodeId,
before: Vec<NodeId>,
first: NodeId,
after: Vec<NodeId>,
)
pub fn replace_with_math_sequence_preserving_scripts( &mut self, id: NodeId, before: Vec<NodeId>, first: NodeId, after: Vec<NodeId>, )
Replaces a node with a math-mode sequence, moving scripts from a
parent Node::Scripted onto the final emitted node when id is the
scripted base.
Every node in before, first, and after must be a unique detached
root.
Sourcepub fn remove_detached(&mut self, id: NodeId) -> Node
pub fn remove_detached(&mut self, id: NodeId) -> Node
Destroy a detached subtree and return the removed root node value.
The subtree must already be detached from the main tree. All descendants are removed from the arena as well.
§Panics
Panics if:
idis the main root or invalididis still attachedidis not tracked as a detached root
Sourcepub fn assert_invariants(&self)
pub fn assert_invariants(&self)
Assert all structural invariants of the AST.
Checked conditions include:
- the main root exists and has no parent
- every parent link corresponds to a real direct edge
- every node is reachable from either the root or a detached root
- every parentless non-root node is tracked in detached roots
- environment bodies are always groups
This method is intended for tests and debug-time validation.
§Panics
Panics with a descriptive message when any invariant is violated.