use serde::Serialize;
use std::path::PathBuf;
use thiserror::Error;
pub use crate::language::{
capture_name_to_chunk_type, ChunkType, FieldStyle, Language, SignatureStyle,
};
#[derive(Error, Debug)]
pub enum ParserError {
#[error("Unsupported file type: {0}")]
UnsupportedFileType(String),
#[error("Failed to parse: {0}")]
ParseFailed(String),
#[error("Failed to compile query for {0}: {1}")]
QueryCompileFailed(String, String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
}
#[derive(Debug, Clone)]
pub struct Chunk {
pub id: String,
pub file: PathBuf,
pub language: Language,
pub chunk_type: ChunkType,
pub name: String,
pub signature: String,
pub content: String,
pub doc: Option<String>,
pub line_start: u32,
pub line_end: u32,
pub content_hash: String,
pub parent_id: Option<String>,
pub window_idx: Option<u32>,
pub parent_type_name: Option<String>,
}
#[derive(Debug, Clone)]
pub struct CallSite {
pub callee_name: String,
pub line_number: u32,
}
#[derive(Debug, Clone)]
pub struct FunctionCalls {
pub name: String,
pub line_start: u32,
pub calls: Vec<CallSite>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)]
pub enum TypeEdgeKind {
Param,
Return,
Field,
Impl,
Bound,
Alias,
}
impl TypeEdgeKind {
pub fn as_str(&self) -> &'static str {
match self {
TypeEdgeKind::Param => "Param",
TypeEdgeKind::Return => "Return",
TypeEdgeKind::Field => "Field",
TypeEdgeKind::Impl => "Impl",
TypeEdgeKind::Bound => "Bound",
TypeEdgeKind::Alias => "Alias",
}
}
}
impl std::fmt::Display for TypeEdgeKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl std::str::FromStr for TypeEdgeKind {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Param" => Ok(TypeEdgeKind::Param),
"Return" => Ok(TypeEdgeKind::Return),
"Field" => Ok(TypeEdgeKind::Field),
"Impl" => Ok(TypeEdgeKind::Impl),
"Bound" => Ok(TypeEdgeKind::Bound),
"Alias" => Ok(TypeEdgeKind::Alias),
other => Err(format!("Unknown TypeEdgeKind: '{other}'")),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TypeRef {
pub type_name: String,
pub line_number: u32,
pub kind: Option<TypeEdgeKind>,
}
#[derive(Debug, Clone)]
pub struct ChunkTypeRefs {
pub name: String,
pub line_start: u32,
pub type_refs: Vec<TypeRef>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn type_edge_kind_round_trip() {
for kind in [
TypeEdgeKind::Param,
TypeEdgeKind::Return,
TypeEdgeKind::Field,
TypeEdgeKind::Impl,
TypeEdgeKind::Bound,
TypeEdgeKind::Alias,
] {
let s = kind.to_string();
let parsed: TypeEdgeKind = s.parse().unwrap();
assert_eq!(kind, parsed, "Round-trip failed for {s}");
}
}
}