1+ use std:: borrow:: Cow ;
2+
13use crate :: marc:: {
24 extract_values:: ExtractValues ,
35 string_normalize:: maybe_not_empty,
46 trim_punctuation,
5- variable_length_field:: { SubfieldIterator , latin_or_non_latin_tag_included_in} ,
7+ variable_length_field:: {
8+ SubfieldIterator , join_subfields_by_code, latin_or_non_latin_tag_included_in,
9+ latin_tag_included_in,
10+ } ,
611} ;
712use itertools:: Itertools ;
813use marctk:: Record ;
@@ -20,7 +25,7 @@ pub fn contains_titles_index(record: &Record) -> impl Iterator<Item = String> {
2025
2126pub fn latin_script_title ( record : & Record ) -> Option < String > {
2227 record
23- . extract_field_values_by (
28+ . first_matching_field_value (
2429 |field| field. tag ( ) == "245" ,
2530 |field| {
2631 Some (
@@ -33,7 +38,33 @@ pub fn latin_script_title(record: &Record) -> Option<String> {
3338 )
3439 } ,
3540 )
36- . next ( )
41+ }
42+
43+ pub fn title_sort ( record : & Record ) -> Option < String > {
44+ record. first_matching_field_value ( latin_tag_included_in ( & [ "245" ] ) , |field| {
45+ let joined =
46+ join_subfields_by_code ( field, & [ "a" , "b" , "c" , "f" , "g" , "h" , "k" , "n" , "p" , "s" ] ) ;
47+ let non_filing_characters = field. ind2 ( ) . parse :: < u8 > ( ) ;
48+ let trimmed = match non_filing_characters {
49+ Ok ( non_filing_characters) => {
50+ without_non_filing_characters ( & joined, non_filing_characters) . to_string ( )
51+ }
52+ Err ( _) => joined,
53+ } ;
54+ maybe_not_empty ( trimmed)
55+ } )
56+ }
57+
58+ fn without_non_filing_characters < ' a > ( title : & ' a str , non_filing_characters : u8 ) -> Cow < ' a , str > {
59+ if non_filing_characters == 0 {
60+ Cow :: Borrowed ( title)
61+ } else {
62+ if title. len ( ) > non_filing_characters. into ( ) {
63+ Cow :: Owned ( title. chars ( ) . skip ( non_filing_characters. into ( ) ) . collect ( ) )
64+ } else {
65+ Cow :: Borrowed ( Default :: default ( ) )
66+ }
67+ }
3768}
3869
3970#[ cfg( test) ]
@@ -49,4 +80,18 @@ mod tests {
4980 assert_eq ! ( contains_titles. next( ) , Some ( String :: from( "زوراء" ) ) ) ;
5081 assert_eq ! ( contains_titles. next( ) , None ) ;
5182 }
83+
84+ #[ test]
85+ fn it_can_find_title_sort ( ) {
86+ let record = Record :: from_breaker ( r"=245 \4 $aThe octopus" ) . unwrap ( ) ;
87+ let title_sort = title_sort ( & record) . unwrap ( ) ;
88+ assert_eq ! ( title_sort, "octopus" ) ;
89+ }
90+
91+ #[ test]
92+ fn it_returns_title_sort_none_if_245_empty ( ) {
93+ let record = Record :: from_breaker ( r"=245 \4 $a " ) . unwrap ( ) ;
94+ let title_sort = title_sort ( & record) ;
95+ assert_eq ! ( title_sort, None ) ;
96+ }
5297}
0 commit comments