use mago_database::file::FileId;
use serde::Deserialize;
use serde::Serialize;
use mago_atom::Atom;
use mago_span::Position;
use crate::identifier::method::MethodIdentifier;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
pub enum FunctionLikeIdentifier {
Function(Atom),
Method(Atom, Atom),
Closure(FileId, Position),
}
impl FunctionLikeIdentifier {
#[inline]
#[must_use]
pub const fn is_function(&self) -> bool {
matches!(self, FunctionLikeIdentifier::Function(_))
}
#[inline]
#[must_use]
pub const fn is_method(&self) -> bool {
matches!(self, FunctionLikeIdentifier::Method(_, _))
}
#[inline]
#[must_use]
pub const fn is_closure(&self) -> bool {
matches!(self, FunctionLikeIdentifier::Closure(_, _))
}
#[inline]
#[must_use]
pub const fn as_method_identifier(&self) -> Option<MethodIdentifier> {
match self {
FunctionLikeIdentifier::Method(fq_classlike_name, method_name) => {
Some(MethodIdentifier::new(*fq_classlike_name, *method_name))
}
_ => None,
}
}
#[inline]
#[must_use]
pub const fn title_kind_str(&self) -> &'static str {
match self {
FunctionLikeIdentifier::Function(_) => "Function",
FunctionLikeIdentifier::Method(_, _) => "Method",
FunctionLikeIdentifier::Closure(_, _) => "Closure",
}
}
#[inline]
#[must_use]
pub const fn kind_str(&self) -> &'static str {
match self {
FunctionLikeIdentifier::Function(_) => "function",
FunctionLikeIdentifier::Method(_, _) => "method",
FunctionLikeIdentifier::Closure(_, _) => "closure",
}
}
#[inline]
#[must_use]
pub fn as_string(&self) -> String {
match self {
FunctionLikeIdentifier::Function(fn_name) => fn_name.to_string(),
FunctionLikeIdentifier::Method(fq_classlike_name, method_name) => {
format!("{fq_classlike_name}::{method_name}")
}
FunctionLikeIdentifier::Closure(file_id, position) => {
format!("{}:{}", file_id, position.offset)
}
}
}
#[inline]
#[must_use]
pub fn to_hash(&self) -> String {
match self {
FunctionLikeIdentifier::Function(fn_name) => fn_name.to_string(),
FunctionLikeIdentifier::Method(fq_classlike_name, method_name) => {
format!("{fq_classlike_name}::{method_name}")
}
FunctionLikeIdentifier::Closure(file_id, position) => {
format!("{}::{}", file_id, position.offset)
}
}
}
}
impl From<MethodIdentifier> for FunctionLikeIdentifier {
#[inline]
fn from(value: MethodIdentifier) -> Self {
FunctionLikeIdentifier::Method(value.get_class_name(), value.get_method_name())
}
}