use ryo_analysis::cascade::CascadeSpec;
use serde::Serialize;
#[derive(Debug, thiserror::Error)]
pub enum DiscoverError {
#[error("Project error: {0}")]
Project(String),
#[error("Query error: {0}")]
Query(String),
}
#[derive(Debug, Clone, Serialize)]
pub struct CascadeResult {
pub symbol: String,
#[serde(serialize_with = "serialize_cascade_specs")]
pub specs: Vec<CascadeSpec>,
}
impl CascadeResult {
pub fn new(symbol: String) -> Self {
Self {
symbol,
specs: Vec::new(),
}
}
pub fn is_empty(&self) -> bool {
self.specs.is_empty()
}
pub fn len(&self) -> usize {
self.specs.len()
}
}
fn serialize_cascade_specs<S>(specs: &[CascadeSpec], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(specs.len()))?;
for spec in specs {
let value = match spec {
CascadeSpec::AddMatchArm {
target,
function_name,
enum_name,
pattern,
body,
} => serde_json::json!({
"type": "AddMatchArm",
"target": target.to_string(),
"function_name": function_name,
"enum_name": enum_name,
"pattern": pattern,
"body": body,
}),
CascadeSpec::AddDerive { symbol_id, derives } => serde_json::json!({
"type": "AddDerive",
"symbol_id": format!("{:?}", symbol_id),
"derives": derives,
}),
CascadeSpec::GenerateImpl {
target,
trait_name,
call_new,
} => serde_json::json!({
"type": "GenerateImpl",
"target": target.to_string(),
"trait_name": trait_name,
"call_new": call_new,
}),
CascadeSpec::ChangeVisibility {
symbol_id,
visibility,
} => serde_json::json!({
"type": "ChangeVisibility",
"symbol_id": format!("{:?}", symbol_id),
"visibility": format!("{:?}", visibility),
}),
CascadeSpec::AddUse {
target_module,
path,
} => serde_json::json!({
"type": "AddUse",
"target_module": target_module.to_string(),
"path": path,
}),
CascadeSpec::RemoveMatchArm {
target,
function_name,
enum_name,
pattern,
} => serde_json::json!({
"type": "RemoveMatchArm",
"target": target.to_string(),
"function_name": function_name,
"enum_name": enum_name,
"pattern": pattern,
}),
};
seq.serialize_element(&value)?;
}
seq.end()
}