unitforge 0.3.8__tar.gz → 0.3.10__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. {unitforge-0.3.8 → unitforge-0.3.10}/Cargo.lock +2 -9
  2. {unitforge-0.3.8 → unitforge-0.3.10}/Cargo.toml +4 -5
  3. {unitforge-0.3.8 → unitforge-0.3.10}/PKG-INFO +1 -1
  4. unitforge-0.3.8/unitforge_macros/src/lib.rs → unitforge-0.3.10/build.rs +97 -215
  5. {unitforge-0.3.8 → unitforge-0.3.10}/src/lib.rs +6 -4
  6. unitforge-0.3.10/src/quantities/mass_div_time_squared_volume.rs +43 -0
  7. {unitforge-0.3.8 → unitforge-0.3.10}/src/relations.rs +4 -1
  8. unitforge-0.3.8/unitforge_macros/Cargo.toml +0 -15
  9. {unitforge-0.3.8 → unitforge-0.3.10}/.gitignore +0 -0
  10. {unitforge-0.3.8 → unitforge-0.3.10}/.gitlab-ci.yml +0 -0
  11. {unitforge-0.3.8 → unitforge-0.3.10}/Readme.md +0 -0
  12. {unitforge-0.3.8 → unitforge-0.3.10}/Readme_py.md +0 -0
  13. {unitforge-0.3.8 → unitforge-0.3.10}/pyproject.toml +0 -0
  14. {unitforge-0.3.8 → unitforge-0.3.10}/src/impl_macros.rs +0 -0
  15. {unitforge-0.3.8 → unitforge-0.3.10}/src/prelude.rs +0 -0
  16. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/acceleration.rs +0 -0
  17. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/angle.rs +0 -0
  18. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/angular_acceleration.rs +0 -0
  19. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/angular_velocity.rs +0 -0
  20. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/area.rs +0 -0
  21. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/area_of_moment.rs +0 -0
  22. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/charge.rs +0 -0
  23. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/compliance.rs +0 -0
  24. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/density.rs +0 -0
  25. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/distance.rs +0 -0
  26. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force.rs +0 -0
  27. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_area.rs +0 -0
  28. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_distance.rs +0 -0
  29. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_div_distance_power_four.rs +0 -0
  30. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_per_volume.rs +0 -0
  31. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_stress.rs +0 -0
  32. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/force_volume.rs +0 -0
  33. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/inverse_area.rs +0 -0
  34. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/inverse_distance.rs +0 -0
  35. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/inverse_stress.rs +0 -0
  36. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/mass.rs +0 -0
  37. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/mass_per_distance.rs +0 -0
  38. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/rotational_stiffness.rs +0 -0
  39. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/stiffness.rs +0 -0
  40. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/strain.rs +0 -0
  41. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/stress.rs +0 -0
  42. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/stress_squared.rs +0 -0
  43. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/time.rs +0 -0
  44. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/velocity.rs +0 -0
  45. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/velocity_squared.rs +0 -0
  46. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/voltage.rs +0 -0
  47. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities/volume.rs +0 -0
  48. {unitforge-0.3.8 → unitforge-0.3.10}/src/quantities.template.rs +0 -0
  49. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/bindings/matrix3_py.template.rs +0 -0
  50. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/bindings/vector3_py.template.rs +0 -0
  51. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/matrix2.rs +0 -0
  52. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/matrix2x3.rs +0 -0
  53. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/matrix3.rs +0 -0
  54. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/matrix3x2.rs +0 -0
  55. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/vector2.rs +0 -0
  56. {unitforge-0.3.8 → unitforge-0.3.10}/src/small_linalg/vector3.rs +0 -0
  57. {unitforge-0.3.8 → unitforge-0.3.10}/src/tests/quantity_unit_tests.rs +0 -0
  58. {unitforge-0.3.8 → unitforge-0.3.10}/src/tests/serde_tests.rs +0 -0
  59. {unitforge-0.3.8 → unitforge-0.3.10}/tests/matrix2.rs +0 -0
  60. {unitforge-0.3.8 → unitforge-0.3.10}/tests/matrix2x3.rs +0 -0
  61. {unitforge-0.3.8 → unitforge-0.3.10}/tests/matrix3.rs +0 -0
  62. {unitforge-0.3.8 → unitforge-0.3.10}/tests/matrix3x2.rs +0 -0
  63. {unitforge-0.3.8 → unitforge-0.3.10}/tests/ndarray_dot.rs +0 -0
  64. {unitforge-0.3.8 → unitforge-0.3.10}/tests/quantities.rs +0 -0
  65. {unitforge-0.3.8 → unitforge-0.3.10}/tests/small_linalg_interfaces.rs +0 -0
  66. {unitforge-0.3.8 → unitforge-0.3.10}/tests/test_quantities.py +0 -0
  67. {unitforge-0.3.8 → unitforge-0.3.10}/tests/test_small_linalg.py +0 -0
  68. {unitforge-0.3.8 → unitforge-0.3.10}/tests/vector2.rs +0 -0
  69. {unitforge-0.3.8 → unitforge-0.3.10}/tests/vector3.rs +0 -0
