#[macro_export]
macro_rules! register_struct_info {
(struct $name:ident { $($fname:ident : $ftype:ty),* }, $vec:expr) => {
struct $name {}
impl $name {
fn get_fields_info<'a>(names_types: &mut Vec<StructInfo>) {
let mut child_names_types = Vec::new();
$(
child_names_types.push(
FieldInfo {
field_name: stringify!($fname),
field_type: stringify!($ftype)
}
);
)*;
let (prefix, struct_name) = stringify!($name).split_at(2);
names_types.push(
StructInfo {
struct_name: struct_name,
fields: child_names_types
}
);
}
}
$name::get_fields_info(&mut $vec);
};
}
#[derive(Debug, Clone)]
pub struct StructInfo<'a> {
pub struct_name: &'a str, pub fields: Vec<FieldInfo<'a>> }
impl<'a> StructInfo<'a> {
pub fn find_field(&self, name: &str) -> Result<(&FieldInfo, usize), String> {
let mut position = 0;
let len = self.fields.len();
let fields = self.fields.clone();
for i in 0..len {
if fields[i].field_name.eq(name) {
return Ok((&self.fields[i], i+1))
}
}
return Err(format!("NO field named {:?}", name));
}
}
#[derive(Debug, Clone)]
pub struct FieldInfo<'a> {
pub field_name: &'a str, pub field_type: &'a str }
#[derive(Debug)]
pub struct FlatBufferManager<'a> {
pub struct_list: Vec<StructInfo<'a>>,
}
impl<'a> FlatBufferManager<'a> {
pub fn new() -> FlatBufferManager<'a> {
FlatBufferManager {
struct_list: Vec::new()
}
}
pub fn find_struct(&self, name: &str) -> Result<&StructInfo, String> {
let mut struct_list = self.struct_list.clone();
let len = struct_list.len();
for i in 0..len {
if struct_list[i].struct_name.eq(name) {
return Ok(&self.struct_list[i]);
}
}
return Err(format!("NO struct named {:?}", name));
}
fn field_position_vec(&self, fields:&mut Vec<&str>) -> Result<Vec<usize>, String> {
let mut position_vec = Vec::new();
let struct_name = fields.pop().unwrap();
let struct_info = match self.find_struct(struct_name) {
Ok(info) => info, Err(e) => return Err(e),
};
let field_name = fields.pop().unwrap();
let rest_field = fields.len();
let (field_type, p) = match struct_info.find_field(field_name) {
Ok((field, p)) => (field.field_type, p),
Err(e) => return Err(e),
};
position_vec.push(p);
if rest_field == 0 {
position_vec.reverse();
return Ok(position_vec);
}
if field_type.eq("String") {
return Err(format!("{:?} has not {:?}",struct_name, fields.pop().unwrap()));
} else if field_type.eq("bool") {
return Err(format!("{:?} has not {:?}",struct_name, fields.pop().unwrap()));
} else {
if field_type.starts_with("List<") {
let (list_str, inner_type) = field_type.split_at(5);
let mut inner_type_string = String::from(inner_type); let last = inner_type_string.len() - 1;
inner_type_string.remove(last);
self.field_position_vec_inner(inner_type_string.as_str(), fields, &mut position_vec);
return Ok(position_vec);
} else {
self.field_position_vec_inner(field_type, fields, &mut position_vec);
return Ok(position_vec);
}
}
}
fn field_position_vec_inner(&self, struct_name: &str, fields:&mut Vec<&str>, position_vec: &mut Vec<usize>) -> Result<(), String> {
let mut field_name = "";
loop {
field_name = fields.pop().unwrap();
match field_name.parse::<usize>() {
Ok(n) => {
position_vec.push(n+1);
if fields.len() == 0 {
position_vec.reverse();
return Ok(());
} else {
continue;
}
}
Err(e) => break,
};
}
let struct_info = match self.find_struct(struct_name) {
Ok(info) => info, Err(e) => return Err(e),
};
let rest_field = fields.len();
let (field_type, p) = match struct_info.find_field(field_name) {
Ok((field, p)) => (field.field_type, p),
Err(e) => return Err(e),
};
position_vec.push(p);
if rest_field == 0 {
position_vec.reverse();
return Ok(());
}
if field_type.eq("String") {
return Err(format!("{:?} has not {:?}",struct_name, fields.pop().unwrap()));
} else if field_type.eq("bool") {
return Err(format!("{:?} has not {:?}",struct_name, fields.pop().unwrap()));
} else {
if field_type.starts_with("List<") {
let (list_str, inner_type) = field_type.split_at(5);
let mut inner_type_string = String::from(inner_type);
let last = inner_type_string.len() - 1;
inner_type_string.remove(last);
return self.field_position_vec_inner(inner_type_string.as_str(), fields, position_vec);
} else {
return self.field_position_vec_inner(field_type, fields, position_vec);
}
}
}
pub fn to_local_vec(&self, local: &str, struct_name: &str) -> Result<Vec<String>, String> {
let string = local.replace("[", ".");
let string = string.as_str().replace("]", "."); let mut vec:Vec<&str> = string.as_str().split(".").collect();
let mut string_vec = Vec::new();
for e in vec {
let e_s = String::from(e);
if e_s.len() == 0 {
continue;
}
string_vec.push(e_s);
}
string_vec.reverse();
string_vec.push(String::from(struct_name));
Ok(string_vec)
}
pub fn field_position(&self, fields:&mut Vec<String>) -> Result<Vec<usize>, String> {
let mut vec:Vec<&str> = Vec::new();
for i in 0..fields.len() {
vec.push(fields[i].as_str());
}
self.field_position_vec(&mut vec)
}
}