Help with modelling ui loop with async

I want to create a library that can perform many tasks without blocking the main thread. These tasks would include

  • Web requests
  • File writes/moves/etc
  • (de)compressing archives
  • getting input from user (ui events)
  • others

I want these tasks to be cancellable, and also to report their progress to the main thread.

What I don't really know is what model to use on the main thread. ideally I could make that async as well, and do a big select on all possible events (where I could actually run the whole thing on one thread). Maybe something like

struct Scheduler {
    downloads: Vec<reqwest::Response>,
    // ... ui stuff etc

enum SchedulerEvent<'a> {
    DownloadProgress(&'a reqwest::Response),
    // ... ui events etc

impl Scheduler {
    async fn next_event(&self) -> SchedulerEvent {
        // select the next event

Then your main function could be (assuming async fn main is a thing)

async fn main() {
    let scheduler = Scheduler::create_somehow();
    loop {
        match scheduler.next_event().await {
             // start new downloads, display progress to screen, or break loop if it's time to close

Are there any keywords I can google to find info on this kind of workflow? Does anyone have any experience with things like this? Am I doing it the best way? Any and all help is welcome.

There is at least,
though i haven't give it try yet.