use blocks;
use rpc::Client;
use std::io::{Read, BufReader, BufRead};
use human_size::Size;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum BlockRecipe {
Rekey,
Info(Vec<u8>),
}
impl BlockRecipe {
pub fn info(buf: Vec<u8>) -> Result<BlockRecipe, blocks::Error> {
blocks::validate_block_size(buf.len())?;
Ok(BlockRecipe::Info(buf))
}
}
pub fn parse_size(size: &str) -> Result<usize, ()> {
let mut size = match size.parse::<Size>() {
Ok(size) => size.into_bytes() as usize,
Err(_) => size.parse().expect("invalid size"),
};
if size >= 65536 {
eprintln!("WARN: --size exceeds maximum block size, caping to 65535");
size = 65535;
}
Ok(size)
}
pub struct InfoBlockPipe<R: Read> {
pub quiet: bool,
client: Client,
src: Option<R>,
}
impl<R: Read> InfoBlockPipe<R> {
#[inline]
pub fn new(client: Client, src: R) -> InfoBlockPipe<R> {
InfoBlockPipe {
quiet: false,
client,
src: Some(src),
}
}
#[inline]
pub fn write(&mut self, buf: Vec<u8>) -> Result<(), ()> {
let block = BlockRecipe::info(buf).expect("couldn't build block recipe");
let pointer = self.client.write_block(block).expect("write block");
if !self.quiet {
println!("{:x}", pointer);
}
Ok(())
}
#[inline]
pub fn start_lines(&mut self) {
let src = BufReader::new(self.src.take().unwrap());
for line in src.lines() {
if let Ok(mut line) = line {
line.push('\n');
self.write(line.as_bytes().to_vec()).expect("write failed");
}
}
}
#[inline]
pub fn start_bytes(&mut self, size: usize) {
let mut src = self.src.take().unwrap();
let mut buf = vec![0; size];
loop {
let i = src.read(&mut buf).unwrap();
if i == 0 {
break;
}
self.write(buf[..i].to_vec()).expect("write failed");
}
}
}