#![allow(dead_code)]
#[derive(Debug, Clone)]
pub struct NukeNode {
pub class: String,
pub name: String,
pub knobs: Vec<(String, String)>,
pub xpos: i32,
pub ypos: i32,
}
#[derive(Debug, Clone)]
pub struct NukeScriptExport {
pub version: String,
pub nodes: Vec<NukeNode>,
}
pub fn new_nuke_export(version: &str) -> NukeScriptExport {
NukeScriptExport {
version: version.to_string(),
nodes: Vec::new(),
}
}
pub fn nuke_add_node(export: &mut NukeScriptExport, class: &str, name: &str) {
export.nodes.push(NukeNode {
class: class.to_string(),
name: name.to_string(),
knobs: Vec::new(),
xpos: 0,
ypos: 0,
});
}
pub fn nuke_set_knob(export: &mut NukeScriptExport, key: &str, value: &str) {
if let Some(node) = export.nodes.last_mut() {
node.knobs.push((key.to_string(), value.to_string()));
}
}
pub fn nuke_set_position(export: &mut NukeScriptExport, x: i32, y: i32) {
if let Some(node) = export.nodes.last_mut() {
node.xpos = x;
node.ypos = y;
}
}
pub fn nuke_node_count(export: &NukeScriptExport) -> usize {
export.nodes.len()
}
pub fn nuke_to_string(export: &NukeScriptExport) -> String {
let mut out = format!("# Nuke {}\n", export.version);
for node in &export.nodes {
out.push_str(&format!("{} {{\n", node.class));
out.push_str(&format!(" name {}\n", node.name));
out.push_str(&format!(" xpos {}\n ypos {}\n", node.xpos, node.ypos));
for (k, v) in &node.knobs {
out.push_str(&format!(" {} {}\n", k, v));
}
out.push_str("}\n");
}
out
}
pub fn nuke_size_estimate(export: &NukeScriptExport) -> usize {
nuke_to_string(export).len()
}
pub fn nuke_find_node<'a>(export: &'a NukeScriptExport, name: &str) -> Option<&'a NukeNode> {
export.nodes.iter().find(|n| n.name == name)
}
pub fn validate_nuke(export: &NukeScriptExport) -> bool {
!export.version.is_empty()
}
pub fn nuke_count_by_class(export: &NukeScriptExport, class: &str) -> usize {
export.nodes.iter().filter(|n| n.class == class).count()
}
#[cfg(test)]
mod tests {
use super::*;
fn sample() -> NukeScriptExport {
let mut exp = new_nuke_export("15.0");
nuke_add_node(&mut exp, "Read", "Read1");
nuke_set_knob(&mut exp, "file", "/path/to/file.exr");
exp
}
#[test]
fn test_node_count() {
let exp = sample();
assert_eq!(nuke_node_count(&exp), 1);
}
#[test]
fn test_to_string_contains_class() {
let exp = sample();
assert!(nuke_to_string(&exp).contains("Read"));
}
#[test]
fn test_validate() {
let exp = sample();
assert!(validate_nuke(&exp));
}
#[test]
fn test_find_node() {
let exp = sample();
assert!(nuke_find_node(&exp, "Read1").is_some());
assert!(nuke_find_node(&exp, "NoSuch").is_none());
}
#[test]
fn test_count_by_class() {
let exp = sample();
assert_eq!(nuke_count_by_class(&exp, "Read"), 1);
assert_eq!(nuke_count_by_class(&exp, "Write"), 0);
}
#[test]
fn test_set_position() {
let mut exp = new_nuke_export("15.0");
nuke_add_node(&mut exp, "Dot", "Dot1");
nuke_set_position(&mut exp, 100, 200);
assert_eq!(exp.nodes[0].xpos, 100);
assert_eq!(exp.nodes[0].ypos, 200);
}
#[test]
fn test_size_estimate_positive() {
let exp = sample();
assert!(nuke_size_estimate(&exp) > 0);
}
#[test]
fn test_knob_count() {
let exp = sample();
assert_eq!(exp.nodes[0].knobs.len(), 1);
}
#[test]
fn test_empty_export() {
let exp = new_nuke_export("15.0");
assert_eq!(nuke_node_count(&exp), 0);
}
}