1use std::path::Path;
4
5use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum CadFormat {
15 Step,
16 Stp,
17 Stl,
18 Obj,
19}
20
21impl CadFormat {
22 pub fn from_path(path: &Path) -> Option<CadFormat> {
24 let ext = path.extension()?.to_str()?.to_ascii_lowercase();
25 match ext.as_str() {
26 "step" => Some(CadFormat::Step),
27 "stp" => Some(CadFormat::Stp),
28 "stl" => Some(CadFormat::Stl),
29 "obj" => Some(CadFormat::Obj),
30 _ => None,
31 }
32 }
33
34 pub fn extension(self) -> &'static str {
36 match self {
37 CadFormat::Step => "step",
38 CadFormat::Stp => "stp",
39 CadFormat::Stl => "stl",
40 CadFormat::Obj => "obj",
41 }
42 }
43
44 pub fn is_brep(self) -> bool {
46 matches!(self, CadFormat::Step | CadFormat::Stp)
47 }
48
49 pub fn is_mesh(self) -> bool {
51 matches!(self, CadFormat::Stl | CadFormat::Obj)
52 }
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58 use std::path::PathBuf;
59
60 #[test]
61 fn detects_tracked_formats_case_insensitively() {
62 assert_eq!(
63 CadFormat::from_path(&PathBuf::from("a.step")),
64 Some(CadFormat::Step)
65 );
66 assert_eq!(
67 CadFormat::from_path(&PathBuf::from("a.STP")),
68 Some(CadFormat::Stp)
69 );
70 assert_eq!(
71 CadFormat::from_path(&PathBuf::from("m.STL")),
72 Some(CadFormat::Stl)
73 );
74 assert_eq!(
75 CadFormat::from_path(&PathBuf::from("m.obj")),
76 Some(CadFormat::Obj)
77 );
78 assert_eq!(CadFormat::from_path(&PathBuf::from("a.iges")), None);
79 assert_eq!(CadFormat::from_path(&PathBuf::from("noext")), None);
80 }
81
82 #[test]
83 fn brep_vs_mesh() {
84 assert!(CadFormat::Step.is_brep() && !CadFormat::Step.is_mesh());
85 assert!(CadFormat::Stl.is_mesh() && !CadFormat::Stl.is_brep());
86 }
87}