draxl_patch/model.rs
1use draxl_ast::{
2 CommentNode, DocNode, Expr, Field, Item, MatchArm, NodeId, Param, Pattern, Rank, SlotName,
3 Stmt, Type, Variant,
4};
5
6/// Slot owner used by slot refs and destinations.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum SlotOwner {
9 /// The root file node.
10 File,
11 /// A node identified by stable id.
12 Node(NodeId),
13}
14
15/// Public slot reference in the Draxl patch surface.
16#[derive(Debug, Clone, PartialEq, Eq)]
17pub struct SlotRef {
18 /// File root or node id that owns the destination slot.
19 pub owner: SlotOwner,
20 /// Stable profile-defined slot name.
21 pub slot: SlotName,
22}
23
24/// Ranked destination for ordered slots.
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct RankedDest {
27 /// Slot that owns the ranked child.
28 pub slot: SlotRef,
29 /// Rank to assign to the inserted or moved child.
30 pub rank: Rank,
31}
32
33/// Destination grammar shared by `insert` and `move`.
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum PatchDest {
36 /// Ranked destination for ordered slots.
37 Ranked(RankedDest),
38 /// Single-child slot destination.
39 Slot(SlotRef),
40}
41
42/// Replaceable, movable, or insertable semantic fragment.
43#[derive(Debug, Clone, PartialEq, Eq)]
44pub enum PatchNode {
45 /// Top-level or nested item fragment.
46 Item(Item),
47 /// Struct field fragment.
48 Field(Field),
49 /// Enum variant fragment.
50 Variant(Variant),
51 /// Function parameter fragment.
52 Param(Param),
53 /// Statement fragment.
54 Stmt(Stmt),
55 /// Match arm fragment.
56 MatchArm(MatchArm),
57 /// Expression fragment.
58 Expr(Expr),
59 /// Type fragment.
60 Type(Type),
61 /// Pattern fragment.
62 Pattern(Pattern),
63 /// Doc comment fragment.
64 Doc(DocNode),
65 /// Line comment fragment.
66 Comment(CommentNode),
67}
68
69/// Path address for scalar field or metadata updates.
70#[derive(Debug, Clone, PartialEq, Eq)]
71pub struct PatchPath {
72 /// Stable id of the root node that owns the path.
73 pub node_id: NodeId,
74 /// Field path segments below the node.
75 pub segments: Vec<String>,
76}
77
78/// Scalar value used by `set`.
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub enum PatchValue {
81 /// Bare identifier-like values such as names or enum variants.
82 Ident(String),
83 /// Quoted string values.
84 Str(String),
85 /// Numeric values.
86 Int(i64),
87 /// Boolean values.
88 Bool(bool),
89}
90
91/// Structured patch operation over the Draxl semantic model.
92#[derive(Debug, Clone, PartialEq, Eq)]
93pub enum PatchOp {
94 /// Inserts a new child into a ranked slot.
95 Insert {
96 /// Ranked destination that owns the inserted child.
97 dest: RankedDest,
98 /// Node to insert.
99 node: PatchNode,
100 },
101 /// Fills or replaces a single-child slot.
102 Put {
103 /// Slot to fill.
104 slot: SlotRef,
105 /// Node to install into the slot.
106 node: PatchNode,
107 },
108 /// Rewrites an existing node payload while preserving its outer shell.
109 Replace {
110 /// Stable id of the node to rewrite.
111 target_id: NodeId,
112 /// Replacement fragment for the node body.
113 replacement: PatchNode,
114 },
115 /// Removes an existing node.
116 Delete {
117 /// Stable id of the node to delete.
118 target_id: NodeId,
119 },
120 /// Relocates an existing node while preserving its identity.
121 Move {
122 /// Stable id of the node to move.
123 target_id: NodeId,
124 /// New destination for the node.
125 dest: PatchDest,
126 },
127 /// Updates a scalar field or metadata path.
128 Set {
129 /// Path to update.
130 path: PatchPath,
131 /// New scalar value.
132 value: PatchValue,
133 },
134 /// Clears an optional scalar field or metadata path.
135 Clear {
136 /// Path to clear.
137 path: PatchPath,
138 },
139 /// Attaches a doc or comment node to a semantic target.
140 Attach {
141 /// Attachable node id.
142 node_id: NodeId,
143 /// Target node id.
144 target_id: NodeId,
145 },
146 /// Detaches a doc or comment node.
147 Detach {
148 /// Attachable node id.
149 node_id: NodeId,
150 },
151}