rust-mjpeg-proxy/src/app.rs

80 lines
1.9 KiB
Rust

use std::sync::{Arc, RwLock};
use http::header::HeaderMap;
use tokio::sync::broadcast::{self, Sender, Receiver};
use mpart_async::server::ParseOutput;
pub type Payload = Arc<ParseOutput>;
#[derive(Clone)]
pub struct App {
state: Arc<RwLock<Option<State>>>,
}
impl App {
pub fn new() -> App {
App {
state: Arc::new(RwLock::new(None)),
}
}
pub fn source(&self, headers: HeaderMap, boundary: Vec<u8>) -> AppSource {
{
let mut state = self.state.write().unwrap();
*state = Some(State {
headers: Arc::new(headers),
boundary,
next_broadcast: broadcast::channel(128),
});
}
AppSource {
app: self.clone(),
}
}
pub fn subscribe(&self) -> Option<Receiver<Payload>> {
let state = self.state.read().unwrap();
state.as_ref().map(|state| {
let tx = &state.next_broadcast.0;
tx.subscribe()
})
}
pub fn boundary(&self) -> Vec<u8> {
let state = self.state.read().unwrap();
state.as_ref().unwrap().boundary.clone()
}
pub fn headers(&self) -> Option<Arc<HeaderMap>> {
let state = self.state.read().unwrap();
state.as_ref().map(|state| {
state.headers.clone()
})
}
}
pub struct AppSource {
app: App,
}
impl Drop for AppSource {
fn drop(&mut self) {
let mut state = self.app.state.write().unwrap();
*state = None;
}
}
impl AppSource {
pub fn begin_part(&mut self) -> Sender<Payload> {
let mut state = self.app.state.write().unwrap();
let (tx, _rx) = std::mem::replace(&mut state.as_mut().unwrap().next_broadcast, broadcast::channel(128));
tx
}
}
struct State {
headers: Arc<HeaderMap>,
boundary: Vec<u8>,
next_broadcast: (Sender<Payload>, Receiver<Payload>),
}