use crate::SymbolPath;
use ryo_symbol::SymbolId;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CascadeSpec {
AddDerive {
symbol_id: SymbolId,
derives: Vec<String>,
},
GenerateImpl {
target: SymbolPath,
trait_name: String,
call_new: bool,
},
ChangeVisibility {
symbol_id: SymbolId,
visibility: Visibility,
},
AddUse {
target_module: SymbolPath,
path: String,
},
AddMatchArm {
target: SymbolPath,
function_name: String,
enum_name: String,
pattern: String,
body: String,
},
RemoveMatchArm {
target: SymbolPath,
function_name: String,
enum_name: String,
pattern: String,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Visibility {
Private,
Crate,
Super,
Public,
}
impl CascadeSpec {
pub fn add_derive(symbol_id: SymbolId, derives: Vec<String>) -> Self {
Self::AddDerive { symbol_id, derives }
}
pub fn generate_impl(
target: SymbolPath,
trait_name: impl Into<String>,
call_new: bool,
) -> Self {
Self::GenerateImpl {
target,
trait_name: trait_name.into(),
call_new,
}
}
pub fn change_visibility(symbol_id: SymbolId, visibility: Visibility) -> Self {
Self::ChangeVisibility {
symbol_id,
visibility,
}
}
pub fn add_use(target_module: SymbolPath, path: impl Into<String>) -> Self {
Self::AddUse {
target_module,
path: path.into(),
}
}
pub fn add_match_arm(
target: SymbolPath,
function_name: impl Into<String>,
enum_name: impl Into<String>,
pattern: impl Into<String>,
body: impl Into<String>,
) -> Self {
Self::AddMatchArm {
target,
function_name: function_name.into(),
enum_name: enum_name.into(),
pattern: pattern.into(),
body: body.into(),
}
}
pub fn remove_match_arm(
target: SymbolPath,
function_name: impl Into<String>,
enum_name: impl Into<String>,
pattern: impl Into<String>,
) -> Self {
Self::RemoveMatchArm {
target,
function_name: function_name.into(),
enum_name: enum_name.into(),
pattern: pattern.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use ryo_symbol::{SymbolKind, SymbolRegistry};
fn dummy_symbol_id(name: &str) -> SymbolId {
let mut registry = SymbolRegistry::new();
let path = SymbolPath::parse(&format!("test_crate::test_{}", name)).unwrap();
registry.register(path, SymbolKind::Struct).unwrap()
}
#[test]
fn test_cascade_spec_add_derive() {
let symbol_id = dummy_symbol_id("config");
let spec = CascadeSpec::add_derive(symbol_id, vec!["Default".to_string()]);
match spec {
CascadeSpec::AddDerive {
symbol_id: sid,
derives,
} => {
assert_eq!(sid, symbol_id);
assert_eq!(derives, vec!["Default".to_string()]);
}
_ => panic!("Expected AddDerive"),
}
}
#[test]
fn test_cascade_spec_add_match_arm() {
let target_path = SymbolPath::parse("test_crate::handlers").unwrap();
let spec = CascadeSpec::add_match_arm(
target_path.clone(),
"process_status",
"Status",
"Status::Cancelled",
"todo!()",
);
match &spec {
CascadeSpec::AddMatchArm {
target,
function_name,
enum_name,
pattern,
body,
} => {
assert_eq!(target, &target_path);
assert_eq!(function_name, "process_status");
assert_eq!(enum_name, "Status");
assert_eq!(pattern, "Status::Cancelled");
assert_eq!(body, "todo!()");
}
_ => panic!("Expected AddMatchArm"),
}
}
}