[][src]Struct no_proto::buffer::NP_Buffer

pub struct NP_Buffer<'buffer> { /* fields omitted */ }

Buffers contain the bytes of each object and allow you to perform reads, updates, deletes and compaction.

Implementations

impl<'buffer> NP_Buffer<'buffer>[src]

pub fn json_encode(&self, path: &'buffer [&str]) -> Result<NP_JSON, NP_Error>[src]

Copy an object at the provided path and all it's children into JSON.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "table",
   "columns": [
        ["age", {"type": "uint8"}],
        ["name", {"type": "string"}]
    ]
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
new_buffer.set(&["name"], "Jeb Kermin");
new_buffer.set(&["age"], 30u8);
 
assert_eq!("{\"name\":\"Jeb Kermin\",\"age\":30}", new_buffer.json_encode(&[])?.stringify());
assert_eq!("\"Jeb Kermin\"", new_buffer.json_encode(&["name"])?.stringify());
 

pub fn close(self) -> Vec<u8>[src]

Moves the underlying bytes out of the buffer, consuming the buffer in the process.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set initial value
new_buffer.set(&[], "hello")?;
// close buffer and get bytes
let bytes: Vec<u8> = new_buffer.close();
assert_eq!([1, 1, 0, 4, 0, 5, 104, 101, 108, 108, 111].to_vec(), bytes);
 

pub fn read_bytes(&self) -> &Vec<u8>[src]

Read the bytes of the buffer immutably. No touching!

pub fn move_cursor(&mut self, path: &[&str]) -> Result<bool, NP_Error>[src]

Move buffer cursor to new location. Cursors can only be moved into children. If you need to move up reset the cursor to root, then move back down to the desired level.

pub fn cursor_to_root(&mut self)[src]

Reset cursor position to root of buffer

pub fn set<X>(&mut self, path: &[&str], value: X) -> Result<bool, NP_Error> where
    X: NP_Value<'buffer> + NP_Scalar
[src]

Used to set scalar values inside the buffer, the path only works with dot notation.

The type that you cast the request to will be compared to the schema, if it doesn't match the schema the request will fail.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
// a list where each item is a map where each key has a value containing a list of strings
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
   "of": {"type": "map", "value": {
        "type": "list", "of": {"type": "string"}
    }}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// third item in the top level list -> key "alpha" of map at 3rd element -> 9th element of list at "alpha" key
// 
new_buffer.set(&["3", "alpha", "9"], "look at all this nesting madness")?;
 
// get the same item we just set
let message = new_buffer.get::<&str>(&["3", "alpha", "9"])?;
 
assert_eq!(message, Some("look at all this nesting madness"));
 

pub fn get_iter<'iter>(
    &'iter self,
    path: &'iter [&str]
) -> Result<Option<NP_Generic_Iterator<'iter>>, NP_Error>
[src]

Get an iterator for a collection

List Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
    "of": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set value at 1 index
new_buffer.set(&["1"], "hello")?;
// set value at 4 index
new_buffer.set(&["4"], "world")?;
// push value onto the end
new_buffer.list_push(&[], "!")?;
 
// get iterator of root (list item)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
    match item.index {
        0 => assert_eq!(item.get::<&str>().unwrap(), None),
        1 => assert_eq!(item.get::<&str>().unwrap(), Some("hello")),
        2 => assert_eq!(item.get::<&str>().unwrap(), None),
        3 => assert_eq!(item.get::<&str>().unwrap(), None),
        4 => assert_eq!(item.get::<&str>().unwrap(), Some("world")),
        5 => assert_eq!(item.get::<&str>().unwrap(), Some("!")),
        _ => panic!()
    };
});
 

Table Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "table",
   "columns": [
        ["age", {"type": "uint8"}],
        ["name", {"type": "string"}],
        ["job", {"type": "string"}],
        ["tags", {"type": "list", "of": {"type": "string"}}]
    ]
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set value of age
new_buffer.set(&["age"], 20u8)?;
// set value of name
new_buffer.set(&["name"], "Bill Kerman")?;
// push value onto tags list
new_buffer.list_push(&["tags"], "rocket")?;
 
