use no_proto::error::NP_Error;
use no_proto::NP_Factory;

fn main() -> Result<(), NP_Error> {
    // JSON is used to describe schema for the factory
    // Each factory represents a single schema
    // One factory can be used to serialize/deserialize any number of buffers
    let user_factory = NP_Factory::new(r#"{
        "type": "table",
        "columns": [
            ["name",   {"type": "string"}],
            ["age",    {"type": "u16", "default": 0}],
            ["tags",   {"type": "list", "of": {
                "type": "string"
            }}]
        ]
    }"#)?;


    // create a new empty buffer
    let mut user_buffer = user_factory.empty_buffer(None); // optional capacity, optional address size (u16 by default)

    // set an internal value of the buffer, set the  "name" column
    user_buffer.set(&["name"], "Billy Joel")?;

    // assign nested internal values, sets the first tag element
    user_buffer.set(&["tags", "0"], "first tag")?;

    // get an internal value of the buffer from the "name" column
    let name = user_buffer.get::<&str>(&["name"])?;
    assert_eq!(name, Some("Billy Joel"));

    // close buffer and get internal bytes
    let user_bytes: Vec<u8> = user_buffer.close();

    // open the buffer again
    let user_buffer = user_factory.open_buffer(user_bytes);

    // get nested internal value, first tag from the tag list
    let tag = user_buffer.get::<&str>(&["tags", "0"])?;
    assert_eq!(tag, Some("first tag"));

    // get nested internal value, the age field
    let age = user_buffer.get::<u16>(&["age"])?;
    // returns default value from schema
    assert_eq!(age, Some(0_u16));

    // close again
    let user_bytes: Vec<u8> = user_buffer.close();

    println!("{:?}", user_bytes);

    Ok(())
}
