@@ -95,24 +95,42 @@ impl Parser for Format {
9595 let first_line = first_line. map_err ( Error :: CsvParse ) ?;
9696
9797 if first_line. len ( ) == 2 {
98- // Single language format: key, value
99- // First line is data, not header
100- records. push ( MultiLanguageCSVRecord {
101- key : first_line[ 0 ] . to_string ( ) ,
102- translations : {
103- let mut map = HashMap :: new ( ) ;
104- map. insert ( "default" . to_string ( ) , first_line[ 1 ] . to_string ( ) ) ;
105- map
106- } ,
107- } ) ;
108-
109- // Process remaining lines
110- for line in lines {
111- let line = line. map_err ( Error :: CsvParse ) ?;
112- if line. len ( ) == 2 {
113- let mut record = MultiLanguageCSVRecord :: new ( line[ 0 ] . to_string ( ) ) ;
114- record. add_translation ( "default" . to_string ( ) , line[ 1 ] . to_string ( ) ) ;
115- records. push ( record) ;
98+ if first_line[ 0 ] . trim ( ) . eq_ignore_ascii_case ( "key" ) {
99+ // Single-language header form: key, <lang>
100+ let language = first_line[ 1 ] . trim ( ) . to_string ( ) ;
101+ if language. is_empty ( ) {
102+ return Err ( Error :: DataMismatch (
103+ "Invalid CSV format: missing language in header" . to_string ( ) ,
104+ ) ) ;
105+ }
106+ for line in lines {
107+ let line = line. map_err ( Error :: CsvParse ) ?;
108+ if line. len ( ) == 2 {
109+ let mut record = MultiLanguageCSVRecord :: new ( line[ 0 ] . to_string ( ) ) ;
110+ record. add_translation ( language. clone ( ) , line[ 1 ] . to_string ( ) ) ;
111+ records. push ( record) ;
112+ }
113+ }
114+ } else {
115+ // Single language data form: key, value
116+ // First line is data, not header
117+ records. push ( MultiLanguageCSVRecord {
118+ key : first_line[ 0 ] . to_string ( ) ,
119+ translations : {
120+ let mut map = HashMap :: new ( ) ;
121+ map. insert ( "default" . to_string ( ) , first_line[ 1 ] . to_string ( ) ) ;
122+ map
123+ } ,
124+ } ) ;
125+
126+ // Process remaining lines
127+ for line in lines {
128+ let line = line. map_err ( Error :: CsvParse ) ?;
129+ if line. len ( ) == 2 {
130+ let mut record = MultiLanguageCSVRecord :: new ( line[ 0 ] . to_string ( ) ) ;
131+ record. add_translation ( "default" . to_string ( ) , line[ 1 ] . to_string ( ) ) ;
132+ records. push ( record) ;
133+ }
116134 }
117135 }
118136 } else if first_line. len ( ) >= 3 {
@@ -400,6 +418,25 @@ mod tests {
400418 ) ;
401419 }
402420
421+ #[ test]
422+ fn test_parse_single_language_header_csv ( ) {
423+ let csv_content = "key,en\n hello,Hello\n bye,Goodbye\n " ;
424+ let format = Format :: from_reader ( Cursor :: new ( csv_content) ) . unwrap ( ) ;
425+ assert_eq ! ( format. records. len( ) , 2 ) ;
426+ assert_eq ! (
427+ format. records[ 0 ] . get_translation( "en" ) ,
428+ Some ( & "Hello" . to_string( ) )
429+ ) ;
430+ assert_eq ! (
431+ format. records[ 1 ] . get_translation( "en" ) ,
432+ Some ( & "Goodbye" . to_string( ) )
433+ ) ;
434+
435+ let resources = Vec :: < Resource > :: try_from ( format) . unwrap ( ) ;
436+ assert_eq ! ( resources. len( ) , 1 ) ;
437+ assert_eq ! ( resources[ 0 ] . metadata. language, "en" ) ;
438+ }
439+
403440 #[ test]
404441 fn test_multi_language_csv_to_resources ( ) {
405442 let csv_content = "key,en,cn\n hello,Hello,你好\n bye,Goodbye,再见\n " ;
0 commit comments