unitforge 0.3.8__tar.gz → 0.3.9__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.
- {unitforge-0.3.8 → unitforge-0.3.9}/Cargo.lock +2 -9
- {unitforge-0.3.8 → unitforge-0.3.9}/Cargo.toml +4 -5
- {unitforge-0.3.8 → unitforge-0.3.9}/PKG-INFO +1 -1
- unitforge-0.3.8/unitforge_macros/src/lib.rs → unitforge-0.3.9/build.rs +97 -215
- {unitforge-0.3.8 → unitforge-0.3.9}/src/lib.rs +6 -4
- unitforge-0.3.9/src/quantities/mass_div_time_squared_volume.rs +43 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/relations.rs +3 -1
- unitforge-0.3.8/unitforge_macros/Cargo.toml +0 -15
- {unitforge-0.3.8 → unitforge-0.3.9}/.gitignore +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/.gitlab-ci.yml +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/Readme.md +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/Readme_py.md +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/pyproject.toml +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/impl_macros.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/prelude.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/acceleration.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/angle.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/angular_acceleration.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/angular_velocity.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/area.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/area_of_moment.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/charge.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/compliance.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/density.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/distance.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_area.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_distance.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_div_distance_power_four.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_per_volume.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_stress.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/force_volume.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/inverse_area.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/inverse_distance.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/inverse_stress.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/mass.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/mass_per_distance.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/rotational_stiffness.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/stiffness.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/strain.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/stress.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/stress_squared.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/time.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/velocity.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/velocity_squared.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/voltage.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities/volume.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/quantities.template.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/bindings/matrix3_py.template.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/bindings/vector3_py.template.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/matrix2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/matrix2x3.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/matrix3.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/matrix3x2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/vector2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/small_linalg/vector3.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/tests/quantity_unit_tests.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/src/tests/serde_tests.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/matrix2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/matrix2x3.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/matrix3.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/matrix3x2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/ndarray_dot.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/quantities.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/small_linalg_interfaces.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/test_quantities.py +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/test_small_linalg.py +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/vector2.rs +0 -0
- {unitforge-0.3.8 → unitforge-0.3.9}/tests/vector3.rs +0 -0
|
@@ -369,22 +369,15 @@ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
|
369
369
|
|
|
370
370
|
[[package]]
|
|
371
371
|
name = "unitforge"
|
|
372
|
-
version = "0.3.
|
|
372
|
+
version = "0.3.9"
|
|
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.
|
|
7
|
+
version = "0.3.9"
|
|
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
|
-
|
|
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,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
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
|
|
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
|
|
131
|
-
.
|
|
132
|
-
|
|
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]) ->
|
|
183
|
-
let alias_re =
|
|
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
|
-
|
|
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(
|
|
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 =
|
|
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> {{
|
|
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(
|
|
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(
|
|
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:
|
|
479
|
-
)
|
|
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
|
-
|
|
8
|
+
include!(concat!(env!("OUT_DIR"), "/quantities.rs"));
|
|
9
9
|
#[cfg(feature = "pyo3")]
|
|
10
|
-
|
|
10
|
+
include!(concat!(env!("OUT_DIR"), "/vector3_py.rs"));
|
|
11
11
|
#[cfg(feature = "pyo3")]
|
|
12
|
-
|
|
12
|
+
include!(concat!(env!("OUT_DIR"), "/matrix3_py.rs"));
|
|
13
13
|
#[cfg(feature = "pyo3")]
|
|
14
|
-
|
|
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,12 @@ 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!(
|
|
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);
|
|
55
56
|
|
|
56
57
|
impl_mul_relation_with_self!(Distance, Area);
|
|
57
58
|
impl_mul_relation_with_self!(Area, AreaOfMoment);
|
|
58
59
|
impl_mul_relation_with_self!(InverseDistance, InverseArea);
|
|
59
60
|
impl_mul_relation_with_self!(Stress, StressSquared);
|
|
61
|
+
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
|
|
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
|
|
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
|
|
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
|
|
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
|