// get iterator of root (table)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
     
    match item.get_key() {
        "name" => assert_eq!(item.get::<&str>().unwrap(), Some("Bill Kerman")),
        "age" =>  assert_eq!(item.get::<u8>().unwrap(), Some(20)),
        "job" => assert_eq!(item.get::<&str>().unwrap(), None),
        "tags" => { /* tags column is list, can't do anything with it here */ },
        _ => { panic!() }
    };
});
 
// we can also loop through items of the tags list
new_buffer.get_iter(&["tags"])?.unwrap().into_iter().for_each(|item| {
    assert_eq!(item.index, 0);
    assert_eq!(item.get::<&str>().unwrap(), Some("rocket"));
});
 

Map Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "map",
   "value": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set value of color key
new_buffer.set(&["color"], "blue")?;
// set value of sport key
new_buffer.set(&["sport"], "soccor")?;
 
// get iterator of root (map)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
    println!("hello");
    match item.get_key() {
        "color" => assert_eq!(item.get::<&str>().unwrap(), Some("blue")),
        "sport" => assert_eq!(item.get::<&str>().unwrap(), Some("soccor")),
        _ => panic!()
    }
});
 

Tuple Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "tuple",
    "values": [
        {"type": "string"},
        {"type": "u8"},
        {"type": "bool"}
    ]
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set value at 0 index
new_buffer.set(&["0"], "hello")?;
// set value at 2 index
new_buffer.set(&["2"], false)?;
 
// get iterator of root (tuple item)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
    match item.index {
        0 => assert_eq!(item.get::<&str>().unwrap(), Some("hello")),
        1 => assert_eq!(item.get::<u8>().unwrap(), None),
        2 => assert_eq!(item.get::<bool>().unwrap(), Some(false)),
        _ => panic!()
    };
});
 

pub fn fast_insert<X>(&mut self, key: &str, value: X) -> Result<bool, NP_Error> where
    X: NP_Value<'buffer> + NP_Scalar
[src]

Allows quick and efficient inserting into lists, maps and tables. CAREFUL. Unlike the set method, this one does not check for existing records with the provided key. This works for Lists, Maps and Tables.

You get a very fast insert into the buffer at the desired key, but you must gaurantee that you're not inserting a key that's already been inserted..

This method will let you insert duplicate keys all day long, then when you go to compact the buffer the duplicates will not be deleted.

This is best used to quickly fill data into a new buffer.

pub fn list_push<X>(
    &mut self,
    path: &[&str],
    value: X
) -> Result<Option<u16>, NP_Error> where
    X: NP_Value<'buffer> + NP_Scalar
[src]

Push a value onto the end of a list. The path provided must resolve to a list type, and the type being pushed must match the schema

This is the most efficient way to add values to a list type.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
    "of": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
new_buffer.set(&["3"], "launch")?;
new_buffer.list_push(&[], "this")?;
new_buffer.list_push(&[], "rocket")?;
 
// get iterator of root (list item)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
    match item.index {
        0 => assert_eq!(item.get::<&str>().unwrap(), None),
        1 => assert_eq!(item.get::<&str>().unwrap(), None),
        2 => assert_eq!(item.get::<&str>().unwrap(), None),
        3 => assert_eq!(item.get::<&str>().unwrap(), Some("launch")),
        4 => assert_eq!(item.get::<&str>().unwrap(), Some("this")),
        5 => assert_eq!(item.get::<&str>().unwrap(), Some("rocket")),
        _ => panic!()
    };
});
 
let mut new_buffer = factory.empty_buffer(None, None);
new_buffer.list_push(&[], "launch")?;
new_buffer.list_push(&[], "this")?;
new_buffer.list_push(&[], "rocket")?;
 
