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