#[macro_export]
macro_rules! kson {
($var:ident) => {
let mut $var = serde_json::json!({});
};
($var:ident $( [ $key:expr ] )+ = $value:expr ) => {{
let mut temp = &mut $var;
$(
let key = $key;
temp = {
if let Some(index) = key.to_string().parse::<usize>().ok() {
if !temp.is_array() {
*temp = serde_json::json!([]);
}
let arr = temp.as_array_mut().unwrap();
if arr.len() <= index {
arr.resize(index + 1, serde_json::Value::Null);
}
&mut arr[index]
} else {
let key_str = key.to_string();
if !temp.is_object() {
*temp = serde_json::json!({});
}
temp.as_object_mut().unwrap()
.entry(key_str)
.or_insert_with(|| serde_json::Value::Null)
}
};
)*
*temp = serde_json::json!($value);
}};
($var:ident $( [ $key:expr ] )+ : &str) => {{
let mut temp = &$var;
$(
let key = $key;
temp = {
if let Some(index) = key.to_string().parse::<usize>().ok() {
if let Some(arr) = temp.as_array() {
arr.get(index).unwrap_or(&serde_json::Value::Null)
} else {
&serde_json::Value::Null
}
} else {
if let Some(obj) = temp.as_object() {
obj.get(&key.to_string()).unwrap_or(&serde_json::Value::Null)
} else {
&serde_json::Value::Null
}
}
};
)*
if let Some(str_value) = temp.as_str() {
str_value
} else if let Some(num_value) = temp.as_i64() {
Box::leak(Box::new(num_value.to_string()))
} else if let Some(num_value) = temp.as_f64() {
Box::leak(Box::new(num_value.to_string()))
} else {
panic!("타입 '&str'로 변환할 수 없습니다.")
}
}};
($var:ident $( [ $key:expr ] ) + : $t:ty) => {{
let mut temp = &$var;
$(
let key = $key;
temp = {
if let Some(index) = key.to_string().parse::<usize>().ok() {
if let Some(arr) = temp.as_array() {
arr.get(index).unwrap_or(&serde_json::Value::Null)
} else {
&serde_json::Value::Null
}
} else {
if let Some(obj) = temp.as_object() {
obj.get(&key.to_string()).unwrap_or(&serde_json::Value::Null)
} else {
&serde_json::Value::Null
}
}
};
)*
serde_json::from_value::<$t>(temp.clone()).unwrap_or_else(|_| {
if let Some(str_value) = temp.as_str() {
if let Ok(parsed_value) = str_value.parse::<$t>() {
parsed_value
} else {
panic!("값을 타입 '{}'으로 변환할 수 없습니다.", stringify!($t))
}
} else if let Some(num_value) = temp.as_f64() {
if stringify!($t) == "String" || stringify!($t) == "&str" {
num_value.to_string().parse::<$t>().unwrap()
} else {
panic!("값을 타입 '{}'으로 변환할 수 없습니다.", stringify!($t))
}
} else {
panic!("타입 '{}'으로 변환할 수 없습니다.", stringify!($t))
}
})
}};
}