11use biblatex:: Person ;
22use biblatex:: { Entry , EntryType } ;
3+ use std:: cmp:: Ordering ;
34use std:: collections:: HashMap ;
45use utils:: BiblatexUtils ;
56use validators:: { MatchedCitation , MatchedCitationDisambiguated } ;
@@ -9,7 +10,7 @@ use crate::validators;
910use crate :: validators:: ArticleFileData ;
1011
1112/// Transform a list of entries into a list of strings according to the Chicago bibliography style.
12- pub fn entries_to_strings ( entries : & Vec < MatchedCitationDisambiguated > ) -> Vec < String > {
13+ pub fn entries_to_strings ( entries : & [ MatchedCitationDisambiguated ] ) -> Vec < String > {
1314 let sorted_entries = sort_entries ( entries) ;
1415 let mut strings_output: Vec < String > = Vec :: new ( ) ;
1516
@@ -64,7 +65,7 @@ pub fn disambiguate_matched_citations(
6465 let author_year_key = format ! ( "{}-{}" , author_last_name, year) ;
6566 author_year_groups
6667 . entry ( author_year_key)
67- . or_insert_with ( Vec :: new )
68+ . or_default ( )
6869 . push ( citation) ;
6970 }
7071
@@ -126,7 +127,7 @@ fn transform_book_entry(matched_citation: &MatchedCitationDisambiguated) -> Stri
126127 let title = extract_title ( & matched_citation. entry ) ;
127128 let publisher = extract_publisher ( & matched_citation. entry ) ;
128129 let address = extract_address ( & matched_citation. entry ) ;
129- let translators = matched_citation. entry . translator ( ) . unwrap_or ( Vec :: new ( ) ) ;
130+ let translators = matched_citation. entry . translator ( ) . unwrap_or_default ( ) ;
130131 let doi = matched_citation. entry . doi ( ) . unwrap_or ( "" . to_string ( ) ) ;
131132
132133 add_authors ( author, & mut book_string) ;
@@ -150,7 +151,7 @@ fn transform_article_entry(matched_citation: &MatchedCitationDisambiguated) -> S
150151 let volume = extract_volume ( & matched_citation. entry ) ;
151152 let number = extract_number ( & matched_citation. entry ) ;
152153 let pages = extract_pages ( & matched_citation. entry ) ;
153- let translators = matched_citation. entry . translator ( ) . unwrap_or ( Vec :: new ( ) ) ;
154+ let translators = matched_citation. entry . translator ( ) . unwrap_or_default ( ) ;
154155 let doi = matched_citation. entry . doi ( ) . unwrap_or ( "" . to_string ( ) ) ;
155156
156157 add_authors ( author, & mut article_string) ;
@@ -171,20 +172,25 @@ fn generate_contributors(
171172 contributor_description : String ,
172173) -> String {
173174 let mut contributors_str = String :: new ( ) ;
174- if contributors. len ( ) > 1 {
175- contributors_str. push_str ( & format ! ( "{} by " , contributor_description) ) ;
176- for ( i, person) in contributors. iter ( ) . enumerate ( ) {
177- if i == contributors. len ( ) - 1 {
178- contributors_str. push_str ( & format ! ( "and {} {}. " , person. given_name, person. name) ) ;
179- } else {
180- contributors_str. push_str ( & format ! ( "{} {}, " , person. given_name, person. name) ) ;
175+ match contributors. len ( ) . cmp ( & 1 ) {
176+ Ordering :: Greater => {
177+ contributors_str. push_str ( & format ! ( "{} by " , contributor_description) ) ;
178+ for ( i, person) in contributors. iter ( ) . enumerate ( ) {
179+ if i == contributors. len ( ) - 1 {
180+ contributors_str
181+ . push_str ( & format ! ( "and {} {}. " , person. given_name, person. name) ) ;
182+ } else {
183+ contributors_str. push_str ( & format ! ( "{} {}, " , person. given_name, person. name) ) ;
184+ }
181185 }
182186 }
183- } else if contributors. len ( ) == 1 {
184- contributors_str. push_str ( & format ! (
185- "{} by {} {}. " ,
186- contributor_description, contributors[ 0 ] . given_name, contributors[ 0 ] . name
187- ) ) ;
187+ Ordering :: Equal => {
188+ contributors_str. push_str ( & format ! (
189+ "{} by {} {}. " ,
190+ contributor_description, contributors[ 0 ] . given_name, contributors[ 0 ] . name
191+ ) ) ;
192+ }
193+ Ordering :: Less => { }
188194 }
189195 contributors_str
190196}
@@ -200,30 +206,36 @@ fn add_authors(author: Vec<biblatex::Person>, bib_html: &mut String) {
200206
201207/// Returns Chicago style format for authors. Handles the case when there are multiple authors.
202208fn format_authors ( author : Vec < biblatex:: Person > ) -> String {
203- if author. len ( ) > 2 {
204- return format ! ( "{}, {} et al. " , author[ 0 ] . name, author[ 0 ] . given_name) ;
205- } else if author. len ( ) == 2 {
206- // In Chicago style, when listing multiple authors in a bibliography entry,
207- // only the first author's name is inverted (i.e., "Last, First"). The second and subsequent
208- // authors' names are written in standard order (i.e., "First Last").
209- // This rule helps differentiate the primary author from co-authors.
210- return format ! (
211- "{}, {} and {} {}. " ,
212- author[ 0 ] . name, author[ 0 ] . given_name, author[ 1 ] . given_name, author[ 1 ] . name
213- ) ;
214- } else {
215- return format ! ( "{}, {}. " , author[ 0 ] . name, author[ 0 ] . given_name) ;
209+ match author. len ( ) . cmp ( & 2 ) {
210+ Ordering :: Greater => {
211+ format ! ( "{}, {} et al. " , author[ 0 ] . name, author[ 0 ] . given_name)
212+ }
213+ Ordering :: Equal => {
214+ // In Chicago style, when listing multiple authors in a bibliography entry,
215+ // only the first author's name is inverted (i.e., "Last, First"). The second and subsequent
216+ // authors' names are written in standard order (i.e., "First Last").
217+ // This rule helps differentiate the primary author from co-authors.
218+ format ! (
219+ "{}, {} and {} {}. " ,
220+ author[ 0 ] . name, author[ 0 ] . given_name, author[ 1 ] . given_name, author[ 1 ] . name
221+ )
222+ }
223+ Ordering :: Less => {
224+ format ! ( "{}, {}. " , author[ 0 ] . name, author[ 0 ] . given_name)
225+ }
216226 }
217227}
218228
219229/// Returns Chicago style format for authors. Handles the case when there are multiple authors.
220230fn format_authors_last_name_only ( author : Vec < biblatex:: Person > ) -> String {
221- if author. len ( ) > 2 {
222- return format ! ( "{} et al." , author[ 0 ] . name) ;
223- } else if author. len ( ) == 2 {
224- return format ! ( "{} and {}" , author[ 0 ] . name, author[ 1 ] . name) ;
225- } else {
226- return format ! ( "{}" , author[ 0 ] . name) ;
231+ match author. len ( ) . cmp ( & 2 ) {
232+ Ordering :: Greater => {
233+ format ! ( "{} et al." , author[ 0 ] . name)
234+ }
235+ Ordering :: Equal => {
236+ format ! ( "{} and {}" , author[ 0 ] . name, author[ 1 ] . name)
237+ }
238+ Ordering :: Less => author[ 0 ] . name . to_string ( ) ,
227239 }
228240}
229241
@@ -272,8 +284,8 @@ fn add_journal_volume_number_pages(
272284}
273285
274286/// Sort entries by author's last name.
275- fn sort_entries ( entries : & Vec < MatchedCitationDisambiguated > ) -> Vec < MatchedCitationDisambiguated > {
276- let mut sorted_entries = entries. clone ( ) ;
287+ fn sort_entries ( entries : & [ MatchedCitationDisambiguated ] ) -> Vec < MatchedCitationDisambiguated > {
288+ let mut sorted_entries = entries. to_vec ( ) ;
277289
278290 sorted_entries. sort_by ( |a, b| {
279291 let a_authors = a. entry . author ( ) . unwrap_or_default ( ) ;
@@ -292,7 +304,7 @@ fn sort_entries(entries: &Vec<MatchedCitationDisambiguated>) -> Vec<MatchedCitat
292304 // Compare by year
293305 let a_year = & a. year_disambiguated ;
294306 let b_year = & b. year_disambiguated ;
295- let cmp_year = a_year. cmp ( & b_year) ;
307+ let cmp_year = a_year. cmp ( b_year) ;
296308 if cmp_year != std:: cmp:: Ordering :: Equal {
297309 return cmp_year;
298310 }
@@ -307,7 +319,7 @@ fn sort_entries(entries: &Vec<MatchedCitationDisambiguated>) -> Vec<MatchedCitat
307319}
308320
309321/// Helper to generate a sortable author string
310- fn author_key ( authors : & Vec < Person > ) -> String {
322+ fn author_key ( authors : & [ Person ] ) -> String {
311323 authors
312324 . first ( )
313325 . map ( |p| p. name . clone ( ) . to_lowercase ( ) )
@@ -317,57 +329,49 @@ fn author_key(authors: &Vec<Person>) -> String {
317329/// Title of the entry.
318330fn extract_title ( entry : & Entry ) -> String {
319331 let title_spanned = entry. title ( ) . unwrap ( ) ;
320- let title = BiblatexUtils :: extract_spanned_chunk ( title_spanned) ;
321- title
332+ BiblatexUtils :: extract_spanned_chunk ( title_spanned)
322333}
323334
324335/// Publisher of the entry.
325336fn extract_publisher ( entry : & Entry ) -> String {
326337 let publisher_spanned = entry. publisher ( ) . unwrap ( ) ;
327- let publisher = BiblatexUtils :: extract_publisher ( & publisher_spanned) ;
328- publisher
338+ BiblatexUtils :: extract_publisher ( & publisher_spanned)
329339}
330340
331341/// Address of the publisher.
332342fn extract_address ( entry : & Entry ) -> String {
333343 let address_spanned = entry. address ( ) . unwrap ( ) ;
334- let address = BiblatexUtils :: extract_spanned_chunk ( address_spanned) ;
335- address
344+ BiblatexUtils :: extract_spanned_chunk ( address_spanned)
336345}
337346
338347/// Year of entry.
339348fn extract_date ( entry : & Entry ) -> i32 {
340349 let date = entry. date ( ) . unwrap ( ) ;
341- let year = BiblatexUtils :: extract_year_from_date ( & date, entry. key . clone ( ) ) . unwrap ( ) ;
342- year
350+ BiblatexUtils :: extract_year_from_date ( & date, entry. key . clone ( ) ) . unwrap ( )
343351}
344352
345353/// Name of the journal of the article.
346354fn extract_journal ( entry : & Entry ) -> String {
347355 let journal_spanned = entry. journal ( ) . unwrap ( ) ;
348- let journal = BiblatexUtils :: extract_spanned_chunk ( & journal_spanned) ;
349- journal
356+ BiblatexUtils :: extract_spanned_chunk ( journal_spanned)
350357}
351358
352359/// Volume of the journal.
353360fn extract_volume ( entry : & Entry ) -> i64 {
354361 let volume_permissive = entry. volume ( ) . unwrap ( ) ;
355- let volume = BiblatexUtils :: extract_volume ( & volume_permissive) ;
356- volume
362+ BiblatexUtils :: extract_volume ( & volume_permissive)
357363}
358364
359365/// Number of the journal.
360366fn extract_number ( entry : & Entry ) -> String {
361367 let number_spanned = entry. number ( ) . unwrap ( ) ;
362- let number = BiblatexUtils :: extract_spanned_chunk ( & number_spanned) ;
363- number
368+ BiblatexUtils :: extract_spanned_chunk ( number_spanned)
364369}
365370
366371/// Pages of the article.
367372fn extract_pages ( entry : & Entry ) -> String {
368373 let pages_permissive = entry. pages ( ) . unwrap ( ) ;
369- let pages = BiblatexUtils :: extract_pages ( & pages_permissive) ;
370- pages
374+ BiblatexUtils :: extract_pages ( & pages_permissive)
371375}
372376
373377/// Create disambiguated citation with letter (e.g., "@hegel2020logic, 123" -> "Hegel 2020a")
0 commit comments