@@ -369,22 +369,15 @@ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
369
369
 
370
370
  [[package]]
371
371
  name = "unitforge"
372
- version = "0.3.8"
372
+ version = "0.3.10"
373
373
  dependencies = [
374
374
  "ndarray",
375
375
  "num-traits",
376
376
  "numpy",
377
377
  "pyo3",
378
+ "regex",
378
379
  "serde",
379
380
  "serde_json",
380
381
  "strum",
381
382
  "strum_macros",
382
- "unitforge_macros",
383
- ]
384
-
385
- [[package]]
386
- name = "unitforge_macros"
387
- version = "0.3.8"
388
- dependencies = [
389
- "regex",
390
383
  ]
@@ -4,7 +4,7 @@ crate-type = ["cdylib", "rlib"]
4
4
 
5
5
  [package]
6
6
  name = "unitforge"
7
- version = "0.3.8"
7
+ version = "0.3.10"
8
8
  edition = "2021"
9
9
  authors = ["Dr.Q team <info@askdrq.com>", "Henrik Stromberg <henrik@askdrq.com>"]
10
10
  description = "A library for unit and quantity consistent computations in Rust"
@@ -23,12 +23,11 @@ pyo3 = { version = "0.26.0", features = ["extension-module", "auto-initialize",
23
23
  numpy = { version = "0.26.0", optional = true }
24
24
  strum = { version = "0.27.2", optional = true }
25
25
  strum_macros = { version = "0.27.2", optional = true }
26
- unitforge_macros = { version = "0.3.8", path = "unitforge_macros" }
26
+
27
+ [build-dependencies]
28
+ regex = "1.11.1"
27
29
 
28
30
  [features]
29
31
  serde = ["dep:serde", "dep:serde_json", "ndarray/serde"]
30
32
  pyo3 = ["dep:pyo3", "dep:numpy"]
31
33
  strum = ["dep:strum", "dep:strum_macros"]
32
-
33
- [workspace]
34
- members = ["unitforge_macros"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unitforge
3
- Version: 0.3.8
3
+ Version: 0.3.10
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Rust
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -1,172 +1,67 @@
1
- use proc_macro::TokenStream;
2
1
  use regex::Regex;
3
- use std::fs;
4
- use std::io;
2
+ use std::fs::File;
5
3
  use std::path::{Path, PathBuf};
6
-
7
- struct SourceFile {
8
- rel_path: String,
9
- content: String,
10
- }
11
-
12
- struct Context {
13
- files: Vec<String>,
14
- quantity_files: Vec<SourceFile>,
15
- relations: Option<SourceFile>,
16
- quantity_names: Vec<String>,
17
- aliases: Vec<(String, String, String, String)>,
18
- }
19
-
20
- #[proc_macro]
21
- pub fn generate_quantities(_input: TokenStream) -> TokenStream {
22
- match generate_quantities_impl() {
23
- Ok(tokens) => tokens,
24
- Err(err) => compile_error(&err),
4
+ use std::{env, fs, io::Write};
5
+
6
+ fn main() {
7
+ let quantities_template_path = "src/quantities.template.rs".to_string();
8
+ let vector_template_path = "src/small_linalg/bindings/vector3_py.template.rs".to_string();
9
+ let matrix_template_path = "src/small_linalg/bindings/matrix3_py.template.rs".to_string();
10
+ println!("cargo:rerun-if-changed=src/quantities/");
11
+ println!("cargo:rerun-if-changed=src/relations.rs");
12
+ println!("cargo:rerun-if-changed={quantities_template_path}");
13
+ println!("cargo:rerun-if-changed={vector_template_path}");
14
+ println!("cargo:rerun-if-changed={matrix_template_path}");
15
+
16
+ let out_dir = env::var("OUT_DIR").unwrap();
17
+
18
+ let mut files = read_all_rs_files(Path::new("src/quantities"));
19
+ if let Ok(relations) = fs::read_to_string("src/relations.rs") {
20
+ files.push(relations);
25
21
  }
26
- }
27
22
 
28
- #[proc_macro]
29
- pub fn generate_vector3_py(_input: TokenStream) -> TokenStream {
30
- match generate_vector3_py_impl() {
31
- Ok(tokens) => tokens,
32
- Err(err) => compile_error(&err),
33
- }
34
- }
23
+ let quantity_macro_re = Regex::new(r"impl_quantity!\s*\(\s*(\w+)").unwrap();
24
+ let quantity_names = extract_quantities(&files, &quantity_macro_re);
25
+ let aliases = extract_aliases(&files);
35
26
 
36
- #[proc_macro]
37
- pub fn generate_matrix3_py(_input: TokenStream) -> TokenStream {
38
- match generate_matrix3_py_impl() {
39
- Ok(tokens) => tokens,
40
- Err(err) => compile_error(&err),
41
- }
42
- }
27
+ write_quantity_code(
28
+ &Path::new(&out_dir).join("quantities.rs"),
29
+ &files,
30
+ &quantity_names,
31
+ quantities_template_path,
32
+ );
43
33
 
44
- #[proc_macro]
45
- pub fn generate_python_module_definition(_input: TokenStream) -> TokenStream {
46
- match generate_python_module_definition_impl() {
47
- Ok(tokens) => tokens,
48
- Err(err) => compile_error(&err),
34
+ if env::var("CARGO_FEATURE_PYO3").is_ok() {
35
+ write_vector_code(
36
+ &Path::new(&out_dir).join("vector3_py.rs"),
37
+ &quantity_names,
38
+ vector_template_path,
39
+ );
40
+ write_matrix_code(
41
+ &Path::new(&out_dir).join("matrix3_py.rs"),
42
+ &quantity_names,
43
+ matrix_template_path,
44
+ );
45
+ write_module_definition(
46
+ &Path::new(&out_dir).join("python_module_definition.rs"),
47
+ &quantity_names,
48
+ aliases,
49
+ );
49
50
  }
50
51
  }
51
52
 
52
- fn generate_quantities_impl() -> Result<TokenStream, String> {
53
- let ctx = load_context()?;
54
- let template = read_template("quantities.template.rs")?;
55
- let generated = write_quantity_code(&template, &ctx.files, &ctx.quantity_names);
56
- let deps = dependency_consts(&deps_for_quantities(&ctx));
57
- parse_generated(&format!("{generated}\n{deps}"))
58
- }
59
-
60
- fn generate_vector3_py_impl() -> Result<TokenStream, String> {
61
- let ctx = load_context()?;
62
- let template = read_template("small_linalg/bindings/vector3_py.template.rs")?;
63
- let generated = write_vector_code(&template, &ctx.quantity_names);
64
- let mut deps_list = deps_for_vector_matrix(&ctx);
65
- deps_list.push("small_linalg/bindings/vector3_py.template.rs".to_string());
66
- let deps = dependency_consts(&deps_list);
67
- parse_generated(&format!("{generated}\n{deps}"))
68
- }
69
-
70
- fn generate_matrix3_py_impl() -> Result<TokenStream, String> {
71
- let ctx = load_context()?;
72
- let template = read_template("small_linalg/bindings/matrix3_py.template.rs")?;
73
- let generated = write_matrix_code(&template, &ctx.quantity_names);
74
- let mut deps_list = deps_for_vector_matrix(&ctx);
75
- deps_list.push("small_linalg/bindings/matrix3_py.template.rs".to_string());
76
- let deps = dependency_consts(&deps_list);
77
- parse_generated(&format!("{generated}\n{deps}"))
78
- }
79
-
80
- fn generate_python_module_definition_impl() -> Result<TokenStream, String> {
81
- let ctx = load_context()?;
82
- let generated = write_module_definition(&ctx.quantity_names, &ctx.aliases);
83
- let deps = dependency_consts(&deps_for_python_module_definition(&ctx));
84
- parse_generated(&format!("{generated}\n{deps}"))
85
- }
86
-
87
- fn compile_error(message: &str) -> TokenStream {
88
- format!("compile_error!({:?});", message)
89
- .parse()
90
- .unwrap_or_else(|_| TokenStream::new())
91
- }
92
-
93
- fn parse_generated(src: &str) -> Result<TokenStream, String> {
94
- src.parse().map_err(|e| format!("Failed to parse generated code: {e}"))
95
- }
96
-
97
- fn unitforge_root() -> PathBuf {
98
- std::env::var("CARGO_MANIFEST_DIR")
99
- .map(PathBuf::from)
100
- .unwrap_or_else(|_| PathBuf::from("."))
101
- }
102
-
103
- fn read_template(rel_path: &str) -> Result<String, String> {
104
- let root = unitforge_root();
105
- let path = root.join("src").join(rel_path);
106
- fs::read_to_string(&path)
107
- .map_err(|e| format!("Failed to read template {}: {e}", path.display()))
108
- }
109
-
110
- fn rel_path_from_src(src_root: &Path, path: &Path) -> Result<String, String> {
111
- let rel = path
112
- .strip_prefix(src_root)
113
- .map_err(|e| format!("Failed to compute relative path: {e}"))?;
114
- Ok(rel.to_string_lossy().replace('\\', "/"))
115
- }
116
-
117
- fn load_context() -> Result<Context, String> {
118
- let root = unitforge_root();
119
- let src_root = root.join("src");
120
- let quantities_dir = src_root.join("quantities");
121
-
122
- let mut quantity_files = Vec::new();
123
- let entries = fs::read_dir(&quantities_dir)
124
- .map_err(|e| format!("Can't read {}: {e}", quantities_dir.display()))?;
125
-
126
- for entry in entries {
127
- let entry = entry.map_err(|e| format!("Failed to read quantity entry: {e}"))?;
53
+ fn read_all_rs_files(dir: &Path) -> Vec<String> {
54
+ let mut contents = Vec::new();
55
+ for entry in fs::read_dir(dir).expect("Can't read src/quantities") {
56
+ let entry = entry.unwrap();
128
57
  let path = entry.path();
129
58
  if path.extension().and_then(|s| s.to_str()) == Some("rs") {
130
- let content = fs::read_to_string(&path)
131
- .map_err(|e| format!("Failed to read {}: {e}", path.display()))?;
132
- let rel_path = rel_path_from_src(&src_root, &path)?;
133
- quantity_files.push(SourceFile { rel_path, content });
59
+ if let Ok(c) = fs::read_to_string(&path) {
60
+ contents.push(c);
61
+ }
134
62
  }
135
63
  }
136
-
137
- let mut files = quantity_files
138
- .iter()
139
- .map(|file| file.content.clone())
140
- .collect::<Vec<_>>();
141
-
142
- let relations_path = src_root.join("relations.rs");
143
- let relations = match fs::read_to_string(&relations_path) {
144
- Ok(content) => {
145
- let rel_path = rel_path_from_src(&src_root, &relations_path)?;
146
- files.push(content.clone());
147
- Some(SourceFile { rel_path, content })
148
- }
149
- Err(err) if err.kind() == io::ErrorKind::NotFound => None,
150
- Err(err) => {
151
- return Err(format!(
152
- "Failed to read {}: {err}",
153
- relations_path.display()
154
- ))
155
- }
156
- };
157
-
158
- let quantity_macro_re =
159
- Regex::new(r"impl_quantity!\s*\(\s*(\w+)").map_err(|e| e.to_string())?;
160
- let quantity_names = extract_quantities(&files, &quantity_macro_re);
161
- let aliases = extract_aliases(&files)?;
162
-
163
- Ok(Context {
164
- files,
165
- quantity_files,
166
- relations,
167
- quantity_names,
168
- aliases,
169
- })
64
+ contents
170
65
  }
171
66
 
172
67
  fn extract_quantities(files: &[String], re: &Regex) -> Vec<String> {
@@ -179,11 +74,9 @@ fn extract_quantities(files: &[String], re: &Regex) -> Vec<String> {
179
74
  result
180
75
  }
181
76
 
182
- fn extract_aliases(files: &[String]) -> Result<Vec<(String, String, String, String)>, String> {
183
- let alias_re = Regex::new(
184
- r"make_alias!\s*\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)",
185
- )
186
- .map_err(|e| e.to_string())?;
77
+ fn extract_aliases(files: &[String]) -> Vec<(String, String, String, String)> {
78
+ let alias_re =
79
+ Regex::new(r"make_alias!\s*\(\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*,\s*(\w+)\s*\)").unwrap();
187
80
  let mut result = Vec::new();
188
81
 
189
82
  for content in files {
@@ -197,7 +90,7 @@ fn extract_aliases(files: &[String]) -> Result<Vec<(String, String, String, Stri
197
90
  }
198
91
  }
199
92
 
200
- Ok(result)
93
+ result
201
94
  }
202
95
 
203
96
  fn camel_to_snake(input: &str) -> String {
@@ -215,7 +108,15 @@ fn camel_to_snake(input: &str) -> String {
215
108
  result
216
109
  }
217
110
 
218
- fn write_quantity_code(template: &str, files: &[String], quantity_names: &[String]) -> String {
111
+ fn write_quantity_code(
112
+ dest_path: &PathBuf,
113
+ files: &[String],
114
+ quantity_names: &[String],
115
+ template_path: String,
116
+ ) {
117
+ let template =
118
+ fs::read_to_string(template_path).expect("Failed to read quantities.template.rs");
119
+
219
120
  let mut quantity_variants = String::new();
220
121
  let mut quantity_to_variants = String::new();
221
122
  let mut quantity_fmt_matches = String::new();
@@ -241,12 +142,9 @@ fn write_quantity_code(template: &str, files: &[String], quantity_names: &[Strin
241
142
  let mul_self_re = Regex::new(r"impl_mul_with_self!\(\s*(\w+),\s*(\w+)\)").unwrap();
242
143
  let div_self_re = Regex::new(r"impl_div_with_self_to_f64!\(\s*(\w+)\)").unwrap();
243
144
  let sqrt_macro_re = Regex::new(r"impl_sqrt!\(\s*(\w+),\s*(\w+)\s*\)").unwrap();
244
- let mul_rel_re = Regex::new(
245
- r"impl_mul_relation_with_other!\(\s*(\w+),\s*(\w+),\s*(\w+)\)",
246
- )
247
- .unwrap();
248
- let mul_self_rel_re =
249
- Regex::new(r"impl_mul_relation_with_self!\(\s*(\w+),\s*(\w+)\)").unwrap();
145
+ let mul_rel_re =
146
+ Regex::new(r"impl_mul_relation_with_other!\(\s*(\w+),\s*(\w+),\s*(\w+)\)").unwrap();
147
+ let mul_self_rel_re = Regex::new(r"impl_mul_relation_with_self!\(\s*(\w+),\s*(\w+)\)").unwrap();
250
148
 
251
149
  let mut first = true;
252
150
  for struct_name in quantity_names {
@@ -296,7 +194,12 @@ fn write_quantity_code(template: &str, files: &[String], quantity_names: &[Strin
296
194
 
297
195
  let lower = camel_to_snake(struct_name);
298
196
  base_quantity_matches += &format!(
299
- " pub fn extract_{lower}(&self) -> Result<{struct_name}, String> {{\n match self {{\n Quantity::{struct_name}Quantity(v) => Ok(*v),\n _ => Err(\"Cannot extract {struct_name} from Quantity enum\".into()),\n }}\n }}\n\n",
197
+ " pub fn extract_{lower}(&self) -> Result<{struct_name}, String> {{
198
+ match self {{
199
+ Quantity::{struct_name}Quantity(v) => Ok(*v),
200
+ _ => Err(\"Cannot extract {struct_name} from Quantity enum\".into()),
201
+ }}
202
+ }}\n\n",
300
203
  );
301
204
 
302
205
  first = false;
@@ -377,7 +280,7 @@ fn write_quantity_code(template: &str, files: &[String], quantity_names: &[Strin
377
280
  }
378
281
  }
379
282
 
380
- template
283
+ let generated = template
381
284
  .replace("// __QUANTITY_VARIANTS__", &quantity_variants)
382
285
  .replace("// __QUANTITY_TO_VARIANTS__", &quantity_to_variants)
383
286
  .replace("// __QUANTITY_FMT_MATCHES__", &quantity_fmt_matches)
@@ -396,10 +299,16 @@ fn write_quantity_code(template: &str, files: &[String], quantity_names: &[Strin
396
299
  .replace("// __BASE_QUANTITY_MATCHES__", &base_quantity_matches)
397
300
  .replace("// __ADD_QUANTITY_MATCHES__", &add_matches)
398
301
  .replace("// __SUB_QUANTITY_MATCHES__", &sub_matches)
399
- .replace("// __QUANTITY_SQRTS__", &sqrt_matches)
302
+ .replace("// __QUANTITY_SQRTS__", &sqrt_matches);
303
+
304
+ let mut f = File::create(dest_path).expect("Could not create output quantities.rs");
305
+ f.write_all(generated.as_bytes())
306
+ .expect("Could not write quantities.rs");
400
307
  }
401
308
 
402
- fn write_vector_code(template: &str, quantity_names: &[String]) -> String {
309
+ fn write_vector_code(dest_path: &PathBuf, quantity_names: &[String], template_path: String) {
310
+ let template =
311
+ fs::read_to_string(template_path).expect("Failed to read vector3_py.template.rs");
403
312
  let mut raw_interfaces = String::new();
404
313
  for struct_name in quantity_names {
405
314
  let lower = camel_to_snake(struct_name);
@@ -427,10 +336,15 @@ fn write_vector_code(template: &str, quantity_names: &[String]) -> String {
427
336
  raw_interfaces += "\n }";
428
337
  raw_interfaces += "\n }";
429
338
  }
430
- template.replace("//__RAW_INTERFACE__", &raw_interfaces)
339
+ let generated = template.replace("//__RAW_INTERFACE__", &raw_interfaces);
340
+ let mut f = File::create(dest_path).expect("Could not create output vector3_py.rs");
341
+ f.write_all(generated.as_bytes())
342
+ .expect("Could not write vector3_py.rs");
431
343
  }
432
344
 
433
- fn write_matrix_code(template: &str, quantity_names: &[String]) -> String {
345
+ fn write_matrix_code(dest_path: &PathBuf, quantity_names: &[String], template_path: String) {
346
+ let template =
347
+ fs::read_to_string(template_path).expect("Failed to read matrix3_py.template.rs");
434
348
  let mut raw_interfaces = String::new();
435
349
  for struct_name in quantity_names {
436
350
  let lower = camel_to_snake(struct_name);
@@ -470,13 +384,17 @@ fn write_matrix_code(template: &str, quantity_names: &[String]) -> String {
470
384
  raw_interfaces += "\n }";
471
385
  raw_interfaces += "\n }";
472
386
  }
473
- template.replace("//__RAW_INTERFACE__", &raw_interfaces)
387
+ let generated = template.replace("//__RAW_INTERFACE__", &raw_interfaces);
388
+ let mut f = File::create(dest_path).expect("Could not create output matrix3_py.rs");
389
+ f.write_all(generated.as_bytes())
390
+ .expect("Could not write matrix3_py.rs");
474
391
  }
475
392
 
476
393
  fn write_module_definition(
394
+ dest_path: &PathBuf,
477
395
  quantity_names: &[String],
478
- aliases: &[(String, String, String, String)],
479
- ) -> String {
396
+ aliases: Vec<(String, String, String, String)>,
397
+ ) {
480
398
  let mut module_src = String::from(
481
399
  "#[pymodule]\n\
482
400
  pub fn unitforge(_py: Python<'_>, m: Bound<PyModule>) -> PyResult<()> {\n\
@@ -499,41 +417,5 @@ fn write_module_definition(
499
417
  ));
500
418
  }
501
419
  module_src.push_str(" Ok(())\n}\n");
502
- module_src
503
- }
504
-
505
- fn deps_for_quantities(ctx: &Context) -> Vec<String> {
506
- let mut deps = Vec::new();
507
- deps.push("quantities.template.rs".to_string());
508
- for file in &ctx.quantity_files {
509
- deps.push(file.rel_path.clone());
510
- }
511
- if let Some(relations) = &ctx.relations {
512
- deps.push(relations.rel_path.clone());
513
- }
514
- deps
515
- }
516
-
517
- fn deps_for_vector_matrix(ctx: &Context) -> Vec<String> {
518
- let mut deps = Vec::new();
519
- for file in &ctx.quantity_files {
520
- deps.push(file.rel_path.clone());
521
- }
522
- deps
523
- }
524
-
525
- fn deps_for_python_module_definition(ctx: &Context) -> Vec<String> {
526
- let mut deps = Vec::new();
527
- for file in &ctx.quantity_files {
528
- deps.push(file.rel_path.clone());
529
- }
530
- deps
531
- }
532
-
533
- fn dependency_consts(paths: &[String]) -> String {
534
- let mut result = String::new();
535
- for path in paths {
536
- result.push_str(&format!("const _: &str = include_str!(\"{}\");\n", path));
537
- }
538
- result
420
+ fs::write(dest_path, module_src).expect("Could not write python_module_definition.rs")
539
421
  }
@@ -5,13 +5,13 @@ pub use impl_macros::*;
5
5
  pub mod prelude;
6
6
  mod relations;
7
7
 
8
- unitforge_macros::generate_quantities!();
8
+ include!(concat!(env!("OUT_DIR"), "/quantities.rs"));
9
9
  #[cfg(feature = "pyo3")]
10
- unitforge_macros::generate_vector3_py!();
10
+ include!(concat!(env!("OUT_DIR"), "/vector3_py.rs"));
11
11
  #[cfg(feature = "pyo3")]
12
- unitforge_macros::generate_matrix3_py!();
12
+ include!(concat!(env!("OUT_DIR"), "/matrix3_py.rs"));
13
13
  #[cfg(feature = "pyo3")]
14
- unitforge_macros::generate_python_module_definition!();
14
+ include!(concat!(env!("OUT_DIR"), "/python_module_definition.rs"));
15
15
 
16
16
  pub use prelude::*;
17
17
 
@@ -54,6 +54,8 @@ pub mod quantities {
54
54
  pub use inverse_stress::*;
55
55
  pub mod mass;
56
56
  pub use mass::*;
57
+ pub mod mass_div_time_squared_volume;
58
+ pub use mass_div_time_squared_volume::*;
57
59
  pub mod mass_per_distance;
58
60
  pub use mass_per_distance::*;
59
61
  pub mod force_distance;
@@ -0,0 +1,43 @@
1
+ use crate::impl_macros::macros::*;
2
+ use crate::prelude::*;
3
+ use ndarray::{Array1, Array2, ArrayView1, ArrayView2};
4
+ use num_traits::identities::Zero;
5
+ use num_traits::{Float, FromPrimitive};
6
+ #[cfg(feature = "pyo3")]
7
+ use pyo3::pyclass;
8
+ #[cfg(feature = "serde")]
9
+ use serde::{Deserialize, Serialize};
10
+ use std::cmp::Ordering;
11
+ use std::fmt;
12
+ use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
13
+ #[cfg(feature = "strum")]
14
+ use strum_macros::EnumIter;
15
+
16
+ #[cfg_attr(feature = "strum", derive(EnumIter))]
17
+ #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18
+ #[derive(Copy, Clone, PartialEq, Debug)]
19
+ #[cfg_attr(feature = "pyo3", pyclass(eq, eq_int))]
20
+ pub enum MassDivTimeSquaredVolumeUnit {
21
+ kg_ssqmq,
22
+ }
23
+
24
+ impl PhysicsUnit for MassDivTimeSquaredVolumeUnit {
25
+ fn name(&self) -> &str {
26
+ match &self {
27
+ MassDivTimeSquaredVolumeUnit::kg_ssqmq => "kg/s²m³",
28
+ }
29
+ }
30
+
31
+ fn base_per_x(&self) -> (f64, i32) {
32
+ match self {
33
+ MassDivTimeSquaredVolumeUnit::kg_ssqmq => (1., 0),
34
+ }
35
+ }
36
+ }
37
+
38
+ impl_quantity!(
39
+ MassDivTimeSquaredVolume,
40
+ MassDivTimeSquaredVolumeUnit,
41
+ [MassDivTimeSquaredVolumeUnit::kg_ssqmq]
42
+ );
43
+ impl_div_with_self_to_f64!(MassDivTimeSquaredVolume);
@@ -50,10 +50,13 @@ impl_mul_relation_with_other!(Area, Density, MassPerDistance);
50
50
  impl_mul_relation_with_other!(MassPerDistance, Acceleration, Stiffness);
51
51
  impl_mul_relation_with_other!(Stiffness, AreaOfMoment, ForceVolume);
52
52
  impl_mul_relation_with_other!(RotationalStiffness, Angle, ForceDistance);
53
- impl_mul_relation_with_other!(InverseArea, Volume, Distance);
53
+ impl_mul_relation_with_other!(AngularAcceleration, Density, MassDivTimeSquaredVolume);
54
+ impl_mul_relation_with_other!(MassDivTimeSquaredVolume, Area, Stress);
54
55
  impl_mul_relation_with_other!(Force, Volume, ForceVolume);
56
+ impl_mul_relation_with_other!(Velocity, AngularVelocity, Acceleration);
55
57
 
56
58
  impl_mul_relation_with_self!(Distance, Area);
57
59
  impl_mul_relation_with_self!(Area, AreaOfMoment);
58
60
  impl_mul_relation_with_self!(InverseDistance, InverseArea);
59
61
  impl_mul_relation_with_self!(Stress, StressSquared);
62
+ impl_mul_relation_with_self!(AngularVelocity, AngularAcceleration);
@@ -1,15 +0,0 @@
1
- [package]
2
- name = "unitforge_macros"
3
- version = "0.3.8"
4
- edition = "2021"
5
- authors = ["Dr.Q team <info@askdrq.com>", "Henrik Stromberg <henrik@askdrq.com>"]
6
- description = "Proc macros for generating units, quantities, and Python bindings in unitforge"
7
- license = "MIT"
8
- repository = "https://gitlab.com/henrikjstromberg/unitforge"
9
- keywords = ["units", "quantities", "simulation", "physics"]
10
-
11
- [lib]
12
- proc-macro = true
13
-
14
- [dependencies]
15
- regex = "1.11.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes