#[cfg(not(feature = "std"))]
use alloc::{
format,
string::String,
vec::Vec,
collections::BTreeMap as HashMap,
};
#[cfg(feature = "std")]
use std::collections::HashMap;
use crate::nodes::node::Node;
pub trait NodeQueryExt {
fn get_required(&self, key: &str) -> Result<&Node, String>;
fn get_int_required(&self, key: &str) -> Result<i64, String>;
fn get_string_required(&self, key: &str) -> Result<&str, String>;
fn get_list_required(&self, key: &str) -> Result<&Vec<Node>, String>;
fn get_dict_required(&self, key: &str) -> Result<&HashMap<String, Node>, String>;
fn get_int_optional(&self, key: &str) -> Option<i64>;
fn get_string_optional(&self, key: &str) -> Option<&str>;
fn get_list_optional(&self, key: &str) -> Option<&Vec<Node>>;
fn get_dict_optional(&self, key: &str) -> Option<&HashMap<String, Node>>;
}
impl NodeQueryExt for Node {
fn get_required(&self, key: &str) -> Result<&Node, String> {
self.get(key)
.ok_or_else(|| format!("Missing required field: '{}'", key))
}
fn get_int_required(&self, key: &str) -> Result<i64, String> {
self.get_required(key)?
.as_integer()
.copied()
.ok_or_else(|| format!("Field '{}' must be an integer", key))
}
fn get_string_required(&self, key: &str) -> Result<&str, String> {
self.get_required(key)?
.as_string()
.ok_or_else(|| format!("Field '{}' must be a string", key))
}
fn get_list_required(&self, key: &str) -> Result<&Vec<Node>, String> {
self.get_required(key)?
.as_list()
.ok_or_else(|| format!("Field '{}' must be a list", key))
}
fn get_dict_required(&self, key: &str) -> Result<&HashMap<String, Node>, String> {
self.get_required(key)?
.as_dictionary()
.ok_or_else(|| format!("Field '{}' must be a dictionary", key))
}
fn get_int_optional(&self, key: &str) -> Option<i64> {
self.get(key).and_then(|n| n.as_integer()).copied()
}
fn get_string_optional(&self, key: &str) -> Option<&str> {
self.get(key).and_then(|n| n.as_string())
}
fn get_list_optional(&self, key: &str) -> Option<&Vec<Node>> {
self.get(key).and_then(|n| n.as_list())
}
fn get_dict_optional(&self, key: &str) -> Option<&HashMap<String, Node>> {
self.get(key).and_then(|n| n.as_dictionary())
}
}