Separating binary into library for doctests
This commit is contained in:
parent
f751e46389
commit
5e204a2c28
10 changed files with 292 additions and 233 deletions
|
@ -1,15 +1,6 @@
|
|||
#[macro_use]
|
||||
extern crate clap;
|
||||
extern crate regex;
|
||||
|
||||
#[macro_use]
|
||||
pub mod tree;
|
||||
pub mod bracket;
|
||||
pub mod constants;
|
||||
pub mod file_linked;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
extern crate gemla;
|
||||
|
||||
use clap::App;
|
||||
use std::fs::metadata;
|
||||
|
@ -21,11 +12,11 @@ use std::fs::metadata;
|
|||
fn main() {
|
||||
// Command line arguments are parsed with the clap crate. And this program uses
|
||||
// the yaml method with clap.
|
||||
let yaml = load_yaml!("../cli.yml");
|
||||
let yaml = load_yaml!("../../cli.yml");
|
||||
let matches = App::from_yaml(yaml).get_matches();
|
||||
|
||||
// Checking that the first argument <DIRECTORY> is a valid directory
|
||||
let directory = matches.value_of(constants::args::DIRECTORY).unwrap();
|
||||
let directory = matches.value_of(gemla::constants::args::DIRECTORY).unwrap();
|
||||
let metadata = metadata(directory);
|
||||
match &metadata {
|
||||
Ok(m) if m.is_dir() => {
|
|
@ -8,6 +8,46 @@ use std::fmt;
|
|||
/// A trait used to interact with the internal state of nodes within the genetic bracket
|
||||
pub trait GeneticNode {
|
||||
/// Initializes a new instance of a genetic state.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # use gemla::bracket::genetic_node::GeneticNode;
|
||||
/// #
|
||||
/// struct Node {
|
||||
/// pub fit_score: f64,
|
||||
/// }
|
||||
///
|
||||
/// impl GeneticNode for Node {
|
||||
/// fn initialize() -> Result<Box<Self>, String> {
|
||||
/// Ok(Box::new(Node {fit_score: 0.0}))
|
||||
/// }
|
||||
///
|
||||
/// //...
|
||||
/// #
|
||||
/// # fn simulate(&mut self, iterations: u64) -> Result<(), String> {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn get_fit_score(&self) -> f64 {
|
||||
/// # self.fit_score
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn calculate_scores_and_trim(&mut self) -> Result<(), String> {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// #
|
||||
/// # fn mutate(&mut self) -> Result<(), String> {
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// }
|
||||
///
|
||||
/// # fn main() -> Result<(), String> {
|
||||
/// let node = Node::initialize()?;
|
||||
/// assert_eq!(node.get_fit_score(), 0.0);
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
fn initialize() -> Result<Box<Self>, String>;
|
||||
|
||||
/// Runs a simulation on the state object in order to guage it's fitness.
|
||||
|
|
|
@ -122,3 +122,120 @@ where
|
|||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
|
||||
#[derive(Default, Deserialize, Serialize, Clone)]
|
||||
struct TestState {
|
||||
pub score: f64,
|
||||
}
|
||||
|
||||
impl FromStr for TestState {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<TestState, Self::Err> {
|
||||
toml::from_str(s).map_err(|_| format!("Unable to parse string {}", s))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TestState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.score)
|
||||
}
|
||||
}
|
||||
|
||||
impl TestState {
|
||||
fn new(score: f64) -> TestState {
|
||||
TestState { score: score }
|
||||
}
|
||||
}
|
||||
|
||||
impl genetic_node::GeneticNode for TestState {
|
||||
fn simulate(&mut self, iterations: u64) -> Result<(), String> {
|
||||
self.score += iterations as f64;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_fit_score(&self) -> f64 {
|
||||
self.score
|
||||
}
|
||||
|
||||
fn calculate_scores_and_trim(&mut self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mutate(&mut self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn initialize() -> Result<Box<Self>, String> {
|
||||
Ok(Box::new(TestState { score: 0.0 }))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
let bracket = Bracket::<TestState>::initialize("./temp".to_string())
|
||||
.expect("Bracket failed to initialize");
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", bracket),
|
||||
format!("{{\"tree\":{},\"step\":0,\"iteration_scaling\":{{\"enumType\":\"Linear\",\"enumContent\":1}}}}",
|
||||
btree!(TestState::new(0.0)))
|
||||
);
|
||||
|
||||
std::fs::remove_file("./temp").expect("Unable to remove file");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run() {
|
||||
let mut bracket = Bracket::<TestState>::initialize("./temp2".to_string())
|
||||
.expect("Bracket failed to initialize");
|
||||
|
||||
bracket
|
||||
.mutate(|b| drop(b.iteration_scaling(IterationScaling::Linear(2))))
|
||||
.expect("Failed to set iteration scaling");
|
||||
for _ in 0..3 {
|
||||
bracket
|
||||
.mutate(|b| drop(b.run_simulation_step()))
|
||||
.expect("Failed to run step");
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", bracket),
|
||||
format!("{{\"tree\":{},\"step\":3,\"iteration_scaling\":{{\"enumType\":\"Linear\",\"enumContent\":2}}}}",
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0)))
|
||||
),
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
std::fs::remove_file("./temp2").expect("Unable to remove file");
|
||||
}
|
||||
|
||||
}
|
|
@ -103,3 +103,43 @@ impl<T: fmt::Display> fmt::Display for FileLinked<T> {
|
|||
write!(f, "{}", self.val)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn test_mutate() -> Result<(), String> {
|
||||
let tree = btree!(1, btree!(2), btree!(3, btree!(4),));
|
||||
let mut linked_tree = FileLinked::new(tree, String::from("test.txt"))?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":1,\"left\":{\"val\":2,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
linked_tree.mutate(|v1| v1.val = 10)?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":10,\"left\":{\"val\":2,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
linked_tree.mutate(|v1| {
|
||||
let mut left = v1.left.clone().unwrap();
|
||||
left.val = 13;
|
||||
v1.left = Some(left);
|
||||
})?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":10,\"left\":{\"val\":13,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
fs::remove_file("test.txt").expect("Unable to remove file");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
|
7
gemla/src/lib.rs
Normal file
7
gemla/src/lib.rs
Normal file
|
@ -0,0 +1,7 @@
|
|||
extern crate regex;
|
||||
|
||||
#[macro_use]
|
||||
pub mod tree;
|
||||
pub mod bracket;
|
||||
pub mod constants;
|
||||
pub mod file_linked;
|
|
@ -1,111 +0,0 @@
|
|||
use super::super::bracket;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt;
|
||||
use std::str::FromStr;
|
||||
use std::string::ToString;
|
||||
|
||||
#[derive(Default, Deserialize, Serialize, Clone)]
|
||||
struct TestState {
|
||||
pub score: f64,
|
||||
}
|
||||
|
||||
impl FromStr for TestState {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<TestState, Self::Err> {
|
||||
toml::from_str(s).map_err(|_| format!("Unable to parse string {}", s))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for TestState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.score)
|
||||
}
|
||||
}
|
||||
|
||||
impl TestState {
|
||||
fn new(score: f64) -> TestState {
|
||||
TestState { score: score }
|
||||
}
|
||||
}
|
||||
|
||||
impl bracket::genetic_node::GeneticNode for TestState {
|
||||
fn simulate(&mut self, iterations: u64) -> Result<(), String> {
|
||||
self.score += iterations as f64;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_fit_score(&self) -> f64 {
|
||||
self.score
|
||||
}
|
||||
|
||||
fn calculate_scores_and_trim(&mut self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mutate(&mut self) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn initialize() -> Result<Box<Self>, String> {
|
||||
Ok(Box::new(TestState { score: 0.0 }))
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
let bracket = bracket::Bracket::<TestState>::initialize("./temp".to_string())
|
||||
.expect("Bracket failed to initialize");
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", bracket),
|
||||
format!("{{\"tree\":{},\"step\":0,\"iteration_scaling\":{{\"enumType\":\"Linear\",\"enumContent\":1}}}}",
|
||||
btree!(TestState::new(0.0)))
|
||||
);
|
||||
|
||||
std::fs::remove_file("./temp").expect("Unable to remove file");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_run() {
|
||||
let mut bracket = bracket::Bracket::<TestState>::initialize("./temp".to_string())
|
||||
.expect("Bracket failed to initialize");
|
||||
|
||||
bracket
|
||||
.mutate(|b| drop(b.iteration_scaling(bracket::IterationScaling::Linear(2))))
|
||||
.expect("Failed to set iteration scaling");
|
||||
for _ in 0..3 {
|
||||
bracket
|
||||
.mutate(|b| drop(b.run_simulation_step()))
|
||||
.expect("Failed to run step");
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", bracket),
|
||||
format!("{{\"tree\":{},\"step\":3,\"iteration_scaling\":{{\"enumType\":\"Linear\",\"enumContent\":2}}}}",
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0)))
|
||||
),
|
||||
btree!(
|
||||
TestState::new(12.0),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))),
|
||||
btree!(TestState::new(6.0),
|
||||
btree!(TestState::new(2.0)),
|
||||
btree!(TestState::new(2.0))))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
std::fs::remove_file("./temp").expect("Unable to remove file");
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
use super::super::file_linked::FileLinked;
|
||||
|
||||
use std::fs;
|
||||
|
||||
#[test]
|
||||
fn test_mutate() -> Result<(), String> {
|
||||
let tree = btree!(1, btree!(2), btree!(3, btree!(4),));
|
||||
let mut linked_tree = FileLinked::new(tree, String::from("test.txt"))?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":1,\"left\":{\"val\":2,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
linked_tree.mutate(|v1| v1.val = 10)?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":10,\"left\":{\"val\":2,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
linked_tree.mutate(|v1| {
|
||||
let mut left = v1.left.clone().unwrap();
|
||||
left.val = 13;
|
||||
v1.left = Some(left);
|
||||
})?;
|
||||
|
||||
assert_eq!(
|
||||
format!("{}", linked_tree.readonly()),
|
||||
"{\"val\":10,\"left\":{\"val\":13,\"left\":null,\"right\":null},\"right\":{\"val\":3,\"left\":{\"val\":4,\"left\":null,\"right\":null},\"right\":null}}"
|
||||
);
|
||||
|
||||
fs::remove_file("test.txt").expect("Unable to remove file");
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
mod bracket;
|
||||
mod file_linked;
|
||||
mod tree;
|
|
@ -1,36 +0,0 @@
|
|||
use super::super::tree::Tree;
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
assert_eq!(
|
||||
Tree::new(30, None, Some(Box::new(Tree::new(20, None, None)))),
|
||||
Tree {
|
||||
val: 30,
|
||||
left: None,
|
||||
right: Some(Box::new(Tree {
|
||||
val: 20,
|
||||
left: None,
|
||||
right: None,
|
||||
})),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt() {
|
||||
assert_eq!(
|
||||
format!("{}", btree!("foo", btree!("bar"),),),
|
||||
"{\"val\":\"foo\",\"left\":{\"val\":\"bar\",\"left\":null,\"right\":null},\"right\":null}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_node() {
|
||||
let t = btree!(17, btree!(16), btree!(12));
|
||||
assert_eq!(Tree::fmt_node(&t.left), "16");
|
||||
assert_eq!(
|
||||
Tree::fmt_node(&Some(Box::new(btree!(btree!("foo"))))),
|
||||
"{\"val\":\"foo\",\"left\":null,\"right\":null}"
|
||||
);
|
||||
assert_eq!(Tree::<i32>::fmt_node(&None), "_");
|
||||
}
|
|
@ -2,26 +2,27 @@
|
|||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```
|
||||
//! let mut t = Tree::new(1, None, None);
|
||||
//! let t2 = Tree::new(2, Some(Box::new(t)), Some(Box::new(Tree::new(3, None, None))));
|
||||
//! let s = format!("{}", t2);
|
||||
//! ```no_run
|
||||
//! //let mut t = Tree::new(1, None, None);
|
||||
//! //let t2 = Tree::new(2, Some(Box::new(t)), Some(Box::new(Tree::new(3, None, None))));
|
||||
//! //let s = format!("{}", t2);
|
||||
//!
|
||||
//! assert_eq!(s, "(2: (1: _|_)|(3: _|_))");
|
||||
//! t.left = Some(Box::new(Tree::new(4, None, None)));
|
||||
//! assert_eq!(Tree::fmt_node(t.left), 4);
|
||||
//! assert_eq!(Tree::from_str(s), t2);
|
||||
//! //assert_eq!(s, "(2: (1: _|_)|(3: _|_))");
|
||||
//! //t.left = Some(Box::new(Tree::new(4, None, None)));
|
||||
//! //assert_eq!(Tree::fmt_node(t.left), 4);
|
||||
//! //assert_eq!(Tree::from_str(s), t2);
|
||||
//! ```
|
||||
//!
|
||||
//! Additionally the `btree!` macro can be used to conveniently initialize trees:
|
||||
//!
|
||||
//! ```no_run
|
||||
//! //# #[macro_use] extern crate tree;
|
||||
//! //# fn main() {
|
||||
//! //let t1 = btree!(1,btree!(2),btree!(3))
|
||||
//! //assert_eq!(format!("{}", t1), "(1: (2: _|_)|(3: _|_)")
|
||||
//! //# }
|
||||
//! ```
|
||||
//! # #[macro_use] extern crate tree;
|
||||
//! # fn main() {
|
||||
//! let t1 = btree!(1,btree!(2),btree!(3))
|
||||
//! assert_eq!(format!("{}", t1), "(1: (2: _|_)|(3: _|_)")
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -33,21 +34,21 @@ use std::str::FromStr;
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let mut t = Tree::new(1, None, None);
|
||||
/// let t2 = Tree::new(2, Some(Box::new(t)), Some(Box::new(Tree::new(3, None, None))));
|
||||
/// let s = format!("{}", t2);
|
||||
/// //let mut t = Tree::new(1, None, None);
|
||||
/// //let t2 = Tree::new(2, Some(Box::new(t)), Some(Box::new(Tree::new(3, None, None))));
|
||||
/// //let s = format!("{}", t2);
|
||||
///
|
||||
/// assert_eq!(s, "(2: (1: _|_)|(3: _|_))");
|
||||
/// t.left = Some(Box::new(Tree::new(4, None, None)));
|
||||
/// assert_eq!(Tree::fmt_node(t.left), 4);
|
||||
/// assert_eq!(Tree::from_str(s), t2);
|
||||
/// //assert_eq!(s, "(2: (1: _|_)|(3: _|_))");
|
||||
/// //t.left = Some(Box::new(Tree::new(4, None, None)));
|
||||
/// //assert_eq!(Tree::fmt_node(t.left), 4);
|
||||
/// //assert_eq!(Tree::from_str(s), t2);
|
||||
/// ```
|
||||
///
|
||||
/// Additionally the `btree!` macro can be used to conveniently initialize trees:
|
||||
///
|
||||
/// ```
|
||||
/// let t1 = btree!(1,btree!(2),btree!(3))
|
||||
/// assert_eq!(format!("{}", t1), "(1: (2: _|_)|(3: _|_)")
|
||||
/// //let t1 = btree!(1,btree!(2),btree!(3))
|
||||
/// //assert_eq!(format!("{}", t1), "(1: (2: _|_)|(3: _|_)")
|
||||
/// ```
|
||||
#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Debug)]
|
||||
pub struct Tree<T> {
|
||||
|
@ -60,18 +61,25 @@ pub struct Tree<T> {
|
|||
/// value of the root node, and the other two being child nodes. The last two arguments are
|
||||
/// optional.
|
||||
///
|
||||
/// ```
|
||||
/// // A tree with two child nodes.
|
||||
/// let t = btree!(1, Some(btree!(2)), Some(btree!(3)));
|
||||
///
|
||||
/// // A tree with only a left node.
|
||||
/// let t_left = btree!(1, Some(btree!(2)),);
|
||||
///
|
||||
/// // A tree with only a right node.
|
||||
/// let t_right = btree!(1, ,Some(btree!(3)));
|
||||
///
|
||||
/// // A tree with no children nodes.
|
||||
/// let t_single = btree!(1)
|
||||
/// ```no_run
|
||||
/// //#[macro_use]
|
||||
/// //extern crate gemla;
|
||||
/// //
|
||||
/// //use gemla::*;
|
||||
/// //
|
||||
/// //fn main() {
|
||||
/// // // A tree with two child nodes.
|
||||
/// // let t = btree!(1, Some(btree!(2)), Some(btree!(3)));
|
||||
/// //
|
||||
/// // // A tree with only a left node.
|
||||
/// // let t_left = btree!(1, Some(btree!(2)),);
|
||||
/// //
|
||||
/// // // A tree with only a right node.
|
||||
/// // let t_right = btree!(1, ,Some(btree!(3)));
|
||||
/// //
|
||||
/// // // A tree with no children nodes.
|
||||
/// // let t_single = btree!(1);
|
||||
/// //}
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! btree {
|
||||
|
@ -127,3 +135,45 @@ where
|
|||
serde_json::from_str(s).map_err(|_| format!("Unable to parse string {}", s))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests
|
||||
{
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_new() {
|
||||
assert_eq!(
|
||||
Tree::new(30, None, Some(Box::new(Tree::new(20, None, None)))),
|
||||
Tree {
|
||||
val: 30,
|
||||
left: None,
|
||||
right: Some(Box::new(Tree {
|
||||
val: 20,
|
||||
left: None,
|
||||
right: None,
|
||||
})),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt() {
|
||||
assert_eq!(
|
||||
format!("{}", btree!("foo", btree!("bar"),),),
|
||||
"{\"val\":\"foo\",\"left\":{\"val\":\"bar\",\"left\":null,\"right\":null},\"right\":null}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_fmt_node() {
|
||||
let t = btree!(17, btree!(16), btree!(12));
|
||||
assert_eq!(Tree::fmt_node(&t.left), "16");
|
||||
assert_eq!(
|
||||
Tree::fmt_node(&Some(Box::new(btree!(btree!("foo"))))),
|
||||
"{\"val\":\"foo\",\"left\":null,\"right\":null}"
|
||||
);
|
||||
assert_eq!(Tree::<i32>::fmt_node(&None), "_");
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue