80 lines
1.9 KiB
Rust
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>),
|
|
}
|