nyx-scanner 0.6.0

A multi-language static analysis tool for detecting security vulnerabilities
Documentation
use crate::server::app::{AppState, ServerEvent};
use axum::Router;
use axum::extract::State;
use axum::response::sse::{Event, KeepAlive, Sse};
use axum::routing::get;
use tokio_stream::StreamExt;
use tokio_stream::wrappers::BroadcastStream;

pub fn routes() -> Router<AppState> {
    Router::new().route("/events", get(event_stream))
}

async fn event_stream(
    State(state): State<AppState>,
) -> Sse<impl tokio_stream::Stream<Item = Result<Event, std::convert::Infallible>>> {
    let rx = state.event_tx.subscribe();
    let stream = BroadcastStream::new(rx).filter_map(|result: Result<ServerEvent, _>| {
        let event = result.ok()?;
        let data = match serde_json::to_string(&event) {
            Ok(s) => s,
            Err(err) => {
                tracing::warn!(error = %err, "failed to serialize server event; dropping");
                return None;
            }
        };
        let event_type = match &event {
            ServerEvent::ScanStarted { .. } => "scan_started",
            ServerEvent::ScanCompleted { .. } => "scan_completed",
            ServerEvent::ScanFailed { .. } => "scan_failed",
            ServerEvent::ScanProgress { .. } => "scan_progress",
            ServerEvent::ConfigChanged => "config_changed",
        };
        Some(Ok(Event::default().event(event_type).data(data)))
    });

    Sse::new(stream).keep_alive(KeepAlive::default())
}