Skip to content

Latest commit

 

History

History

time

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

⏳ time-lib

Asynchronous Rust library to manage synchronized timers.

Features

  • Create custom timers using cycles and handlers.
  • Use pre-defined timers like Pomodoro or 52/17.
  • Servers control the timer and can bind to multiple protocols simultaneously
  • Clients can connect simultaneously to the same server
  • Supports tokio and async-std async runtimes

See the full API documentation on docs.rs.

Concept

The core concept is the timer, which contains information about the time cycle and the state.

The server runs the timer and accepts connections from clients using binders. It can bind using multiple binders, using different protocols (the default one is TCP, but you can create your own).

The client controls the server's timer using requests and responses. Multiple clients can connect to the same server.

┌────────────────────────┐
│Server                  │
│             ┌────────┐ │ Request ┌────────┐
│             │        │◄├─────────┤        │
│    ┌────────┤Binder A│ │         │Client A│
│    │        │        ├─┼────────►│        │
│    │        └────────┘ │Response └────────┘
│    │                   │
│    ▼        ┌────────┐ │         ┌────────┐
│ ┌─────┐     │        │◄├─────────┤        │
│ │Timer│◄────┤Binder B│ │         │Client B│
│ └─────┘     │        ├─┼────────►│        │
│    ▲        └────────┘ │         └────────┘
│    │                   │
│    │        ┌────────┐ │         ┌────────┐
│    │        │        │◄├─────────┤        │
│    └────────┤Binder C│ │         │Client C│
│             │        ├─┼────────►│        │
│             └────────┘ │         └────────┘
│                        │
└────────────────────────┘

Examples

use std::time::Duration;

use time::{
    client::tcp::TcpClient,
    server::{tcp::TcpBind, ServerBuilder, ServerEvent},
    timer::TimerEvent,
};

static HOST: &str = "127.0.0.1";
static PORT: u16 = 3000;

#[tokio::main]
async fn main() {
    let server = ServerBuilder::new()
        .with_server_handler(|event: ServerEvent| async move {
            println!("server event: {event:?}");
            Ok(())
        })
        .with_timer_handler(|event: TimerEvent| async move {
            println!("timer event: {event:?}");
            Ok(())
        })
        .with_binder(TcpBind::new(HOST, PORT))
        .with_pomodoro_config()
        .build()
        .unwrap();

    server
        .bind_with(|| async {
            // wait for the binder to be ready
            tokio::time::sleep(Duration::from_secs(1)).await;

            let client = TcpClient::new_boxed(HOST, PORT);

            client.start().await.unwrap();
            tokio::time::sleep(Duration::from_secs(1)).await;

            client.pause().await.unwrap();
            tokio::time::sleep(Duration::from_secs(1)).await;

            let timer = client.get().await.unwrap();
            println!("current timer: {timer:?}");

            Ok(())
        })
        .await
        .unwrap();
}

Other examples can be found at ./examples:

cargo run --example

Sponsoring

nlnet

Special thanks to the NLnet foundation and the European Commission that helped the project to receive financial support from various programs:

If you appreciate the project, feel free to donate using one of the following providers:

GitHub Ko-fi Buy Me a Coffee Liberapay thanks.dev PayPal