You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
genmarkov/src/api/single.rs

48 lines
1.2 KiB

//! Handler for /single/
use super::*;
//TODO: Change to stream impl like normal `feed` has, instead of taking aggregate?
pub async fn single_stream(host: IpAddr, num: Option<usize>, body: impl Buf) -> Result<BoxStream<'static, Result<String, Infallible>>, ApiError>
{
let body = aggregate(body)?;
info!("{} <- {:?}", host, &body[..]);
let mut chain = Chain::new();
if_debug! {
let timer = std::time::Instant::now();
}
cfg_if! {
if #[cfg(feature="split-newlines")] {
for body in body.split('\n').filter(|line| !line.trim().is_empty()) {
feed::feed(&mut chain, body, 1..);
}
}else {
feed::feed(&mut chain, body, 1..);
}
}
if_debug!{
trace!("Write took {}ms", timer.elapsed().as_millis());
}
if chain.is_empty() {
Ok(stream::empty().boxed())
} else {
match num {
None => Ok(stream::iter(iter::once(Ok(chain.generate_str()))).boxed()),
Some(num) => {
let (mut tx, rx) = mpsc::channel(num);
tokio::spawn(async move {
for string in chain.str_iter_for(num) {
if let Err(e) = tx.send(string).await {
error!("Failed to send string to body, aborting: {:?}", e.0);
break;
}
}
});
Ok(StreamExt::map(rx, |x| Ok::<_, Infallible>(x)).boxed())
}
}
}
}