// get iterator of root (list item)
new_buffer.get_iter(&[])?.unwrap().into_iter().for_each(|item| {
    match item.index {
        0 => assert_eq!(item.get::<&str>().unwrap(), Some("launch")),
        1 => assert_eq!(item.get::<&str>().unwrap(), Some("this")),
        2 => assert_eq!(item.get::<&str>().unwrap(), Some("rocket")),
        _ => panic!()
    };
});
 

pub fn get_type(
    &self,
    path: &[&str]
) -> Result<Option<&'buffer NP_TypeKeys>, NP_Error>
[src]

Get the schema info at a specific path, works for an type

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::schema::NP_TypeKeys;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// get schema of root
let type_key = new_buffer.get_type(&[])?.unwrap();
 
let is_string = match type_key {
    NP_TypeKeys::UTF8String  => {
        true
    },
    _ => false
};
 
assert!(is_string);
 
 

pub fn length(&self, path: &[&str]) -> Result<Option<usize>, NP_Error>[src]

Get length of String, Bytes, Table, Tuple, List or Map Type

If the type found at the path provided does not support length operations, you'll get None.

If the length of the item is zero, you can expect Some(0).

String Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set initial value
new_buffer.set(&[], "hello")?;
// get length of value at root (String)
assert_eq!(new_buffer.length(&[])?, Some(5));
 

Collection (List) Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
    "of": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set value at 9th index
new_buffer.set(&["9"], "hello")?;
// get length of value at root (List)
assert_eq!(new_buffer.length(&[])?, Some(10));
 

Collection (Table) Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "table",
   "columns": [
        ["age", {"type": "u8"}],
        ["name", {"type": "string"}]
    ]
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// get length of value at root (Table)
assert_eq!(new_buffer.length(&[])?, Some(2));
 

Collection (Map) Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "map",
   "value": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set values
new_buffer.set(&["foo"], "bar")?;
new_buffer.set(&["foo2"], "bar2")?;
// get length of value at root (Map)
assert_eq!(new_buffer.length(&[])?, Some(2));
 

Collection (Tuple) Example

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "tuple",
   "values": [
        {"type": "string"}, 
        {"type": "string"}
    ]
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// get length of value at root (Tuple)
assert_eq!(new_buffer.length(&[])?, Some(2));
 

pub fn del(&mut self, path: &[&str]) -> Result<bool, NP_Error>[src]

Clear an inner value from the buffer. The path only works with dot notation. This can also be used to clear deeply nested collection objects or scalar objects.

Returns true if it deleted a value, false otherwise.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
    "of": {"type": "string"}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set index 0
new_buffer.set(&["0"], "hello")?;
// del index 0
new_buffer.del(&["0"])?;
// value is gone now!
assert_eq!(None, new_buffer.get::<&str>(&["0"])?);
 

pub fn get<'get, X: 'get>(
    &'get self,
    path: &'get [&str]
) -> Result<Option<X>, NP_Error> where
    X: NP_Value<'get> + NP_Scalar
[src]

Retrieve an inner value from the buffer. The path only works with dot notation.

The type that you cast the request to will be compared to the schema, if it doesn't match the schema the request will fail.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
// a list where each item is a map where each key has a value containing a list of strings
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "list",
   "of": {"type": "map", "value": {
        "type": "list", "of": {"type": "string"}
    }}
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// third item in the top level list -> key "alpha" of map at 3rd element -> 9th element of list at "alpha" key
// 
new_buffer.set(&["3", "alpha", "9"], "who would build a schema like this")?;
 
// get the same item we just set
let message = new_buffer.get::<&str>(&["3", "alpha", "9"])?;
 
assert_eq!(message, Some("who would build a schema like this"));
 

pub fn maybe_compact<F>(
    &mut self,
    new_capacity: Option<u32>,
    new_size: Option<NP_Size>,
    callback: F
) -> Result<(), NP_Error> where
    F: FnMut(NP_Size_Data) -> bool, 
[src]

This performs a compaction if the closure provided as the third argument returns true. Compaction is a pretty expensive operation (requires full copy of the whole buffer) so should be done sparingly. The closure is provided an argument that contains the original size of the buffer, how many bytes could be saved by compaction, and how large the new buffer would be after compaction.

