lex_analysis/
reference_targets.rs1use crate::utils::session_identifier;
2use lex_core::lex::ast::{Annotation, Definition, Session};
3use lex_core::lex::inlines::ReferenceType;
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash)]
6pub enum ReferenceTarget {
7 AnnotationLabel(String),
8 DefinitionSubject(String),
9 Session(String),
10 CitationKey(String),
11}
12
13pub fn targets_from_reference_type(reference_type: &ReferenceType) -> Vec<ReferenceTarget> {
14 let mut targets = Vec::new();
15 match reference_type {
16 ReferenceType::FootnoteLabeled { label } => {
17 push_unique(
18 &mut targets,
19 ReferenceTarget::AnnotationLabel(label.clone()),
20 );
21 }
22 ReferenceType::FootnoteNumber { number } => {
23 push_unique(
24 &mut targets,
25 ReferenceTarget::AnnotationLabel(number.to_string()),
26 );
27 }
28 ReferenceType::Citation(data) => {
29 for key in &data.keys {
30 push_unique(&mut targets, ReferenceTarget::CitationKey(key.clone()));
31 }
32 }
33 ReferenceType::General { target } => {
34 if !target.trim().is_empty() {
35 push_unique(
36 &mut targets,
37 ReferenceTarget::DefinitionSubject(target.trim().to_string()),
38 );
39 }
40 }
41 ReferenceType::ToCome {
42 identifier: Some(id),
43 } if !id.trim().is_empty() => {
44 push_unique(
45 &mut targets,
46 ReferenceTarget::DefinitionSubject(id.trim().to_string()),
47 );
48 }
49 ReferenceType::ToCome { .. } => {}
50 ReferenceType::Session { target } => {
51 if !target.trim().is_empty() {
52 push_unique(
53 &mut targets,
54 ReferenceTarget::Session(target.trim().to_string()),
55 );
56 }
57 }
58 _ => {}
59 }
60 targets
61}
62
63pub fn targets_from_annotation(annotation: &Annotation) -> Vec<ReferenceTarget> {
64 let mut targets = Vec::new();
65 let label = annotation.data.label.value.trim();
66 if !label.is_empty() {
67 push_unique(
68 &mut targets,
69 ReferenceTarget::AnnotationLabel(label.to_string()),
70 );
71 push_unique(
72 &mut targets,
73 ReferenceTarget::CitationKey(label.to_string()),
74 );
75 }
76 targets
77}
78
79pub fn targets_from_definition(definition: &Definition) -> Vec<ReferenceTarget> {
80 let mut targets = Vec::new();
81 let subject = definition.subject.as_string().trim();
82 if !subject.is_empty() {
83 push_unique(
84 &mut targets,
85 ReferenceTarget::DefinitionSubject(subject.to_string()),
86 );
87 }
88 targets
89}
90
91pub fn targets_from_session(session: &Session) -> Vec<ReferenceTarget> {
92 let mut targets = Vec::new();
93 if let Some(identifier) = session_identifier(session) {
94 push_unique(&mut targets, ReferenceTarget::Session(identifier));
95 }
96 targets
97}
98
99fn push_unique(targets: &mut Vec<ReferenceTarget>, target: ReferenceTarget) {
100 if targets.iter().any(|existing| existing == &target) {
101 return;
102 }
103 targets.push(target);
104}