🐸 Frogue(Fed)

~ololduck/Frogue

Raw

//! SSH TUI module - provides terminal UI over SSH channels.

pub mod register;

use std::io::{self, Write};
use std::sync::Arc;

use tokio::sync::mpsc;
use tracing::debug;

/// A writer that sends bytes to an SSH channel via an mpsc channel.
///
/// This bridges synchronous writes (needed by crossterm/ratatui) to the
/// asynchronous SSH channel.
pub struct ChannelWriter {
    tx: mpsc::UnboundedSender<Vec<u8>>,
}

impl ChannelWriter {
    pub fn new(tx: mpsc::UnboundedSender<Vec<u8>>) -> Self {
        Self { tx }
    }
}

impl Write for ChannelWriter {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.tx
            .send(buf.to_vec())
            .map_err(|e| io::Error::new(io::ErrorKind::BrokenPipe, e.to_string()))?;
        Ok(buf.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

/// Runs the registration TUI over SSH.
///
/// Spawns the registration form and handles input/output through the provided
/// channels.
pub async fn run_registration(
    input_rx: &mut mpsc::UnboundedReceiver<Vec<u8>>,
    output_tx: mpsc::UnboundedSender<Vec<u8>>,
    verified_key: Option<russh::keys::ssh_key::PublicKey>,
    state: Arc<tokio::sync::RwLock<crate::AppState>>,
) -> Result<Option<crate::entities::users::Model>, Box<dyn std::error::Error + Send + Sync>> {
    debug!("starting registration TUI");

    register::run_registration_form(input_rx, output_tx, verified_key, state).await
}