//! Feeding the chain use super::*; fn feed(chain: &mut Chain, what: impl AsRef) { chain.feed(what.as_ref().split_whitespace() .filter(|word| !word.is_empty()) .map(|s| s.to_owned()).collect::>()); } pub async fn full(who: &IpAddr, state: State, mut body: impl Unpin + Stream>) -> Result { let mut buffer = Vec::new(); let mut written = 0usize; while let Some(buf) = body.next().await { let mut body = buf.map_err(|_| FillBodyError)?; while body.has_remaining() { buffer.extend_from_slice(body.bytes()); let cnt = body.bytes().len(); body.advance(cnt); written += cnt; } } if !buffer.ends_with(&[b'\n']) { // probably useless eh? buffer.push(b'\n'); } let buffer = std::str::from_utf8(&buffer[..]).map_err(|_| FillBodyError)?; info!("{} -> {:?}", who, buffer); let mut chain = state.chain().write().await; feed(&mut chain, buffer); state.notify_save(); Ok(written) } #[derive(Debug)] pub struct FillBodyError; impl error::Error for FillBodyError{} impl warp::reject::Reject for FillBodyError{} impl fmt::Display for FillBodyError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "failed to feed chain with this data") } }