rustapi-core 0.1.550

The core engine of the RustAPI framework. Provides the hyper-based HTTP server, router, extraction logic, and foundational traits.
Documentation
#![cfg(feature = "http3-dev")]

use rustapi_core::RustApi;
use std::net::UdpSocket;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::oneshot;

#[tokio::test]
async fn run_http3_dev_with_shutdown_runs_lifecycle_hooks() {
    let on_start = Arc::new(AtomicBool::new(false));
    let on_shutdown = Arc::new(AtomicBool::new(false));
    let on_start_flag = on_start.clone();
    let on_shutdown_flag = on_shutdown.clone();

    let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
    let port = socket.local_addr().unwrap().port();
    drop(socket);

    let addr = format!("127.0.0.1:{port}");
    let app = RustApi::new()
        .health_endpoints()
        .on_start(move || {
            let on_start_flag = on_start_flag.clone();
            async move {
                on_start_flag.store(true, Ordering::SeqCst);
            }
        })
        .on_shutdown(move || {
            let on_shutdown_flag = on_shutdown_flag.clone();
            async move {
                on_shutdown_flag.store(true, Ordering::SeqCst);
            }
        });

    let (tx, rx) = oneshot::channel();
    let server = tokio::spawn(async move {
        app.run_http3_dev_with_shutdown(&addr, async {
            rx.await.ok();
        })
        .await
    });

    tokio::time::sleep(Duration::from_millis(500)).await;
    assert!(
        on_start.load(Ordering::SeqCst),
        "on_start should run via prepare_for_serve before HTTP/3 accept loop"
    );

    tx.send(()).unwrap();
    let _ = tokio::time::timeout(Duration::from_secs(3), server).await;
    assert!(
        on_shutdown.load(Ordering::SeqCst),
        "on_shutdown should run after HTTP/3 shutdown signal"
    );
}