clippet 0.1.8

Provides a teeny way to have some nice byte structures that's easy to use.
Documentation
//! Provides a teeny way to have some nice byte structures that's easy to use.
//! It's all provided in one structure and many function implementation.
use bytes::BytesMut;
use std::io::BufReader;
use std::io::prelude::*;
use std::fs::File;

/// A structure for containing chunks of data and information about it.
/// The label field is useful for storing things like MIME types.
/// The size field is automatically increased when you append to the data field.
#[derive(Debug)]
pub struct Clippet {
	label: String,
	size: i32,
	data: Vec<BytesMut>,
}

impl Clippet {
	/// Returns the label field.
	///
	/// ```no_run
	/// let data = Clippet { label : "Hello!".to_string(), ... };
	/// assert_eq!(data.get_label(), "Hello!")
	/// ```
	pub fn get_label(&self) -> String {
		return self.label.to_string()
	}
	/// Changes the label field.
	///
	/// ```no_run
	/// let data = Clippet { ... };
	/// assert_eq!(data.set_label("Hello!"), true);
	/// ```
	pub fn set_label(&mut self, label: &str) -> bool {
		self.label = label.to_string();
		if &self.label == label {
			return true
		} else {
			return false
		}
	}
	/// Appends a sequence of bytes to the Clippet structure.
	/// Also increases the size field by one.
	///
	/// ```no_run
	/// let bytes = BytesMut::from("Hello, world!");
	/// let mut data = Clippet { ... };
	/// data.add_bytes(bytes);
	/// ```
	pub fn add_bytes(&mut self, bytes: BytesMut) {
		self.data.push(bytes);
		self.size = self.size + 1;
	}
	/// Removes a sequence of bytes from the Clippet structure.
	/// Also decreases the size field by one.
	///
	/// ```no_run
	/// let mut data = Clippet { ... };
	/// data.get_size() // e.g. 10
	/// data.drop_bytes(5) // drops 6th sequence of bytes
	/// data.get_size() // 9
	/// ```
	pub fn drop_bytes(&mut self, index: usize) {
		self.data.remove(index);
		self.size = self.size - 1;
	}
	/// Returns the size of the data field.
	///
	/// ```no_run
	/// let data = Clippet { ... };
	/// assert_eq!(data.get_size(), 0);
	/// ```
	pub fn get_size(&self) -> i32 {
		return self.size
	}
	/// Returns a sequence of bytes.
	///
	/// ```no_run
	/// let bytes = BytesMut::from("Hello, world!");
	/// let mut data = Clippet { ... };
	/// data.add_bytes(bytes);
	/// assert_eq!(data.get_data(0), bytes);
	/// ```
	pub fn get_data(&self, index: usize) -> BytesMut {
		return self.data[index].to_owned()
	}
	/// Takes an indexed byte sequence and returns it as a String.
	/// ```no_run
	/// let bytes = BytesMut::from("Hello, world!");
	/// let mut data = Clippet { ... };
	/// data.add_bytes(bytes);
	/// assert_eq!(data.get_as_string(0), "Hello, world!");
	/// ```
	pub fn get_as_string(&self, index: usize) -> String {
		let bytes = self.get_data(index);
		let y = bytes.as_ref();
		let x = String::from_utf8_lossy(y).to_string();
		return x
	}
	/// Takes a filename and splits it into sequences of bytes within a Clippet.
	/// It is recommended to use smaller byte sequences, however this is user-configurable.
	///
	/// ```no_run
	/// let data = Clippet::from_file("example.txt", 512);
	/// ```
	pub fn from_file(name: &str, size: usize) -> Clippet {
		let mut i = false;
		let mut data: Vec<BytesMut> = vec![];
		let f = File::open(name).unwrap();
		let mut reader = BufReader::with_capacity(size, f);
		while !i {
			let buffer = reader.fill_buf().unwrap();
			let bytes = BytesMut::from(buffer);
			data.push(bytes);
			let length = buffer.len();
			if length < size { i = true; }
			reader.consume(length);
		}
		let clip = Clippet { label: "".to_string(), size: data.len() as i32, data: data };
		return clip
		
	}
	/// Takes a sequence of bytes and wraps it around a Clippet structure.
	///
	/// ```no_run
	/// let data = Clippet::from_bytes(foo);
	/// ```
	pub fn from_bytes(bytes: BytesMut) -> Clippet {
		let clip = Clippet { label: "".to_string(), size: 1, data: vec![bytes] };
		return clip
	}
	/// Alias of `get_size(&self)`
	pub fn len(&self) -> i32 {
		return self.get_size()
	}
	/// Takes a string and splits it into sequences of bytes within a Clippet.
	/// It is recommended to use smaller byte sequences, however this is user-configurable.
	/// This uses a string reference.
	///
	/// ```no_run
	/// let data = Clippet::from_string("Lorem ipsum dolor amet...", 512);
	/// ```
	pub fn from_string(str: &str, size: usize) -> Clippet {
		let mut i = false;
		let mut data: Vec<BytesMut> = vec![];
		let string = str.as_bytes();
		let mut reader = BufReader::with_capacity(size, string);
		while !i {
			let buffer = reader.fill_buf().unwrap();
			let bytes = BytesMut::from(buffer);
			data.push(bytes);
			let length = buffer.len();
			if length < size { i = true; }
			reader.consume(length);
		}
		let clip = Clippet { label: "".to_string(), size: data.len() as i32, data: data };
		return clip
		
	}
	/// Consumes the Clippet, combines all of its byte sequences and outputs them as a String literal.
	///
	/// ```no_run
	/// let data = Clippet::from_string("Hello, World!", 512);
	/// println!("{}", data.combine()); /// Hello, World!
	/// ```
	pub fn combine(self) -> String {
		let mut string = "".to_string();
		for v in self.data {
			let y = v.as_ref();
			let x = String::from_utf8_lossy(y).to_string();
			if string == "".to_string() {
				string = x;
			} else {
				string = format!("{}{}", string, x);
			}
		}
		return string
	}
	/// Replaces the Clippet with one that has all of its data in one chunk.
	/// The label is retained, the data is not modified apart from being dechunked.
	///
	/// ```no_run
	/// let data = Clippet::from_string("HelloWorld", 5); // [b"Hello", b"World"]
	/// let data = data.dechunk(); // [b"HelloWorld"]
	/// ```
	pub fn dechunk(self) -> Clippet {
		// Retain label.
		let label = self.label.to_string();
		let data = self.combine();
		let clip = Clippet { label: label, size: 1, data: vec![BytesMut::from(data.as_str())] };
		return clip
	}
	/// Combines the Clippet and then remakes it, retaining the label, with the specified max chunk size.
	/// No data is modified.
	///
	/// ```no_run
	/// let longstring = "long string bla bla bla..."; // Pretend this is 2KB large!
	/// let data = Clippet::from_string(longstring, 512); // size: 4
	/// let data = data.rechunk(1024) // size: 2
	/// ```
	pub fn rechunk(self, size: usize) -> Clippet {
		let label = self.label.to_string();
		let data = self.combine();
		let mut clip = Clippet::from_string(&data, size);
		if label != "".to_string() { clip.label = label; }
		return clip
	}
}