working example

serve
Avril 4 years ago
parent e5a675fe45
commit 19a3943012
Signed by: flanchan
GPG Key ID: 284488987C31F630

1446
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -8,4 +8,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
chain = {package = "markov", version = "1.1.0"} chain = {package = "markov", version = "1.1.0"}
tokio = {version = "0.2", features=["full"]}
warp = "0.2"
pretty_env_logger = "0.4.0"

@ -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…
Cancel
Save