oxihuman_export/
nuke_export.rs1#![allow(dead_code)]
4
5#[derive(Debug, Clone)]
9pub struct NukeNode {
10 pub class: String,
11 pub name: String,
12 pub knobs: Vec<(String, String)>,
13 pub xpos: i32,
14 pub ypos: i32,
15}
16
17#[derive(Debug, Clone)]
19pub struct NukeScriptExport {
20 pub version: String,
21 pub nodes: Vec<NukeNode>,
22}
23
24pub fn new_nuke_export(version: &str) -> NukeScriptExport {
26 NukeScriptExport {
27 version: version.to_string(),
28 nodes: Vec::new(),
29 }
30}
31
32pub fn nuke_add_node(export: &mut NukeScriptExport, class: &str, name: &str) {
34 export.nodes.push(NukeNode {
35 class: class.to_string(),
36 name: name.to_string(),
37 knobs: Vec::new(),
38 xpos: 0,
39 ypos: 0,
40 });
41}
42
43pub fn nuke_set_knob(export: &mut NukeScriptExport, key: &str, value: &str) {
45 if let Some(node) = export.nodes.last_mut() {
46 node.knobs.push((key.to_string(), value.to_string()));
47 }
48}
49
50pub fn nuke_set_position(export: &mut NukeScriptExport, x: i32, y: i32) {
52 if let Some(node) = export.nodes.last_mut() {
53 node.xpos = x;
54 node.ypos = y;
55 }
56}
57
58pub fn nuke_node_count(export: &NukeScriptExport) -> usize {
60 export.nodes.len()
61}
62
63pub fn nuke_to_string(export: &NukeScriptExport) -> String {
65 let mut out = format!("# Nuke {}\n", export.version);
66 for node in &export.nodes {
67 out.push_str(&format!("{} {{\n", node.class));
68 out.push_str(&format!(" name {}\n", node.name));
69 out.push_str(&format!(" xpos {}\n ypos {}\n", node.xpos, node.ypos));
70 for (k, v) in &node.knobs {
71 out.push_str(&format!(" {} {}\n", k, v));
72 }
73 out.push_str("}\n");
74 }
75 out
76}
77
78pub fn nuke_size_estimate(export: &NukeScriptExport) -> usize {
80 nuke_to_string(export).len()
81}
82
83pub fn nuke_find_node<'a>(export: &'a NukeScriptExport, name: &str) -> Option<&'a NukeNode> {
85 export.nodes.iter().find(|n| n.name == name)
86}
87
88pub fn validate_nuke(export: &NukeScriptExport) -> bool {
90 !export.version.is_empty()
91}
92
93pub fn nuke_count_by_class(export: &NukeScriptExport, class: &str) -> usize {
95 export.nodes.iter().filter(|n| n.class == class).count()
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 fn sample() -> NukeScriptExport {
103 let mut exp = new_nuke_export("15.0");
104 nuke_add_node(&mut exp, "Read", "Read1");
105 nuke_set_knob(&mut exp, "file", "/path/to/file.exr");
106 exp
107 }
108
109 #[test]
110 fn test_node_count() {
111 let exp = sample();
112 assert_eq!(nuke_node_count(&exp), 1);
113 }
114
115 #[test]
116 fn test_to_string_contains_class() {
117 let exp = sample();
118 assert!(nuke_to_string(&exp).contains("Read"));
119 }
120
121 #[test]
122 fn test_validate() {
123 let exp = sample();
124 assert!(validate_nuke(&exp));
125 }
126
127 #[test]
128 fn test_find_node() {
129 let exp = sample();
130 assert!(nuke_find_node(&exp, "Read1").is_some());
131 assert!(nuke_find_node(&exp, "NoSuch").is_none());
132 }
133
134 #[test]
135 fn test_count_by_class() {
136 let exp = sample();
137 assert_eq!(nuke_count_by_class(&exp, "Read"), 1);
138 assert_eq!(nuke_count_by_class(&exp, "Write"), 0);
139 }
140
141 #[test]
142 fn test_set_position() {
143 let mut exp = new_nuke_export("15.0");
144 nuke_add_node(&mut exp, "Dot", "Dot1");
145 nuke_set_position(&mut exp, 100, 200);
146 assert_eq!(exp.nodes[0].xpos, 100);
147 assert_eq!(exp.nodes[0].ypos, 200);
148 }
149
150 #[test]
151 fn test_size_estimate_positive() {
152 let exp = sample();
153 assert!(nuke_size_estimate(&exp) > 0);
154 }
155
156 #[test]
157 fn test_knob_count() {
158 let exp = sample();
159 assert_eq!(exp.nodes[0].knobs.len(), 1);
160 }
161
162 #[test]
163 fn test_empty_export() {
164 let exp = new_nuke_export("15.0");
165 assert_eq!(nuke_node_count(&exp), 0);
166 }
167}