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/main.rs

82 lines
2.1 KiB

4 years ago
use chain::{
Chain,
};
4 years ago
use warp::{
Filter,
Buf,
};
4 years ago
use std::{
4 years ago
sync::Arc,
};
use tokio::{
sync::{
RwLock,
4 years ago
},
4 years ago
stream::{Stream,StreamExt,},
prelude::*,
4 years ago
};
4 years ago
const MAX_CONTENT_LENGTH: u64 = 1024 * 16;
const MAX_GEN_SIZE: usize = 256;
async fn full_body(chain: &mut Chain<String>, mut body: impl Unpin + Stream<Item = Result<impl Buf, impl std::error::Error + 'static>>) -> Result<(), Box<dyn std::error::Error>> {
let mut buffer = Vec::new();
while let Some(buf) = body.next().await {
let mut body = buf?;
while body.has_remaining() {
buffer.extend_from_slice(body.bytes());
let cnt = body.bytes().len();
body.advance(cnt);
}
4 years ago
}
4 years ago
let buffer = std::str::from_utf8(&buffer[..])?;
chain.feed_str(buffer);
Ok(())
4 years ago
}
4 years ago
#[tokio::main]
async fn main() {
pretty_env_logger::init();
let chain = Arc::new(RwLock::new(Chain::new()));
let chain = warp::any().map(move || Arc::clone(&chain));
4 years ago
4 years ago
let push = warp::put()
.and(chain.clone())
.and(warp::path("put"))
.and(warp::body::content_length_limit(MAX_CONTENT_LENGTH))
.and(warp::body::stream())
.and_then(|chain: Arc<RwLock<Chain<String>>>, buf| {
async move {
use std::ops::DerefMut;
let res = format!("{:?}", full_body(chain.write().await.deref_mut(), buf).await);
Ok::<String, std::convert::Infallible>(res)
}
});
4 years ago
4 years ago
let read = warp::get()
.and(chain.clone())
.and(warp::path("get"))
.and(warp::path::param().map(|opt: usize| Some(opt)).or(warp::any().map(|| Option::<usize>::None)).unify())
.and_then(|chain: Arc<RwLock<Chain<String>>>, num: Option<usize>| {
async move {
let chain = chain.read().await;
if chain.is_empty() {
Ok(String::default())
} else {
match num {
Some(num) if num < MAX_GEN_SIZE => Ok(chain.str_iter_for(num).collect()),
_ => Ok::<String, std::convert::Infallible>(chain.generate_str()),
}
}
4 years ago
}
4 years ago
});
warp::serve(push
.or(read))
.bind_with_graceful_shutdown(([127,0,0,1], 8777), async { tokio::signal::ctrl_c().await.unwrap(); }).1
.await
4 years ago
}