Skip to main content

rust_motion_paths/
subpaths.rs

1//! SVG subpath extraction.
2
3use crate::parser::{parse_path, serialize_instructions};
4use crate::types::Instruction;
5
6/// Splits a compound SVG path into individual subpaths based on `M` (move) commands.
7///
8/// Returns an empty vector if the path cannot be parsed or contains no instructions.
9pub fn get_subpaths(path: &str) -> Vec<String> {
10    let instructions = match parse_path(path) {
11        Ok(insts) => insts,
12        Err(_) => return Vec::new(),
13    };
14
15    let mut subpaths = Vec::new();
16    let mut current_subpath = Vec::new();
17
18    for inst in instructions {
19        if matches!(inst, Instruction::MoveTo { .. }) && !current_subpath.is_empty() {
20            subpaths.push(serialize_instructions(&current_subpath));
21            current_subpath.clear();
22        }
23        current_subpath.push(inst);
24    }
25
26    if !current_subpath.is_empty() {
27        subpaths.push(serialize_instructions(&current_subpath));
28    }
29
30    subpaths
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36
37    #[test]
38    fn test_get_subpaths() {
39        let path = "M 0 0 L 10 10 M 20 20 L 30 30 Z";
40        let subpaths = get_subpaths(path);
41        assert_eq!(subpaths.len(), 2);
42        assert_eq!(subpaths[0], "M 0.0000 0.0000 L 10.0000 10.0000");
43        assert_eq!(subpaths[1], "M 20.0000 20.0000 L 30.0000 30.0000 Z");
44    }
45}