citum_schema_style/locale/
message_ids.rs1use super::Locale;
15use super::message::MessageArgs;
16use super::types::{GeneralTerm, GrammaticalGender, MessageSyntax, TermForm};
17use crate::citation::LocatorType;
18use crate::template::ContributorRole;
19
20impl Locale {
21 pub(super) fn general_term_to_message_id(term: &GeneralTerm) -> &str {
23 match term {
24 GeneralTerm::And => "and",
25 GeneralTerm::EtAl => "et-al",
26 GeneralTerm::AndOthers => "and-others",
27 GeneralTerm::Accessed => "accessed",
28 GeneralTerm::Cited => "cited",
29 GeneralTerm::Retrieved => "retrieved",
30 GeneralTerm::NoDate => "no-date",
31 GeneralTerm::Ibid => "ibid",
32 GeneralTerm::In => "in",
33 GeneralTerm::At => "at",
34 GeneralTerm::By => "by",
35 GeneralTerm::From => "from",
36 GeneralTerm::Of => "of",
37 GeneralTerm::To => "to",
38 GeneralTerm::Anonymous => "anonymous",
39 GeneralTerm::Circa => "circa",
40 GeneralTerm::Forthcoming => "forthcoming",
41 GeneralTerm::Online => "online",
42 GeneralTerm::AvailableAt => "available-at",
43 GeneralTerm::ReviewOf => "review-of",
44 GeneralTerm::Here => "here",
45 GeneralTerm::Deposited => "deposited",
46 GeneralTerm::Patent => "patent",
47 GeneralTerm::Issued => "issued",
48 GeneralTerm::Volume => "volume",
49 GeneralTerm::Issue => "issue",
50 GeneralTerm::Page => "page",
51 GeneralTerm::Chapter => "chapter",
52 GeneralTerm::Edition => "edition",
53 GeneralTerm::Section => "section",
54 GeneralTerm::OriginalWorkPublished => "original-work-published",
55 GeneralTerm::PersonalCommunication => "personal-communication",
56 GeneralTerm::Unknown(s) => s.as_str(),
57 }
58 }
59
60 pub(super) fn general_term_to_legacy_key(term: &GeneralTerm) -> &str {
62 match term {
63 GeneralTerm::EtAl => "et_al",
64 GeneralTerm::NoDate => "no_date",
65 _ => Self::general_term_to_message_id(term),
66 }
67 }
68
69 pub(super) fn role_message_id(role: &ContributorRole, form: &TermForm) -> Option<&'static str> {
70 let prefix = match role {
71 ContributorRole::Editor => "role.editor",
72 ContributorRole::Translator => "role.translator",
73 ContributorRole::Guest => "role.guest",
74 _ => return None,
75 };
76
77 match *form {
78 TermForm::Long => Some(match prefix {
79 "role.editor" => "role.editor.label-long",
80 "role.translator" => "role.translator.label-long",
81 "role.guest" => "role.guest.label-long",
82 _ => return None,
83 }),
84 TermForm::Short => Some(match prefix {
85 "role.editor" => "role.editor.label",
86 "role.translator" => "role.translator.label",
87 "role.guest" => "role.guest.label",
88 _ => return None,
89 }),
90 TermForm::Verb | TermForm::VerbShort => Some(match prefix {
91 "role.editor" => "role.editor.verb",
92 "role.translator" => "role.translator.verb",
93 "role.guest" => "role.guest.verb",
94 _ => return None,
95 }),
96 _ => None,
97 }
98 }
99
100 pub(super) fn locator_message_id(
101 locator: &LocatorType,
102 form: &TermForm,
103 ) -> Option<&'static str> {
104 let prefix = match locator {
105 LocatorType::Page => "term.page-label",
106 LocatorType::Chapter => "term.chapter-label",
107 LocatorType::Volume => "term.volume-label",
108 LocatorType::Section => "term.section-label",
109 LocatorType::Figure => "term.figure-label",
110 LocatorType::Note => "term.note-label",
111 _ => return None,
112 };
113
114 match *form {
115 TermForm::Long => Some(match prefix {
116 "term.page-label" => "term.page-label-long",
117 "term.chapter-label" => "term.chapter-label-long",
118 "term.volume-label" => "term.volume-label-long",
119 "term.section-label" => "term.section-label-long",
120 "term.figure-label" => "term.figure-label-long",
121 "term.note-label" => "term.note-label-long",
122 _ => return None,
123 }),
124 TermForm::Short => Some(prefix),
125 _ => None,
126 }
127 }
128
129 pub(super) fn general_message_id(term: &GeneralTerm, form: &TermForm) -> Option<&'static str> {
130 match (term, form) {
131 (GeneralTerm::And, _) => Some("term.and"),
132 (GeneralTerm::EtAl, _) => Some("term.et-al"),
133 (GeneralTerm::AndOthers, _) => Some("term.and-others"),
134 (GeneralTerm::Accessed, _) => Some("term.accessed"),
135 (GeneralTerm::Cited, _) => Some("term.cited"),
136 (GeneralTerm::Retrieved, _) => Some("term.retrieved"),
137 (GeneralTerm::NoDate, TermForm::Long) => Some("term.no-date-long"),
138 (GeneralTerm::NoDate, _) => Some("term.no-date"),
139 (GeneralTerm::Forthcoming, _) => Some("term.forthcoming"),
140 (GeneralTerm::Circa, TermForm::Long) => Some("term.circa-long"),
141 (GeneralTerm::Circa, _) => Some("term.circa"),
142 _ => None,
143 }
144 }
145
146 pub(super) fn gender_selector_key(gender: &GrammaticalGender) -> &str {
147 match gender {
148 GrammaticalGender::Masculine => "masculine",
149 GrammaticalGender::Feminine => "feminine",
150 GrammaticalGender::Neuter => "neuter",
151 GrammaticalGender::Common => "common",
152 GrammaticalGender::Unknown(s) => s.as_str(),
153 }
154 }
155
156 pub fn resolve_message(&self, message_id: &str, args: &MessageArgs<'_>) -> Option<String> {
162 let message = self.messages.get(message_id)?;
163
164 if !message.contains('{') {
165 return Some(message.clone());
166 }
167
168 if self.evaluation.message_syntax == MessageSyntax::Static {
169 return None;
170 }
171
172 self.evaluator.evaluate(message, args)
173 }
174
175 pub fn resolve_template_message(
181 &self,
182 message_id: &str,
183 args: &MessageArgs<'_>,
184 form: Option<&TermForm>,
185 gender: Option<GrammaticalGender>,
186 ) -> Option<String> {
187 if let Some((term, implied_form)) = Self::term_message_parts(message_id) {
188 let effective_form = form.cloned().or(implied_form).unwrap_or(TermForm::Long);
189 if let Some(value) = self.resolved_general_term(&term, &effective_form, gender) {
190 return Some(value);
191 }
192 }
193
194 self.resolve_message(message_id, args)
195 }
196
197 fn term_message_parts(message_id: &str) -> Option<(GeneralTerm, Option<TermForm>)> {
198 let key = message_id.strip_prefix("term.")?;
199 let (term_key, implied_form) = key
200 .strip_suffix("-long")
201 .map_or((key, None), |base| (base, Some(TermForm::Long)));
202 let term = Self::parse_general_term(term_key)
203 .unwrap_or_else(|| GeneralTerm::Unknown(term_key.to_string()));
204 Some((term, implied_form))
205 }
206
207 pub(super) fn resolve_message_text(
208 &self,
209 message_id: &str,
210 count: Option<u64>,
211 gender: Option<GrammaticalGender>,
212 ) -> Option<String> {
213 let args = MessageArgs {
214 count,
215 gender: gender.as_ref().map(Self::gender_selector_key),
216 ..MessageArgs::default()
217 };
218
219 self.resolve_message(message_id, &args)
220 }
221}