use crate::utils::session_identifier;
use lex_core::lex::ast::{Annotation, Definition, Session};
use lex_core::lex::inlines::ReferenceType;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ReferenceTarget {
AnnotationLabel(String),
DefinitionSubject(String),
Session(String),
CitationKey(String),
}
pub fn targets_from_reference_type(reference_type: &ReferenceType) -> Vec<ReferenceTarget> {
let mut targets = Vec::new();
match reference_type {
ReferenceType::AnnotationReference { label } => {
push_unique(
&mut targets,
ReferenceTarget::AnnotationLabel(label.clone()),
);
}
ReferenceType::FootnoteNumber { number } => {
push_unique(
&mut targets,
ReferenceTarget::AnnotationLabel(number.to_string()),
);
}
ReferenceType::Citation(data) => {
for key in &data.keys {
push_unique(&mut targets, ReferenceTarget::CitationKey(key.clone()));
}
}
ReferenceType::General { target } => {
if !target.trim().is_empty() {
push_unique(
&mut targets,
ReferenceTarget::DefinitionSubject(target.trim().to_string()),
);
}
}
ReferenceType::ToCome {
identifier: Some(id),
} if !id.trim().is_empty() => {
push_unique(
&mut targets,
ReferenceTarget::DefinitionSubject(id.trim().to_string()),
);
}
ReferenceType::ToCome { .. } => {}
ReferenceType::Session { target } => {
if !target.trim().is_empty() {
push_unique(
&mut targets,
ReferenceTarget::Session(target.trim().to_string()),
);
}
}
_ => {}
}
targets
}
pub fn targets_from_annotation(annotation: &Annotation) -> Vec<ReferenceTarget> {
let mut targets = Vec::new();
let label = annotation.data.label.value.trim();
if !label.is_empty() {
push_unique(
&mut targets,
ReferenceTarget::AnnotationLabel(label.to_string()),
);
push_unique(
&mut targets,
ReferenceTarget::CitationKey(label.to_string()),
);
}
targets
}
pub fn targets_from_definition(definition: &Definition) -> Vec<ReferenceTarget> {
let mut targets = Vec::new();
let subject = definition.subject.as_string().trim();
if !subject.is_empty() {
push_unique(
&mut targets,
ReferenceTarget::DefinitionSubject(subject.to_string()),
);
}
targets
}
pub fn targets_from_session(session: &Session) -> Vec<ReferenceTarget> {
let mut targets = Vec::new();
if let Some(identifier) = session_identifier(session) {
push_unique(&mut targets, ReferenceTarget::Session(identifier));
}
targets
}
fn push_unique(targets: &mut Vec<ReferenceTarget>, target: ReferenceTarget) {
if targets.iter().any(|existing| existing == &target) {
return;
}
targets.push(target);
}