Rust + Iced + Tokio: Problem with async function
⚓ Rust 📅 2026-03-28 👤 surdeus 👁️ 2I am attempting to learn how to use Tokio and async functions. I want my program to startup and display a loading screen as quickly as possible and in parallel run a function to update an SQL database from a CSV file. Once the database is updated I would like the function to return a message to the iced update function so I can update several state variables and display a new screen. Below is my attempt using an async function "update_database" that is spawned via Tokio in the iced run function. It runs and the println's in the new and async functions print but the println in Message::GoToUpdateDataBaseScreen in the iced update function does not. So here is what I am trying to determine. 1) Does this code run the async function in parallel with the program booting up and displaying the loading screen and if not what have I done wrong. 2) How do I setup the update_database function so that it returns a message to the iced update function once it has completed. Below is the code. Any input will be appreciated.
async fn update_database<'a>() -> Message<> {
println!("Starting database update..."); // prints second
let record_data = match insert_csv_data_into_db().await {
Ok(data) => {
data
},
Err(_) => {
return Message::GoToUpdateDataBaseScreen(0, 0, 0)
}
};
println!("Database update completed. Records read: {}, Records inserted: {}, Records updated: {}", record_data[0], record_data[1], record_data[2]); // prints third
Message::GoToUpdateDataBaseScreen(record_data[0], record_data[1], record_data[2])
}
// #[derive(Debug, Clone)]
pub struct State {
pub records_read: u64,
pub records_inserted: u64,
pub records_updated: u64,
pub screen: Screen,
pub closing_values: Vec<QueryResults>,
pub heading: String,
}
impl State {
fn new() -> Self {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.spawn(update_database());
println!("State initialized with loading screen."); // prints first
Self {
records_read: 0,
records_inserted: 0,
records_updated: 0,
screen: Screen::LoadingScreen,
closing_values: Vec::new(),
heading: String::new(),
}
}
fn update(&mut self, msg: Message) -> Task<Message> {
match msg {
Message::GoToUpdateDataBaseScreen(records_read, records_inserted, records_updated) => {
println!("Updating database screen with records read: {}, records inserted: {}, records updated: {}", records_read, records_inserted, records_updated); // never prints
self.screen = Screen::UpdateDatabaseScreen;
self.records_read = records_read;
self.records_inserted = records_inserted;
self.records_updated = records_updated;
Task::none()
}
Message::Exit => {
std::process::exit(0);
}
Message::GoToHomeScreen => {
self.screen = Screen::HomeScreen;
self.records_read = 0;
self.records_inserted = 0;
Task::none()
}
Message::GoToMinCloseScreen | Message::GoToMaxCloseScreen | Message::GoToAllCloseScreen => {
self.screen = Screen::ClosingScreen;
let query_results = match msg {
Message::GoToMinCloseScreen => get_close(QueryType::Min),
Message::GoToMaxCloseScreen => get_close(QueryType::Max),
Message::GoToAllCloseScreen => get_close(QueryType::All),
_ => unreachable!(),
};
let query_results = match query_results {
Ok(results) => results,
Err(e) => {
if let IoSqlError::IoError(io_err) = e {
println!("I/O error details: {}", io_err);
} else if let IoSqlError::SqlError(sql_err) = e {
println!("SQL error details: {}", sql_err);
}
return Task::none();
}
};
self.heading = match msg {
Message::GoToMinCloseScreen => "Minimum Closing Prices".to_string(),
Message::GoToMaxCloseScreen => "Maximum Closing Prices".to_string(),
Message::GoToAllCloseScreen => "All Closing Prices".to_string(),
_ => unreachable!(),
};
self.closing_values = query_results;
Task::none()
}
} // end of match statement
}
fn view(&self) -> iced::Element<'_, Message> {
match self.screen {
Screen::LoadingScreen => {
loading_view()
}
Screen::HomeScreen => {
home_view()
}
Screen::UpdateDatabaseScreen => {
update_db_view(self.records_read, self.records_inserted, self.records_updated)
}
Screen::ClosingScreen => {
closeing_view(&self.heading, self.closing_values.as_ref())
}
}
} // end of view function
}
2 posts - 2 participants
🏷️ Rust_feed