@@ -19,19 +19,19 @@ impl Category {
1919 fn from_parent (
2020 slug : & str ,
2121 name : & str ,
22- description : & str ,
22+ description : String ,
2323 parent : Option < & Category > ,
2424 ) -> Category {
2525 match parent {
2626 Some ( parent) => Category {
2727 slug : format ! ( "{}::{}" , parent. slug, slug) ,
2828 name : format ! ( "{}::{}" , parent. name, name) ,
29- description : description . into ( ) ,
29+ description,
3030 } ,
3131 None => Category {
3232 slug : slug. into ( ) ,
3333 name : name. into ( ) ,
34- description : description . into ( ) ,
34+ description,
3535 } ,
3636 }
3737 }
@@ -47,6 +47,10 @@ fn optional_string_from_toml<'a>(toml: &'a toml::value::Table, key: &str) -> &'a
4747 toml. get ( key) . and_then ( toml:: Value :: as_str) . unwrap_or ( "" )
4848}
4949
50+ fn process_description ( description : & str ) -> String {
51+ description. split_whitespace ( ) . collect :: < Vec < _ > > ( ) . join ( " " )
52+ }
53+
5054fn categories_from_toml (
5155 categories : & toml:: value:: Table ,
5256 parent : Option < & Category > ,
@@ -58,10 +62,13 @@ fn categories_from_toml(
5862 . as_table ( )
5963 . with_context ( || format ! ( "category {slug} was not a TOML table" ) ) ?;
6064
65+ let description = optional_string_from_toml ( details, "description" ) ;
66+ let description = process_description ( description) ;
67+
6168 let category = Category :: from_parent (
6269 slug,
6370 required_string_from_toml ( details, "name" ) ?,
64- optional_string_from_toml ( details , " description" ) ,
71+ description,
6572 parent,
6673 ) ;
6774
@@ -120,3 +127,47 @@ pub async fn sync_with_connection(toml_str: &str, conn: &mut AsyncPgConnection)
120127 } )
121128 . await
122129}
130+
131+ #[ cfg( test) ]
132+ mod tests {
133+ use super :: * ;
134+
135+ #[ test]
136+ fn test_process_description ( ) {
137+ // Leading whitespace
138+ assert_eq ! ( process_description( " description" ) , "description" ) ;
139+ assert_eq ! ( process_description( "\t description" ) , "description" ) ;
140+ assert_eq ! ( process_description( "\n \n description" ) , "description" ) ;
141+
142+ // Trailing whitespace
143+ assert_eq ! ( process_description( "description " ) , "description" ) ;
144+ assert_eq ! ( process_description( "description\t " ) , "description" ) ;
145+ assert_eq ! ( process_description( "description\n \n " ) , "description" ) ;
146+
147+ // Both leading and trailing whitespace
148+ assert_eq ! ( process_description( " description " ) , "description" ) ;
149+ assert_eq ! ( process_description( "\t description\t " ) , "description" ) ;
150+ assert_eq ! (
151+ process_description( "\n description with spaces \n " ) ,
152+ "description with spaces"
153+ ) ;
154+
155+ // Collapses internal whitespace
156+ assert_eq ! (
157+ process_description( " multi word description " ) ,
158+ "multi word description"
159+ ) ;
160+ assert_eq ! (
161+ process_description( " description\n with\n newlines " ) ,
162+ "description with newlines"
163+ ) ;
164+ assert_eq ! (
165+ process_description( "text\n \n \n with\t \t multiple\n whitespace" ) ,
166+ "text with multiple whitespace"
167+ ) ;
168+
169+ // Empty string
170+ assert_eq ! ( process_description( "" ) , "" ) ;
171+ assert_eq ! ( process_description( " " ) , "" ) ;
172+ }
173+ }
0 commit comments