use ryo_symbol::SymbolId;
use crate::Mutation;
#[derive(Debug, Clone)]
pub struct StructFieldDef {
pub name: String,
pub ty: String,
pub is_pub: bool,
}
impl StructFieldDef {
pub fn new(name: impl Into<String>, ty: impl Into<String>) -> Self {
Self {
name: name.into(),
ty: ty.into(),
is_pub: false,
}
}
pub fn public(mut self) -> Self {
self.is_pub = true;
self
}
}
#[derive(Debug, Clone)]
pub struct AddStructMutation {
pub parent: SymbolId,
pub name: String,
pub fields: Vec<StructFieldDef>,
pub is_pub: bool,
pub derives: Vec<String>,
}
impl AddStructMutation {
pub fn new(parent: SymbolId, name: impl Into<String>) -> Self {
Self {
parent,
name: name.into(),
fields: Vec::new(),
is_pub: false,
derives: Vec::new(),
}
}
pub fn with_field(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
self.fields.push(StructFieldDef::new(name, ty));
self
}
pub fn with_pub_field(mut self, name: impl Into<String>, ty: impl Into<String>) -> Self {
self.fields.push(StructFieldDef::new(name, ty).public());
self
}
pub fn with_fields(mut self, fields: Vec<(String, String)>) -> Self {
self.fields = fields
.into_iter()
.map(|(name, ty)| StructFieldDef::new(name, ty))
.collect();
self
}
pub fn with_fields_vis(mut self, fields: Vec<(String, String, bool)>) -> Self {
self.fields = fields
.into_iter()
.map(|(name, ty, is_pub)| {
let mut f = StructFieldDef::new(name, ty);
if is_pub {
f = f.public();
}
f
})
.collect();
self
}
pub fn public(mut self) -> Self {
self.is_pub = true;
self
}
pub fn with_derives(mut self, derives: Vec<String>) -> Self {
self.derives = derives;
self
}
}
impl Mutation for AddStructMutation {
fn describe(&self) -> String {
let vis = if self.is_pub { "pub " } else { "" };
let fields: Vec<_> = self
.fields
.iter()
.map(|f| {
let field_vis = if f.is_pub { "pub " } else { "" };
format!("{}{}: {}", field_vis, f.name, f.ty)
})
.collect();
format!(
"Add {}struct {} {{ {} }} to {}",
vis,
self.name,
fields.join(", "),
self.parent
)
}
fn mutation_type(&self) -> &'static str {
"AddStruct"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}
#[derive(Debug, Clone)]
pub struct RemoveStructMutation {
pub struct_id: SymbolId,
}
impl RemoveStructMutation {
pub fn new(struct_id: SymbolId) -> Self {
Self { struct_id }
}
}
impl Mutation for RemoveStructMutation {
fn describe(&self) -> String {
format!("Remove struct {}", self.struct_id)
}
fn mutation_type(&self) -> &'static str {
"RemoveStruct"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}