use checkito::*;
use core::fmt;
enum Node {
Null,
Boolean(bool),
Number(f64),
String(String),
Array(Vec<Node>),
Object(Vec<(Node, Node)>),
}
impl Node {
pub fn size(&self) -> usize {
match self {
Node::Array(nodes) => nodes.len() + nodes.iter().map(Node::size).sum::<usize>(),
Node::Object(nodes) => {
nodes.len()
+ nodes
.iter()
.map(|pair| pair.0.size() + pair.1.size())
.sum::<usize>()
}
_ => 1,
}
}
}
impl fmt::Debug for Node {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Null => write!(f, "null"),
Self::Boolean(arg0) => write!(f, "{arg0}"),
Self::Number(arg0) => write!(f, "{arg0}"),
Self::String(arg0) => write!(f, r#""{arg0}""#),
Self::Array(arg0) => f.debug_list().entries(arg0).finish(),
Self::Object(arg0) => f
.debug_map()
.entries(arg0.iter().map(|pair| (&pair.0, &pair.1)))
.finish(),
}
}
}
fn string() -> impl Generate<Item = Node> {
regex!(r#"([a-zA-Z0-9]|[#-~ !]|(\\[\\"/bfnrt])|(\\u([0-9a-fA-F]){4}))*"#)
.map(Node::String)
}
fn node() -> impl Generate<Item = Node> {
(
with(|| Node::Null),
bool::generator().map(Node::Boolean),
number::<f64>().map(Node::Number),
string(),
lazy(node)
.collect_with(..32usize)
.dampen()
.map(Node::Array)
.boxed(),
(string(), lazy(node))
.collect_with(..32usize)
.dampen()
.map(Node::Object)
.boxed(),
)
.any()
.unify()
}
fn main() {
let result = node().check(|node| node.size() < 100);
dbg!(result.unwrap());
}