The first argument, new_capacity, is the capacity of the underlying Vec that we'll be copying the data into. The default is the size of the old buffer.

The second argument, new_size, can be used to change the size of the address space in the new buffer. Default behavior is to copy the address size of the old buffer. Be careful, if you're going from a larg address space down to a smaller one the data might not fit in the new buffer.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set initial value
new_buffer.set(&[], "hello")?;
// using 11 bytes
assert_eq!(NP_Size_Data {
    current_buffer: 11,
    after_compaction: 11,
    wasted_bytes: 0
}, new_buffer.calc_bytes()?);
// update the value
new_buffer.set(&[], "hello, world")?;
// now using 25 bytes, with 7 bytes of wasted space
assert_eq!(NP_Size_Data {
    current_buffer: 25,
    after_compaction: 18,
    wasted_bytes: 7
}, new_buffer.calc_bytes()?);
// compact to save space
new_buffer.maybe_compact(None, None, |compact_data| {
    // only compact if wasted bytes are greater than 5
    if compact_data.wasted_bytes > 5 {
        true
    } else {
        false
    }
})?;
// back down to 18 bytes with no wasted bytes
assert_eq!(NP_Size_Data {
    current_buffer: 18,
    after_compaction: 18,
    wasted_bytes: 0
}, new_buffer.calc_bytes()?);
 

pub fn compact(
    &mut self,
    new_capacity: Option<u32>,
    new_size: Option<NP_Size>
) -> Result<(), NP_Error>
[src]

Compacts a buffer to remove an unused bytes or free space after a mutation. This is a pretty expensive operation (requires full copy of the whole buffer) so should be done sparingly.

The first argument, new_capacity, is the capacity of the underlying Vec that we'll be copying the data into. The default is the size of the old buffer.

The second argument, new_size, can be used to change the size of the address space in the new buffer. Default behavior is to copy the address size of the old buffer. Be careful, if you're going from a larg address space down to a smaller one the data might not fit in the new buffer.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
// set initial value
new_buffer.set(&[], "hello")?;
// using 11 bytes
assert_eq!(NP_Size_Data {
    current_buffer: 11,
    after_compaction: 11,
    wasted_bytes: 0
}, new_buffer.calc_bytes()?);
// update the value
new_buffer.set(&[], "hello, world")?;
// now using 25 bytes, with 7 bytes of wasted bytes
assert_eq!(NP_Size_Data {
    current_buffer: 25,
    after_compaction: 18,
    wasted_bytes: 7
}, new_buffer.calc_bytes()?);
// compact to save space
new_buffer.compact(None, None)?;
// back down to 18 bytes with no wasted bytes
assert_eq!(NP_Size_Data {
    current_buffer: 18,
    after_compaction: 18,
    wasted_bytes: 0
}, new_buffer.calc_bytes()?);
 

pub fn calc_bytes(&self) -> Result<NP_Size_Data, NP_Error>[src]

Recursively measures how many bytes each element in the buffer is using. This will let you know how many bytes can be saved from a compaction.

use no_proto::error::NP_Error;
use no_proto::NP_Factory;
use no_proto::buffer::NP_Size_Data;
 
let factory: NP_Factory = NP_Factory::new(r#"{
   "type": "string"
}"#)?;
 
let mut new_buffer = factory.empty_buffer(None, None);
new_buffer.set(&[], "hello")?;
assert_eq!(NP_Size_Data {
    current_buffer: 11,
    after_compaction: 11,
    wasted_bytes: 0
}, new_buffer.calc_bytes()?);
 

Trait Implementations

impl<'buffer> Debug for NP_Buffer<'buffer>[src]

Auto Trait Implementations

impl<'buffer> Send for NP_Buffer<'buffer>

impl<'buffer> !Sync for NP_Buffer<'buffer>

impl<'buffer> Unpin for NP_Buffer<'buffer>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.