use log::error;
use crate::img::{Error,DiskImageType};
use crate::STDRESULT;
#[macro_export]
macro_rules! getByte {
($root:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
$root[&$typ]$([stringify!($x)])+ = json::JsonValue::String(hex::ToHex::encode_hex(&vec![$slf.$($x).+]))
};
}
#[macro_export]
macro_rules! getByteEx {
($root:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
$root[&$typ]$([stringify!($x)])+ = json::JsonValue::new_object();
$root[&$typ]$([stringify!($x)])+["_raw"] = json::JsonValue::String(hex::ToHex::encode_hex(&vec![$slf.$($x).+]))
};
}
#[macro_export]
macro_rules! getHex {
($root:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
$root[&$typ]$([stringify!($x)])+ = json::JsonValue::String(hex::ToHex::encode_hex(&$slf.$($x).+))
};
}
#[macro_export]
macro_rules! getHexEx {
($root:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
$root[&$typ]$([stringify!($x)])+ = json::JsonValue::new_object();
$root[&$typ]$([stringify!($x)])+["_raw"] = json::JsonValue::String(hex::ToHex::encode_hex(&$slf.$($x).+))
};
}
#[macro_export]
macro_rules! putByte {
($val:ident,$key:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
if meta::match_key($key,&[&$typ,$(stringify!($x)),+]) {
return meta::set_metadata_byte($val, &mut $slf.$($x).+);
}
};
}
#[macro_export]
macro_rules! putHex {
($val:ident,$key:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
if meta::match_key($key,&[&$typ,$(stringify!($x)),+]) {
return meta::set_metadata_hex($val, &mut $slf.$($x).+);
}
};
}
#[macro_export]
macro_rules! putString {
($val:ident,$key:ident,$typ:ident,$slf:ident.$($x:ident).+) => {
if meta::match_key($key,&[&$typ,$(stringify!($x)),+]) {
$slf.$($x).+ = $val.to_string();
return Ok(());
}
};
}
#[macro_export]
macro_rules! putStringBuf {
($val:ident,$key:ident,$typ:ident,$slf:ident.$($x:ident).+,$pad:expr_2021) => {
if meta::match_key($key,&[&$typ,$(stringify!($x)),+]) {
return meta::set_metadata_utf8($val,&mut $slf.$($x).+,$pad);
}
};
}
pub fn match_key(key_path: &[String],test_path: &[&str]) -> bool {
let pad = match key_path.last() {
Some(last) if last=="_raw" => 1,
_ => 0
};
if key_path.len()!=test_path.len()+pad {
return false;
}
for i in 0..test_path.len() {
if key_path[i]!=test_path[i] {
return false;
}
}
true
}
pub fn test_metadata(key_path: &[String], typ: DiskImageType) -> STDRESULT {
let mut node = key_path.iter();
match node.next() {
Some(key) if key==&typ.to_string() => Ok(()),
_ => {
error!("metadata root did not match `{}`",typ.to_string());
Err(Box::new(Error::MetadataMismatch))
}
}
}
pub fn set_metadata_hex(hex_val: &str, buf: &mut [u8]) -> STDRESULT {
match hex::decode_to_slice(hex_val, buf) {
Ok(()) => Ok(()),
Err(e) => Err(Box::new(e))
}
}
pub fn set_metadata_byte(hex_val: &str, buf: &mut u8) -> STDRESULT {
let mut slice: [u8;1] = [0];
match hex::decode_to_slice(hex_val, &mut slice) {
Ok(()) => { *buf = slice[0]; Ok(()) },
Err(e) => Err(Box::new(e))
}
}
pub fn set_metadata_utf8(utf8_val: &str, buf: &mut [u8], pad: u8) -> STDRESULT {
let bytes = utf8_val.as_bytes();
if bytes.len()<=buf.len() {
for i in 0..bytes.len() {
buf[i] = bytes[i];
}
for i in bytes.len()..buf.len() {
buf[i] = pad;
}
Ok(())
} else {
Err(Box::new(Error::MetadataMismatch))
}
}