use crate::{idl::{JS_AST, JS_Schema}, schema::{NP_Schema_Addr, NP_Value_Kind}};
use crate::NP_Schema;
use crate::{memory::NP_Memory, schema::{NP_Parsed_Schema}};
use alloc::vec::Vec;
use crate::json_flex::{JSMAP, NP_JSON};
use crate::schema::{NP_TypeKeys};
use crate::{pointer::NP_Value, error::NP_Error};
use alloc::string::String;
use alloc::boxed::Box;
use alloc::string::ToString;
use alloc::borrow::ToOwned;
use super::{NP_Cursor, NP_Scalar};
#[derive(Debug)]
pub struct NP_Union {
pub value: Option<String>,
pub is_default: bool
}
impl<'value> NP_Scalar<'value> for NP_Union {
fn schema_default(_schema: &NP_Parsed_Schema) -> Option<Self> where Self: Sized {
None
}
fn np_max_value(_cursor: &NP_Cursor, _memory: &NP_Memory) -> Option<Self> {
None
}
fn np_min_value(_cursor: &NP_Cursor, _memory: &NP_Memory) -> Option<Self> {
None
}
}
impl NP_Union {
pub fn select(mut cursor: NP_Cursor, types: &Vec<(u8, String, usize)>, key: &str, make_path: bool, schema_query: bool, memory: &NP_Memory) -> Result<Option<NP_Cursor>, NP_Error> {
match types.iter().position(|val| { val.1 == key }) {
Some(x) => {
if schema_query {
let schema_value = &types[x];
cursor.parent_schema_addr = cursor.schema_addr;
cursor.schema_addr = schema_value.2;
return Ok(Some(cursor))
}
let union_value = cursor.get_value(memory);
let addr_value = union_value.get_addr_value();
if addr_value == 0 { if make_path { let new_addr = memory.malloc_borrow(&[0u8; 3])?;
union_value.set_addr_value(new_addr as u32);
} else { return Ok(None)
}
}
let addr_value = union_value.get_addr_value() as usize;
let union_index = memory.read_bytes()[addr_value];
if union_index == 0 && make_path == false {
return Ok(None)
}
if union_index == 0 { memory.write_bytes()[addr_value] = (x as u8) + 1;
return Ok(Some(NP_Cursor::new(addr_value + 1, types[x].2, cursor.schema_addr)))
} else if union_index == (x as u8) + 1 { return Ok(Some(NP_Cursor::new(addr_value + 1, types[x].2, cursor.schema_addr)))
} else { return Ok(None);
}
},
None => return Ok(None)
}
}
}
impl<'value> NP_Value<'value> for NP_Union {
fn type_idx() -> (&'value str, NP_TypeKeys) {
("union", NP_TypeKeys::Union)
}
fn self_type_idx(&self) -> (&'value str, NP_TypeKeys) {
("union", NP_TypeKeys::Union)
}
fn schema_to_json(schema: &Vec<NP_Parsed_Schema>, address: usize)-> Result<NP_JSON, NP_Error> {
todo!()
}
fn schema_to_idl(_schema: &Vec<NP_Parsed_Schema>, _address: usize)-> Result<String, NP_Error> {
todo!()
}
fn from_idl_to_schema(_schema: Vec<NP_Parsed_Schema>, _name: &str, _idl: &JS_Schema, _args: &Vec<JS_AST>) -> Result<(bool, Vec<u8>, Vec<NP_Parsed_Schema>), NP_Error> {
todo!()
}
fn from_json_to_schema(mut schema: Vec<NP_Parsed_Schema>, json_schema: &Box<NP_JSON>) -> Result<(bool, Vec<u8>, Vec<NP_Parsed_Schema>), NP_Error> {
todo!()
}
fn from_bytes_to_schema(mut schema: Vec<NP_Parsed_Schema>, address: usize, bytes: &[u8]) -> (bool, Vec<NP_Parsed_Schema>) {
todo!()
}
fn set_from_json<'set>(_depth: usize, _apply_null: bool, _cursor: NP_Cursor, _memory: &'set NP_Memory, _value: &Box<NP_JSON>) -> Result<(), NP_Error> where Self: 'set + Sized {
todo!()
}
fn default_value(_depth: usize, _schema_addr: usize, _schemas: &Vec<NP_Parsed_Schema>) -> Option<Self> {
todo!()
}
fn into_value(_cursor: &NP_Cursor, _memory: &'value NP_Memory) -> Result<Option<Self>, NP_Error> where Self: Sized {
todo!()
}
fn to_json(_depth:usize, _cursor: &NP_Cursor, _memory: &'value NP_Memory) -> NP_JSON {
todo!()
}
fn get_size(_depth:usize, _cursor: &'value NP_Cursor, _memory: &'value NP_Memory) -> Result<usize, NP_Error> {
todo!()
}
fn do_compact<, M2: NP_Memory>(_depth:usize, mut _from_cursor: NP_Cursor, _from_memory: &'value NP_Memory, mut _to_cursor: NP_Cursor, _to_memory: &'value NP_Memory2) -> Result<NP_Cursor, NP_Error> where Self: 'value + Sized {
todo!()
}
}
#[test]
fn schema_parsing_works() -> Result<(), NP_Error> {
let schema = r#"{"type":"union","types":[["value1",{"type":"string"}],["value2",{"type":"uint8"}]]}"#;
let factory = crate::NP_Factory::new_json(schema)?;
assert_eq!(schema, factory.schema.to_json()?.stringify());
let factory2 = crate::NP_Factory::new_bytes(factory.export_schema_bytes())?;
assert_eq!(schema, factory2.schema.to_json()?.stringify());
Ok(())
}