feat: improve formatting output
* duration is now in human readable format * list of artists is now capped at 140 chars max
This commit is contained in:
		
							parent
							
								
									46edd0f781
								
							
						
					
					
						commit
						7c828a55db
					
				| @ -1,6 +1,6 @@ | |||||||
| [package] | [package] | ||||||
| name = "songlify" | name = "songlify" | ||||||
| version = "0.2.1" | version = "0.2.2" | ||||||
| edition = "2018" | edition = "2018" | ||||||
| 
 | 
 | ||||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||||||
|  | |||||||
							
								
								
									
										14
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -4,8 +4,12 @@ use crate::spotify::TrackInfo; | |||||||
| use spotify::SpotifyKind::Track; | use spotify::SpotifyKind::Track; | ||||||
| 
 | 
 | ||||||
| use crate::spotify::SpotifyKind::{Album, Playlist}; | use crate::spotify::SpotifyKind::{Album, Playlist}; | ||||||
|  | use crate::utils::{human_readable_duration, truncate_with_dots}; | ||||||
| 
 | 
 | ||||||
| mod spotify; | mod spotify; | ||||||
|  | mod utils; | ||||||
|  | 
 | ||||||
|  | static MAX_ARTISTS_CHARS: usize = 140; | ||||||
| 
 | 
 | ||||||
| #[tokio::main] | #[tokio::main] | ||||||
| async fn main() { | async fn main() { | ||||||
| @ -28,10 +32,10 @@ async fn main() { | |||||||
|                                     "Track information:\n\ |                                     "Track information:\n\ | ||||||
|                                 🎵 Track name: {}\n\ |                                 🎵 Track name: {}\n\ | ||||||
|                                 🧑🎤 Artist(s): {}\n\ |                                 🧑🎤 Artist(s): {}\n\ | ||||||
|                                 ⏳ Duration: {} second(s)",
 |                                 ⏳ Duration: {}",
 | ||||||
|                                     info.name, |                                     info.name, | ||||||
|                                     info.artists.join(", "), |                                     truncate_with_dots(info.artists.join(", "), MAX_ARTISTS_CHARS), | ||||||
|                                     info.duration.as_secs() |                                     human_readable_duration(info.duration) | ||||||
|                                 ); |                                 ); | ||||||
|                                 Some(message.reply_to(reply).await?) |                                 Some(message.reply_to(reply).await?) | ||||||
|                             } |                             } | ||||||
| @ -49,7 +53,7 @@ async fn main() { | |||||||
|                                     🧑🎤 {} artist(s): {}",
 |                                     🧑🎤 {} artist(s): {}",
 | ||||||
|                                     info.name, |                                     info.name, | ||||||
|                                     info.artists.len(), |                                     info.artists.len(), | ||||||
|                                     info.artists.join(", ") |                                     truncate_with_dots(info.artists.join(", "), MAX_ARTISTS_CHARS) | ||||||
|                                 ); |                                 ); | ||||||
|                                 if !info.genres.is_empty() { |                                 if !info.genres.is_empty() { | ||||||
|                                     reply.push_str( |                                     reply.push_str( | ||||||
| @ -77,7 +81,7 @@ async fn main() { | |||||||
|                                     🧑🎤 {} artist(s): {}",
 |                                     🧑🎤 {} artist(s): {}",
 | ||||||
|                                     info.name, |                                     info.name, | ||||||
|                                     info.artists.len(), |                                     info.artists.len(), | ||||||
|                                     info.artists.join(", ") |                                     truncate_with_dots(info.artists.join(", "), MAX_ARTISTS_CHARS) | ||||||
|                                 ); |                                 ); | ||||||
|                                 Some( |                                 Some( | ||||||
|                                     message |                                     message | ||||||
|  | |||||||
							
								
								
									
										96
									
								
								src/utils/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/utils/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | use std::ops::Add; | ||||||
|  | use std::time::Duration; | ||||||
|  | 
 | ||||||
|  | pub(crate) fn truncate_with_dots(to_truncate: String, new_size: usize) -> String { | ||||||
|  |     if to_truncate.len() < new_size { | ||||||
|  |         return to_truncate; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     let mut new_string = to_truncate.clone(); | ||||||
|  |     let dots = "..."; | ||||||
|  |     if new_size as isize - 3 > 0 { | ||||||
|  |         new_string.truncate(new_size - 3); | ||||||
|  |         new_string.add(dots) | ||||||
|  |     } else { | ||||||
|  |         let mut dots_to_ret = String::new(); | ||||||
|  |         for _i in 0..new_size { | ||||||
|  |             dots_to_ret.push('.'); | ||||||
|  |         } | ||||||
|  |         return dots_to_ret; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub(crate) fn human_readable_duration(duration: Duration) -> String { | ||||||
|  |     let total_duration = duration.as_secs(); | ||||||
|  |     let mut minutes = total_duration / 60; | ||||||
|  |     let seconds = total_duration % 60; | ||||||
|  | 
 | ||||||
|  |     if minutes >= 60 { | ||||||
|  |         let hours = minutes / 60; | ||||||
|  |         minutes = minutes % 60; | ||||||
|  |         return format!( | ||||||
|  |             "{} hour(s), {} minute(s) and {} second(s)", | ||||||
|  |             hours, minutes, seconds | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |     format!("{} minute(s) and {} second(s)", minutes, seconds) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[cfg(test)] | ||||||
|  | mod test { | ||||||
|  |     use super::*; | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn should_truncate_short_string_as_expected() { | ||||||
|  |         let example_string = "example"; | ||||||
|  |         let expected_string = ".."; | ||||||
|  | 
 | ||||||
|  |         assert_eq!( | ||||||
|  |             expected_string, | ||||||
|  |             truncate_with_dots(example_string.to_string(), 2) | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn should_truncate_long_string_as_expected() { | ||||||
|  |         let example_string = "this is a very long string"; | ||||||
|  |         let expected_string = "this i..."; | ||||||
|  | 
 | ||||||
|  |         assert_eq!( | ||||||
|  |             expected_string, | ||||||
|  |             truncate_with_dots(example_string.to_string(), 9) | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn should_not_truncate_if_string_is_not_long_enough() { | ||||||
|  |         let example_string = "short string"; | ||||||
|  |         let expected_string = "short string"; | ||||||
|  | 
 | ||||||
|  |         assert_eq!( | ||||||
|  |             expected_string, | ||||||
|  |             truncate_with_dots(example_string.to_string(), 1000) | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn should_print_correct_duration_into_human_readable_format() { | ||||||
|  |         let duration: Duration = Duration::new(124, 0); | ||||||
|  |         let got = human_readable_duration(duration); | ||||||
|  | 
 | ||||||
|  |         assert_eq!("2 minute(s) and 4 second(s)", got) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn should_handle_duration_in_hours() { | ||||||
|  |         let duration1 = Duration::new(3621, 0); | ||||||
|  |         let got1 = human_readable_duration(duration1); | ||||||
|  | 
 | ||||||
|  |         assert_eq!("1 hour(s), 0 minute(s) and 21 second(s)", got1); | ||||||
|  | 
 | ||||||
|  |         let duration2 = Duration::new(5021, 0); | ||||||
|  |         let got2 = human_readable_duration(duration2); | ||||||
|  | 
 | ||||||
|  |         assert_eq!("1 hour(s), 23 minute(s) and 41 second(s)", got2); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user