use std::path::PathBuf;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SymbolKind {
Function,
Method,
Struct,
Enum,
Trait,
Impl,
Class,
Interface,
Const,
Type,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[allow(dead_code)]
pub enum SpanChangeKind {
Unchanged,
WhitespaceOnly,
DocsOnly,
Mixed,
Semantic,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
#[allow(dead_code)]
pub(crate) enum SymbolChangeType {
Added,
Removed,
ModifiedBody,
ModifiedSignature,
TouchedOnly,
}
#[derive(Debug, Clone)]
pub struct CodeSymbol {
pub kind: SymbolKind,
pub name: String,
pub file: PathBuf,
pub line: usize,
pub end_line: usize,
pub is_public: bool,
pub is_added: bool,
pub is_whitespace_only: Option<bool>,
pub span_change_kind: Option<SpanChangeKind>,
pub signature: Option<String>,
pub parent_scope: Option<String>,
}
impl CodeSymbol {
#[must_use]
#[allow(dead_code)]
pub(crate) fn change_type(&self) -> SymbolChangeType {
match (self.is_added, self.is_whitespace_only) {
(true, None) => SymbolChangeType::Added,
(false, None) => SymbolChangeType::Removed,
(true, Some(true)) => SymbolChangeType::TouchedOnly,
(true, Some(false)) => SymbolChangeType::ModifiedBody,
(false, Some(true)) => SymbolChangeType::TouchedOnly,
(false, Some(false)) => SymbolChangeType::ModifiedBody,
}
}
}
impl std::fmt::Display for CodeSymbol {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let action = if self.is_added { "+" } else { "-" };
if let Some(sig) = &self.signature {
let scope_prefix = self
.parent_scope
.as_ref()
.map(|s| format!("{s} > "))
.unwrap_or_default();
write!(
f,
"[{}] {}{} ({}:{})",
action,
scope_prefix,
sig,
self.file.display(),
self.line
)
} else {
let visibility = if self.is_public { "pub " } else { "" };
write!(
f,
"[{}] {}{:?} {} ({}:{})",
action,
visibility,
self.kind,
self.name,
self.file.display(),
self.line
)
}
}
}