parent
e5a675fe45
commit
19a3943012
File diff suppressed because it is too large
Load Diff
@ -1,47 +1,81 @@
|
|||||||
use chain::{
|
use chain::{
|
||||||
Chain,
|
Chain,
|
||||||
};
|
};
|
||||||
|
use warp::{
|
||||||
|
Filter,
|
||||||
|
Buf,
|
||||||
|
};
|
||||||
use std::{
|
use std::{
|
||||||
io::{
|
sync::Arc,
|
||||||
BufRead,
|
};
|
||||||
self,
|
use tokio::{
|
||||||
|
sync::{
|
||||||
|
RwLock,
|
||||||
},
|
},
|
||||||
|
stream::{Stream,StreamExt,},
|
||||||
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn buffered_read_all_lines<T: BufRead+?Sized, F: FnMut(&str) -> io::Result<()>>(input: &mut T, mut then: F) -> io::Result<usize>
|
const MAX_CONTENT_LENGTH: u64 = 1024 * 16;
|
||||||
{
|
const MAX_GEN_SIZE: usize = 256;
|
||||||
let mut buffer = String::new();
|
|
||||||
let mut read;
|
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 total=0;
|
let mut buffer = Vec::new();
|
||||||
while {read = input.read_line(&mut buffer)?; read!=0} {
|
|
||||||
then(&buffer[..])?;
|
while let Some(buf) = body.next().await {
|
||||||
buffer.clear();
|
let mut body = buf?;
|
||||||
total += read;
|
while body.has_remaining() {
|
||||||
|
buffer.extend_from_slice(body.bytes());
|
||||||
|
let cnt = body.bytes().len();
|
||||||
|
body.advance(cnt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(total)
|
|
||||||
|
let buffer = std::str::from_utf8(&buffer[..])?;
|
||||||
|
chain.feed_str(buffer);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[tokio::main]
|
||||||
let stdin = io::stdin();
|
async fn main() {
|
||||||
let mut stdin = stdin.lock();
|
pretty_env_logger::init();
|
||||||
let mut chain = Chain::new();
|
|
||||||
|
let chain = Arc::new(RwLock::new(Chain::new()));
|
||||||
|
let chain = warp::any().map(move || Arc::clone(&chain));
|
||||||
|
|
||||||
buffered_read_all_lines(&mut stdin, |string| {
|
let push = warp::put()
|
||||||
chain.feed(&string.split_whitespace()
|
.and(chain.clone())
|
||||||
.filter(|word| !word.is_empty())
|
.and(warp::path("put"))
|
||||||
.map(|s| s.to_owned()).collect::<Vec<_>>());
|
.and(warp::body::content_length_limit(MAX_CONTENT_LENGTH))
|
||||||
|
.and(warp::body::stream())
|
||||||
Ok(())
|
.and_then(|chain: Arc<RwLock<Chain<String>>>, buf| {
|
||||||
}).expect("Failed to read from stdin");
|
async move {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let res = format!("{:?}", full_body(chain.write().await.deref_mut(), buf).await);
|
||||||
|
Ok::<String, std::convert::Infallible>(res)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if !chain.is_empty() {
|
let read = warp::get()
|
||||||
if let Some(num) = std::env::args().skip(1).next() {
|
.and(chain.clone())
|
||||||
let sz: usize = num.parse().expect("Cannot parse number of tokens to generate");
|
.and(warp::path("get"))
|
||||||
for string in chain.str_iter_for(sz) {
|
.and(warp::path::param().map(|opt: usize| Some(opt)).or(warp::any().map(|| Option::<usize>::None)).unify())
|
||||||
println!("{}", string);
|
.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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
println!("{}", chain.generate_str());
|
|
||||||
}
|
warp::serve(push
|
||||||
}
|
.or(read))
|
||||||
|
.bind_with_graceful_shutdown(([127,0,0,1], 8777), async { tokio::signal::ctrl_c().await.unwrap(); }).1
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in new issue