use super::super::protocol::{DocumentSymbol, SymbolKind};
use crate::repo_map::parser;
pub fn path_to_uri(path: &str) -> String {
if path.starts_with('/') {
format!("file://{path}")
} else {
format!("file:///{path}")
}
}
pub fn uri_to_path(uri: &str) -> String {
if let Some(rest) = uri.strip_prefix("file://") {
if rest.starts_with('/') && rest.len() > 2 && rest.as_bytes()[2] == b':' {
rest[1..].to_string()
} else {
rest.to_string()
}
} else {
uri.to_string()
}
}
pub fn to_repo_symbols(symbols: &[DocumentSymbol], file_path: &str) -> Vec<parser::Symbol> {
let mut out = Vec::new();
flatten_symbols(symbols, &mut out, file_path);
out
}
pub(super) fn flatten_symbols(
symbols: &[DocumentSymbol],
out: &mut Vec<parser::Symbol>,
_file_path: &str,
) {
for sym in symbols {
if let Some(kind) = map_symbol_kind(sym.kind) {
out.push(parser::Symbol {
name: sym.name.clone(),
kind,
line: (sym.selection_range.start.line as usize) + 1,
signature: sym.detail.clone(),
});
}
if let Some(children) = &sym.children {
flatten_symbols(children, out, _file_path);
}
}
}
pub(super) fn map_symbol_kind(kind: SymbolKind) -> Option<parser::SymbolKind> {
match kind {
SymbolKind::Function | SymbolKind::Method | SymbolKind::Constructor => {
Some(parser::SymbolKind::Function)
}
SymbolKind::Class | SymbolKind::Struct => Some(parser::SymbolKind::Struct),
SymbolKind::Enum => Some(parser::SymbolKind::Enum),
SymbolKind::Interface => Some(parser::SymbolKind::Trait),
SymbolKind::Module | SymbolKind::Namespace | SymbolKind::Package => {
Some(parser::SymbolKind::Mod)
}
SymbolKind::Constant => Some(parser::SymbolKind::Const),
SymbolKind::TypeParameter => Some(parser::SymbolKind::Type),
_ => None,
}
}