Skip to main content

ryo_mutations/basic/
struct_def.rs

1//! Struct mutations: AddStructMutation, RemoveStructMutation
2
3use ryo_symbol::SymbolId;
4
5use crate::Mutation;
6
7/// Field definition for AddStructMutation
8#[derive(Debug, Clone)]
9pub struct StructFieldDef {
10    pub name: String,
11    pub ty: String,
12    pub is_pub: bool,
13}
14
15impl StructFieldDef {
16    pub fn new(name: impl Into<String>, ty: impl Into<String>) -> Self {
17        Self {
18            name: name.into(),
19            ty: ty.into(),
20            is_pub: false,
21        }
22    }
23
24    pub fn public(mut self) -> Self {
25        self.is_pub = true;
26        self
27    }
28}
29
30/// Add a new struct to the file
31#[derive(Debug, Clone)]
32pub struct AddStructMutation {
33    /// Parent module SymbolId where the struct should be added
34    pub parent: SymbolId,
35    pub name: String,
36    pub fields: Vec<StructFieldDef>,
37    pub is_pub: bool,
38    pub derives: Vec<String>,
39}
40
41impl AddStructMutation {
42    pub fn new(parent: SymbolId, name: impl Into<String>) -> Self {
43        Self {
44            parent,
45            name: name.into(),
46            fields: Vec::new(),
47            is_pub: false,
48            derives: Vec::new(),
49        }
50    }
51
52    pub fn with_field(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
53        self.fields.push(StructFieldDef::new(name, ty));
54        self
55    }
56
57    /// Add a public field
58    pub fn with_pub_field(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
59        self.fields.push(StructFieldDef::new(name, ty).public());
60        self
61    }
62
63    /// Add fields from (name, type) tuples - all private (legacy compatibility)
64    pub fn with_fields(mut self, fields: Vec<(String, String)>) -> Self {
65        self.fields = fields
66            .into_iter()
67            .map(|(name, ty)| StructFieldDef::new(name, ty))
68            .collect();
69        self
70    }
71
72    /// Add fields with visibility information
73    pub fn with_fields_vis(mut self, fields: Vec<(String, String, bool)>) -> Self {
74        self.fields = fields
75            .into_iter()
76            .map(|(name, ty, is_pub)| {
77                let mut f = StructFieldDef::new(name, ty);
78                if is_pub {
79                    f = f.public();
80                }
81                f
82            })
83            .collect();
84        self
85    }
86
87    pub fn public(mut self) -> Self {
88        self.is_pub = true;
89        self
90    }
91
92    pub fn with_derives(mut self, derives: Vec<String>) -> Self {
93        self.derives = derives;
94        self
95    }
96}
97
98impl Mutation for AddStructMutation {
99    fn describe(&self) -> String {
100        let vis = if self.is_pub { "pub " } else { "" };
101        let fields: Vec<_> = self
102            .fields
103            .iter()
104            .map(|f| {
105                let field_vis = if f.is_pub { "pub " } else { "" };
106                format!("{}{}: {}", field_vis, f.name, f.ty)
107            })
108            .collect();
109        format!(
110            "Add {}struct {} {{ {} }} to {}",
111            vis,
112            self.name,
113            fields.join(", "),
114            self.parent
115        )
116    }
117
118    fn mutation_type(&self) -> &'static str {
119        "AddStruct"
120    }
121
122    fn box_clone(&self) -> Box<dyn Mutation> {
123        Box::new(self.clone())
124    }
125}
126
127/// Remove a struct from the file
128#[derive(Debug, Clone)]
129pub struct RemoveStructMutation {
130    /// SymbolId of the struct to remove (required, O(1) access)
131    pub struct_id: SymbolId,
132}
133
134impl RemoveStructMutation {
135    pub fn new(struct_id: SymbolId) -> Self {
136        Self { struct_id }
137    }
138}
139
140impl Mutation for RemoveStructMutation {
141    fn describe(&self) -> String {
142        format!("Remove struct {}", self.struct_id)
143    }
144
145    fn mutation_type(&self) -> &'static str {
146        "RemoveStruct"
147    }
148
149    fn box_clone(&self) -> Box<dyn Mutation> {
150        Box::new(self.clone())
151    }
152}