diff --git a/src/commands/my_listings.rs b/src/commands/my_listings.rs index 4a6eb4e..1a8a9bb 100644 --- a/src/commands/my_listings.rs +++ b/src/commands/my_listings.rs @@ -187,7 +187,7 @@ async fn show_listing_details( target: impl Into, ) -> HandlerResult { let response = format!( - "🔍 Viewing Listing Details\n\n\ + "🔍 Listing Details\n\n\ Title: {}\n\ Description: {}\n", listing.base.title, diff --git a/src/commands/new_listing/tests.rs b/src/commands/new_listing/tests.rs index d036647..0c26275 100644 --- a/src/commands/new_listing/tests.rs +++ b/src/commands/new_listing/tests.rs @@ -46,7 +46,7 @@ fn test_complete_field_processing_workflow() { for (field, input) in workflow { let result = process_field_update(field, &mut draft, input); - assert!(result.is_ok(), "Processing {:?} should succeed", field); + assert!(result.is_ok(), "Processing {field:?} should succeed"); } // Verify realistic final state @@ -130,8 +130,7 @@ fn test_natural_language_duration_conversion() { assert_eq!( fields.end_delay, ListingDuration::hours(expected_hours), - "Business duration '{}' should convert correctly", - input + "Business duration '{input}' should convert correctly" ); } } diff --git a/src/commands/new_listing/ui.rs b/src/commands/new_listing/ui.rs index f854579..4205f76 100644 --- a/src/commands/new_listing/ui.rs +++ b/src/commands/new_listing/ui.rs @@ -43,14 +43,11 @@ pub async fn display_listing_summary( .unwrap_or("No description") )); - match &draft.fields { - ListingFields::FixedPriceListing(fields) => { - response_lines.push(format!( - "💰 Buy it Now Price: ${}", - fields.buy_now_price - )); - } - _ => {} + if let ListingFields::FixedPriceListing(fields) = &draft.fields { + response_lines.push(format!( + "💰 Buy it Now Price: ${}", + fields.buy_now_price + )); } match &draft.persisted { @@ -73,7 +70,7 @@ pub async fn display_listing_summary( response_lines.push("".to_string()); response_lines.push("Please review your listing and choose an action:".to_string()); - send_message(&bot, target, response_lines.join("\n"), keyboard).await?; + send_message(bot, target, response_lines.join("\n"), keyboard).await?; Ok(()) } diff --git a/src/db/bind_fields.rs b/src/db/bind_fields.rs index 87855e9..e93f108 100644 --- a/src/db/bind_fields.rs +++ b/src/db/bind_fields.rs @@ -1,4 +1,3 @@ -use std::iter::repeat; use sqlx::{prelude::*, query::Query, sqlite::SqliteArguments, Encode, Sqlite}; @@ -16,15 +15,11 @@ where Box::new(move |query| query.bind(value)) } +#[derive(Default)] pub struct BindFields { binds: Vec<(&'static str, BindFn)>, } -impl Default for BindFields { - fn default() -> Self { - Self { binds: vec![] } - } -} impl BindFields { #[must_use] @@ -59,6 +54,6 @@ impl BindFields { } pub fn bind_placeholders(&self) -> impl Iterator + '_ { - repeat("?").take(self.binds.len()) + std::iter::repeat_n("?", self.binds.len()) } } diff --git a/src/db/dao/user_dao.rs b/src/db/dao/user_dao.rs index 6a8cfa1..77dd32e 100644 --- a/src/db/dao/user_dao.rs +++ b/src/db/dao/user_dao.rs @@ -116,7 +116,7 @@ impl UserDAO { .await?; let user = FromRow::from_row(&row)?; - log::info!("load user from db: {:?}", user); + log::info!("load user from db: {user:?}"); Ok(user) } @@ -229,7 +229,7 @@ mod tests { assert_eq!(inserted_user.telegram_id, 12345.into()); assert_eq!(inserted_user.username, Some("testuser".to_string())); assert_eq!(inserted_user.first_name, "Test User".to_string()); - assert_eq!(inserted_user.is_banned, false); + assert!(!inserted_user.is_banned); // Find by ID let found_user = UserDAO::find_by_id(&pool, inserted_user.persisted.id) @@ -323,7 +323,7 @@ mod tests { assert_eq!(updated_user.username, Some("newname".to_string())); assert_eq!(updated_user.first_name, "New Name".to_string()); - assert_eq!(updated_user.is_banned, true); + assert!(updated_user.is_banned); } #[tokio::test] diff --git a/src/db/types/money_amount.rs b/src/db/types/money_amount.rs index 2c7bc80..9a6772a 100644 --- a/src/db/types/money_amount.rs +++ b/src/db/types/money_amount.rs @@ -203,7 +203,7 @@ mod tests { // Insert test data sqlx::query("INSERT INTO test_money (amount, currency) VALUES (?, ?)") - .bind(&amount) + .bind(amount) .bind(CurrencyType::Usd) .execute(&pool) .await @@ -245,7 +245,7 @@ mod tests { sqlx::query("INSERT INTO test_money (amount, currency, optional_amount) VALUES (?, ?, ?)") .bind(MoneyAmount::from_str("100.00").unwrap()) .bind(CurrencyType::Usd) - .bind(&optional_amount) + .bind(optional_amount) .execute(&pool) .await .expect("Failed to insert some optional amount"); @@ -290,7 +290,7 @@ mod tests { // Insert into database sqlx::query("INSERT INTO test_money (amount, currency) VALUES (?, ?)") - .bind(&amount) + .bind(amount) .bind(CurrencyType::Usd) .execute(&pool) .await @@ -308,10 +308,7 @@ mod tests { assert_eq!( retrieved_amount.to_string(), expected_str, - "Cent-level precision not correct for input: {} (expected: {}, got: {})", - input_str, - expected_str, - retrieved_amount.to_string() + "Cent-level precision not correct for input: {input_str} (expected: {expected_str}, got: {retrieved_amount})" ); } @@ -479,8 +476,7 @@ mod tests { let threshold_amount = MoneyAmount::from_str(threshold).unwrap(); let query = format!( - "SELECT COUNT(*) as count FROM test_bids WHERE bid_amount {} ?", - operator + "SELECT COUNT(*) as count FROM test_bids WHERE bid_amount {operator} ?" ); let count_row = sqlx::query(&query) @@ -492,8 +488,7 @@ mod tests { let count: i64 = count_row.get("count"); assert_eq!( count as usize, expected_count, - "Comparison {} {} failed", - operator, threshold + "Comparison {operator} {threshold} failed" ); } @@ -524,8 +519,7 @@ mod tests { let count: i64 = count_row.get("count"); assert_eq!( count as usize, expected_count, - "BETWEEN {} AND {} failed", - min_amount, max_amount + "BETWEEN {min_amount} AND {max_amount} failed" ); } diff --git a/src/dptree_utils.rs b/src/dptree_utils.rs index 5d8a356..25c20f1 100644 --- a/src/dptree_utils.rs +++ b/src/dptree_utils.rs @@ -94,11 +94,11 @@ mod tests { #[derive(Debug, Clone, PartialEq)] enum InnerEnum { - InnerSimple, - InnerWithParam(&'static str), - InnerWithMultiple(&'static str, i32), - InnerWithStruct { field: &'static str }, - InnerWithMultiStruct { field: &'static str, number: i32 }, + Simple, + WithParam(&'static str), + WithMultiple(&'static str, i32), + WithStruct { field: &'static str }, + WithMultiStruct { field: &'static str, number: i32 }, } // Helper function for testing handlers with expected results @@ -144,29 +144,29 @@ mod tests { )] // Single parameter extraction from nested enum #[case::nested_single_match( - case![TestEnum::NestedVariant(InnerEnum::InnerWithParam(p))].endpoint(|p: &'static str| async move { p }), - TestEnum::NestedVariant(InnerEnum::InnerWithParam("nested")), + case![TestEnum::NestedVariant(InnerEnum::WithParam(p))].endpoint(|p: &'static str| async move { p }), + TestEnum::NestedVariant(InnerEnum::WithParam("nested")), Some("nested") )] #[case::nested_single_wrong_inner_variant( - case![TestEnum::NestedVariant(InnerEnum::InnerWithParam(p))].endpoint(|p: &'static str| async move { p }), - TestEnum::NestedVariant(InnerEnum::InnerSimple), + case![TestEnum::NestedVariant(InnerEnum::WithParam(p))].endpoint(|p: &'static str| async move { p }), + TestEnum::NestedVariant(InnerEnum::Simple), None )] #[case::nested_single_wrong_outer_variant( - case![TestEnum::NestedVariant(InnerEnum::InnerWithParam(p))].endpoint(|p: &'static str| async move { p }), + case![TestEnum::NestedVariant(InnerEnum::WithParam(p))].endpoint(|p: &'static str| async move { p }), TestEnum::DefaultVariant, None )] // Single field extraction from nested struct #[case::struct_field_match( - case![TestEnum::NestedVariant(InnerEnum::InnerWithStruct { field })].endpoint(|field: &'static str| async move { field }), - TestEnum::NestedVariant(InnerEnum::InnerWithStruct { field: "struct_value" }), + case![TestEnum::NestedVariant(InnerEnum::WithStruct { field })].endpoint(|field: &'static str| async move { field }), + TestEnum::NestedVariant(InnerEnum::WithStruct { field: "struct_value" }), Some("struct_value") )] #[case::struct_field_no_match( - case![TestEnum::NestedVariant(InnerEnum::InnerWithStruct { field })].endpoint(|field: &'static str| async move { field }), - TestEnum::NestedVariant(InnerEnum::InnerSimple), + case![TestEnum::NestedVariant(InnerEnum::WithStruct { field })].endpoint(|field: &'static str| async move { field }), + TestEnum::NestedVariant(InnerEnum::Simple), None )] #[tokio::test] @@ -202,8 +202,8 @@ mod tests { // Test cases for nested multiple parameter extraction #[rstest::rstest] - #[case(TestEnum::NestedVariant(InnerEnum::InnerWithMultiple("nested", 123)), Some(("nested", 123)))] - #[case(TestEnum::NestedVariant(InnerEnum::InnerSimple), None)] + #[case(TestEnum::NestedVariant(InnerEnum::WithMultiple("nested", 123)), Some(("nested", 123)))] + #[case(TestEnum::NestedVariant(InnerEnum::Simple), None)] #[case(TestEnum::DefaultVariant, None)] #[tokio::test] async fn test_nested_multiple_parameter_extraction( @@ -211,7 +211,7 @@ mod tests { #[case] expected_params: Option<(&'static str, i32)>, ) { let handler: Handler<'static, (&str, i32), DpHandlerDescription> = - case![TestEnum::NestedVariant(InnerEnum::InnerWithMultiple(s, n))] + case![TestEnum::NestedVariant(InnerEnum::WithMultiple(s, n))] .endpoint(|params: (&'static str, i32)| async move { params }); let input = deps![input_variant]; @@ -225,8 +225,8 @@ mod tests { // Test cases for struct pattern extraction #[rstest::rstest] - #[case(TestEnum::NestedVariant(InnerEnum::InnerWithStruct { field: "struct_field" }), Some("struct_field"))] - #[case(TestEnum::NestedVariant(InnerEnum::InnerSimple), None)] + #[case(TestEnum::NestedVariant(InnerEnum::WithStruct { field: "struct_field" }), Some("struct_field"))] + #[case(TestEnum::NestedVariant(InnerEnum::Simple), None)] #[case(TestEnum::DefaultVariant, None)] #[tokio::test] async fn test_struct_pattern_extraction( @@ -234,10 +234,8 @@ mod tests { #[case] expected_field: Option<&'static str>, ) { let handler: Handler<'static, &str, DpHandlerDescription> = - case![TestEnum::NestedVariant(InnerEnum::InnerWithStruct { - field - })] - .endpoint(|field: &'static str| async move { field }); + case![TestEnum::NestedVariant(InnerEnum::WithStruct { field })] + .endpoint(|field: &'static str| async move { field }); let input = deps![input_variant]; let result = handler.dispatch(input).await; @@ -250,8 +248,8 @@ mod tests { // Test cases for multi-field struct pattern extraction #[rstest::rstest] - #[case(TestEnum::NestedVariant(InnerEnum::InnerWithMultiStruct { field: "multi_field", number: 42 }), Some(("multi_field", 42)))] - #[case(TestEnum::NestedVariant(InnerEnum::InnerSimple), None)] + #[case(TestEnum::NestedVariant(InnerEnum::WithMultiStruct { field: "multi_field", number: 42 }), Some(("multi_field", 42)))] + #[case(TestEnum::NestedVariant(InnerEnum::Simple), None)] #[case(TestEnum::DefaultVariant, None)] #[tokio::test] async fn test_multi_struct_pattern_extraction( @@ -259,7 +257,7 @@ mod tests { #[case] expected_fields: Option<(&'static str, i32)>, ) { let handler: Handler<'static, (&str, i32), DpHandlerDescription> = - case![TestEnum::NestedVariant(InnerEnum::InnerWithMultiStruct { + case![TestEnum::NestedVariant(InnerEnum::WithMultiStruct { field, number })] diff --git a/src/message_utils.rs b/src/message_utils.rs index 4c5ff39..7660a86 100644 --- a/src/message_utils.rs +++ b/src/message_utils.rs @@ -143,15 +143,6 @@ pub fn create_single_button_keyboard(text: &str, callback_data: &str) -> InlineK InlineKeyboardMarkup::new([[InlineKeyboardButton::callback(text, callback_data)]]) } -// Create a keyboard with multiple buttons in a single row -pub fn create_single_row_keyboard(buttons: &[(&str, &str)]) -> InlineKeyboardMarkup { - let keyboard_buttons: Vec = buttons - .iter() - .map(|(text, callback_data)| InlineKeyboardButton::callback(*text, *callback_data)) - .collect(); - InlineKeyboardMarkup::new([keyboard_buttons]) -} - // Create a keyboard with multiple rows pub fn create_multi_row_keyboard(rows: &[&[(&str, &str)]]) -> InlineKeyboardMarkup { let mut keyboard = InlineKeyboardMarkup::default();