use ryo_source::pure::{PureField, PureFields, PureType, PureVis};
use ryo_symbol::SymbolId;
use crate::Mutation;
#[derive(Debug, Clone)]
pub struct AddEnumMutation {
pub parent: SymbolId,
pub name: String,
pub variants: Vec<(String, PureFields)>, pub is_pub: bool,
pub derives: Vec<String>,
}
impl AddEnumMutation {
pub fn new(parent: SymbolId, name: impl Into<String>) -> Self {
Self {
parent,
name: name.into(),
variants: Vec::new(),
is_pub: false,
derives: Vec::new(),
}
}
pub fn with_variant(mut self, name: impl Into<String>) -> Self {
self.variants.push((name.into(), PureFields::Unit));
self
}
pub fn with_tuple_variant(mut self, name: impl Into<String>, types: Vec<String>) -> Self {
let fields: Vec<PureType> = types.into_iter().map(PureType::Path).collect();
self.variants.push((name.into(), PureFields::Tuple(fields)));
self
}
pub fn with_struct_variant(
mut self,
name: impl Into<String>,
fields: Vec<(String, String)>,
) -> Self {
let pure_fields: Vec<PureField> = fields
.into_iter()
.map(|(n, t)| PureField {
attrs: Vec::new(),
vis: PureVis::Private,
name: n,
ty: PureType::Path(t),
})
.collect();
self.variants
.push((name.into(), PureFields::Named(pure_fields)));
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 AddEnumMutation {
fn describe(&self) -> String {
let vis = if self.is_pub { "pub " } else { "" };
format!(
"Add {}enum {} with {} variants to {}",
vis,
self.name,
self.variants.len(),
self.parent
)
}
fn mutation_type(&self) -> &'static str {
"AddEnum"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}
#[derive(Debug, Clone)]
pub struct RemoveEnumMutation {
pub symbol_id: SymbolId,
}
impl RemoveEnumMutation {
pub fn new(symbol_id: SymbolId) -> Self {
Self { symbol_id }
}
}
impl Mutation for RemoveEnumMutation {
fn describe(&self) -> String {
format!("Remove enum {}", self.symbol_id)
}
fn mutation_type(&self) -> &'static str {
"RemoveEnum"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}
#[derive(Debug, Clone)]
pub struct AddVariantMutation {
pub enum_id: SymbolId,
pub variant_name: String,
pub fields: PureFields,
}
impl AddVariantMutation {
pub fn new(enum_id: SymbolId, variant_name: impl Into<String>, fields: PureFields) -> Self {
Self {
enum_id,
variant_name: variant_name.into(),
fields,
}
}
pub fn unit(enum_id: SymbolId, variant_name: impl Into<String>) -> Self {
Self::new(enum_id, variant_name, PureFields::Unit)
}
pub fn tuple(enum_id: SymbolId, variant_name: impl Into<String>, types: Vec<String>) -> Self {
Self::new(
enum_id,
variant_name,
PureFields::Tuple(types.into_iter().map(PureType::Path).collect()),
)
}
pub fn struct_variant(
enum_id: SymbolId,
variant_name: impl Into<String>,
fields: Vec<(String, String)>,
) -> Self {
let pure_fields: Vec<PureField> = fields
.into_iter()
.map(|(n, t)| PureField {
attrs: Vec::new(),
vis: PureVis::Private,
name: n,
ty: PureType::Path(t),
})
.collect();
Self::new(enum_id, variant_name, PureFields::Named(pure_fields))
}
}
impl Mutation for AddVariantMutation {
fn describe(&self) -> String {
format!("Add variant {} to enum {}", self.variant_name, self.enum_id)
}
fn mutation_type(&self) -> &'static str {
"AddVariant"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}
#[derive(Debug, Clone)]
pub struct RemoveVariantMutation {
pub enum_id: SymbolId,
pub variant_name: String,
}
impl RemoveVariantMutation {
pub fn new(enum_id: SymbolId, variant_name: impl Into<String>) -> Self {
Self {
enum_id,
variant_name: variant_name.into(),
}
}
}
impl Mutation for RemoveVariantMutation {
fn describe(&self) -> String {
format!(
"Remove variant {} from enum {}",
self.variant_name, self.enum_id
)
}
fn mutation_type(&self) -> &'static str {
"RemoveVariant"
}
fn box_clone(&self) -> Box<dyn Mutation> {
Box::new(self.clone())
}
}