use alloc::{borrow::ToOwned, boxed::Box, collections::BTreeMap, vec::Vec};
use core::fmt::{self, Debug, Pointer};
use crate::own;
#[derive(Debug, Clone)]
#[cfg_attr(feature = "minicbor", derive(minicbor::Encode, minicbor::Decode))]
pub struct Node {
#[cfg_attr(feature = "minicbor", n(0))]
pub type_name: Option<Box<str>>,
#[cfg_attr(feature = "minicbor", n(1))]
pub node_name: Box<str>,
#[cfg_attr(feature = "minicbor", n(2))]
pub arguments: Vec<Scalar>,
#[cfg_attr(feature = "minicbor", n(3))]
pub properties: BTreeMap<Box<str>, Scalar>,
#[cfg_attr(feature = "minicbor", n(4))]
pub children: Option<Vec<Node>>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "minicbor", derive(minicbor::Encode, minicbor::Decode))]
pub struct Scalar {
#[cfg_attr(feature = "minicbor", n(0))]
pub type_name: Option<Box<str>>,
#[cfg_attr(feature = "minicbor", n(1))]
pub literal: Box<str>,
}
impl Node {
pub fn new(name: &str) -> Self {
Self {
type_name: None,
node_name: own!(name),
arguments: Vec::new(),
properties: BTreeMap::new(),
children: None,
}
}
pub fn children(&self) -> impl ExactSizeIterator<Item = &Node> {
self.children
.as_ref()
.map(|c| c.iter())
.unwrap_or_else(|| [].iter())
}
}
impl Scalar {
pub fn new(type_name: Box<str>, literal: Box<str>) -> Self {
Self {
type_name: Some(type_name),
literal,
}
}
}
impl From<Box<str>> for Scalar {
fn from(value: Box<str>) -> Self {
Scalar {
type_name: None,
literal: value,
}
}
}
macro_rules! impl_pointer {
($ty:ty) => {
impl Pointer for $ty {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ptr = self as *const Self;
Pointer::fmt(&ptr, f)
}
}
};
}
impl_pointer!(Node);
impl_pointer!(Scalar);