69 lines
1.5 KiB
Rust
69 lines
1.5 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>) -> Sender<Payload> {
|
|
let (tx, _rx) = broadcast::channel(128);
|
|
let mut state = self.state.write().unwrap();
|
|
*state = Some(State {
|
|
headers: Arc::new(headers),
|
|
boundary,
|
|
tx: tx.clone(),
|
|
});
|
|
|
|
tx
|
|
}
|
|
|
|
// TODO: async drop til 1st header
|
|
pub fn subscribe(&self) -> Option<Receiver<Payload>> {
|
|
let state = self.state.read().unwrap();
|
|
state.as_ref().map(|state| {
|
|
state.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;
|
|
}
|
|
}
|
|
|
|
struct State {
|
|
headers: Arc<HeaderMap>,
|
|
boundary: Vec<u8>,
|
|
tx: Sender<Payload>,
|
|
}
|