siderust-js 0.1.0

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 (272) hide show
  1. package/.github/workflows/ci.yml +166 -0
  2. package/.gitmodules +9 -0
  3. package/CHANGELOG.md +26 -0
  4. package/LICENSE +661 -0
  5. package/README.md +138 -0
  6. package/package.json +12 -0
  7. package/qtty-js/.github/workflows/ci.yml +151 -0
  8. package/qtty-js/.gitmodules +3 -0
  9. package/qtty-js/CHANGELOG.md +31 -0
  10. package/qtty-js/LICENSE +661 -0
  11. package/qtty-js/README.md +132 -0
  12. package/qtty-js/package.json +20 -0
  13. package/qtty-js/qtty/.github/workflows/ci.yml +155 -0
  14. package/qtty-js/qtty/CHANGELOG.md +120 -0
  15. package/qtty-js/qtty/Cargo.lock +1462 -0
  16. package/qtty-js/qtty/Cargo.toml +12 -0
  17. package/qtty-js/qtty/LICENSE +661 -0
  18. package/qtty-js/qtty/README.md +9 -0
  19. package/qtty-js/qtty/qtty/Cargo.toml +41 -0
  20. package/qtty-js/qtty/qtty/README.md +8 -0
  21. package/qtty-js/qtty/qtty/examples/angles.rs +14 -0
  22. package/qtty-js/qtty/qtty/examples/astronomy.rs +17 -0
  23. package/qtty-js/qtty/qtty/examples/dimensional_arithmetic.rs +83 -0
  24. package/qtty-js/qtty/qtty/examples/python_integration.rs +61 -0
  25. package/qtty-js/qtty/qtty/examples/quickstart.rs +15 -0
  26. package/qtty-js/qtty/qtty/examples/ratios.rs +12 -0
  27. package/qtty-js/qtty/qtty/examples/serde_with_unit.rs +234 -0
  28. package/qtty-js/qtty/qtty/examples/serialization.rs +141 -0
  29. package/qtty-js/qtty/qtty/examples/serialization_advanced.rs +155 -0
  30. package/qtty-js/qtty/qtty/src/f32.rs +108 -0
  31. package/qtty-js/qtty/qtty/src/f64.rs +30 -0
  32. package/qtty-js/qtty/qtty/src/i128.rs +111 -0
  33. package/qtty-js/qtty/qtty/src/i16.rs +111 -0
  34. package/qtty-js/qtty/qtty/src/i32.rs +111 -0
  35. package/qtty-js/qtty/qtty/src/i64.rs +111 -0
  36. package/qtty-js/qtty/qtty/src/i8.rs +111 -0
  37. package/qtty-js/qtty/qtty/src/lib.rs +238 -0
  38. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.lock +83 -0
  39. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/Cargo.toml +10 -0
  40. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std/src/lib.rs +7 -0
  41. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.lock +83 -0
  42. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/Cargo.toml +10 -0
  43. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-no-std-alloc/src/lib.rs +7 -0
  44. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.lock +83 -0
  45. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/Cargo.toml +10 -0
  46. package/qtty-js/qtty/qtty/tests/fixtures/qtty-vec-std/src/lib.rs +5 -0
  47. package/qtty-js/qtty/qtty/tests/integration_tests.rs +529 -0
  48. package/qtty-js/qtty/qtty/tests/qtty_vec_feature_matrix.rs +58 -0
  49. package/qtty-js/qtty/qtty-core/Cargo.toml +41 -0
  50. package/qtty-js/qtty/qtty-core/README.md +8 -0
  51. package/qtty-js/qtty/qtty-core/examples/diesel_integration.rs +145 -0
  52. package/qtty-js/qtty/qtty-core/examples/quantity_db_serde.rs +215 -0
  53. package/qtty-js/qtty/qtty-core/src/dimension.rs +249 -0
  54. package/qtty-js/qtty/qtty-core/src/feature_diesel.rs +318 -0
  55. package/qtty-js/qtty/qtty-core/src/feature_pyo3.rs +27 -0
  56. package/qtty-js/qtty/qtty-core/src/feature_serde.rs +203 -0
  57. package/qtty-js/qtty/qtty-core/src/feature_tiberius.rs +28 -0
  58. package/qtty-js/qtty/qtty-core/src/lib.rs +744 -0
  59. package/qtty-js/qtty/qtty-core/src/macros.rs +93 -0
  60. package/qtty-js/qtty/qtty-core/src/quantity.rs +810 -0
  61. package/qtty-js/qtty/qtty-core/src/scalar.rs +1742 -0
  62. package/qtty-js/qtty/qtty-core/src/unit.rs +332 -0
  63. package/qtty-js/qtty/qtty-core/src/units/angular.rs +1228 -0
  64. package/qtty-js/qtty/qtty-core/src/units/area.rs +243 -0
  65. package/qtty-js/qtty/qtty-core/src/units/frequency.rs +179 -0
  66. package/qtty-js/qtty/qtty-core/src/units/length.rs +1270 -0
  67. package/qtty-js/qtty/qtty-core/src/units/mass.rs +488 -0
  68. package/qtty-js/qtty/qtty-core/src/units/mod.rs +26 -0
  69. package/qtty-js/qtty/qtty-core/src/units/power.rs +324 -0
  70. package/qtty-js/qtty/qtty-core/src/units/time.rs +667 -0
  71. package/qtty-js/qtty/qtty-core/src/units/unitless.rs +212 -0
  72. package/qtty-js/qtty/qtty-core/src/units/velocity.rs +210 -0
  73. package/qtty-js/qtty/qtty-core/src/units/volume.rs +269 -0
  74. package/qtty-js/qtty/qtty-core/tests/core.rs +628 -0
  75. package/qtty-js/qtty/qtty-core/tests/diesel.rs +461 -0
  76. package/qtty-js/qtty/qtty-core/tests/integers.rs +632 -0
  77. package/qtty-js/qtty/qtty-core/tests/no_cross_unit_ops.rs +35 -0
  78. package/qtty-js/qtty/qtty-core/tests/pyo3.rs +334 -0
  79. package/qtty-js/qtty/qtty-core/tests/quantity_f32.rs +276 -0
  80. package/qtty-js/qtty/qtty-core/tests/scalar_decimal.rs +258 -0
  81. package/qtty-js/qtty/qtty-core/tests/scalar_f32.rs +286 -0
  82. package/qtty-js/qtty/qtty-core/tests/scalar_f64_real.rs +287 -0
  83. package/qtty-js/qtty/qtty-core/tests/scalar_rational.rs +260 -0
  84. package/qtty-js/qtty/qtty-core/tests/serde.rs +256 -0
  85. package/qtty-js/qtty/qtty-core/tests/tiberius.rs +208 -0
  86. package/qtty-js/qtty/qtty-derive/Cargo.toml +23 -0
  87. package/qtty-js/qtty/qtty-derive/README.md +8 -0
  88. package/qtty-js/qtty/qtty-derive/src/lib.rs +340 -0
  89. package/qtty-js/qtty/qtty-ffi/ARCHITECTURE.md +3 -0
  90. package/qtty-js/qtty/qtty-ffi/Cargo.toml +31 -0
  91. package/qtty-js/qtty/qtty-ffi/README.md +9 -0
  92. package/qtty-js/qtty/qtty-ffi/build.rs +326 -0
  93. package/qtty-js/qtty/qtty-ffi/cbindgen.toml +105 -0
  94. package/qtty-js/qtty/qtty-ffi/include/qtty_ffi.h +1126 -0
  95. package/qtty-js/qtty/qtty-ffi/src/ffi.rs +1251 -0
  96. package/qtty-js/qtty/qtty-ffi/src/ffi_serde.rs +294 -0
  97. package/qtty-js/qtty/qtty-ffi/src/helpers.rs +310 -0
  98. package/qtty-js/qtty/qtty-ffi/src/lib.rs +229 -0
  99. package/qtty-js/qtty/qtty-ffi/src/macros.rs +121 -0
  100. package/qtty-js/qtty/qtty-ffi/src/registry.rs +274 -0
  101. package/qtty-js/qtty/qtty-ffi/src/types.rs +620 -0
  102. package/qtty-js/qtty/qtty-ffi/tests/integration_tests.rs +842 -0
  103. package/qtty-js/qtty/qtty-ffi/units.csv +156 -0
  104. package/qtty-js/qtty/qtty-ffi/units.csv.md +3 -0
  105. package/qtty-js/qtty-node/.prettierignore +6 -0
  106. package/qtty-js/qtty-node/.prettierrc.json +6 -0
  107. package/qtty-js/qtty-node/README.md +250 -0
  108. package/qtty-js/qtty-node/c8.config.json +11 -0
  109. package/qtty-js/qtty-node/eslint.config.js +31 -0
  110. package/qtty-js/qtty-node/examples/arithmetic.mjs +64 -0
  111. package/qtty-js/qtty-node/examples/astronomy.mjs +90 -0
  112. package/qtty-js/qtty-node/examples/quickstart.mjs +36 -0
  113. package/qtty-js/qtty-node/examples/serialization.mjs +125 -0
  114. package/qtty-js/qtty-node/examples/unit_factories.mjs +74 -0
  115. package/qtty-js/qtty-node/index.d.ts +219 -0
  116. package/qtty-js/qtty-node/index.js +323 -0
  117. package/qtty-js/qtty-node/lib/DerivedQuantity.js +122 -0
  118. package/qtty-js/qtty-node/lib/Quantity.js +151 -0
  119. package/qtty-js/qtty-node/lib/backend.js +25 -0
  120. package/qtty-js/qtty-node/native.cjs +306 -0
  121. package/qtty-js/qtty-node/package-lock.json +3223 -0
  122. package/qtty-js/qtty-node/package.json +70 -0
  123. package/qtty-js/qtty-node/units.d.ts +299 -0
  124. package/qtty-js/qtty-node/units.js +210 -0
  125. package/qtty-js/qtty-web/Cargo.lock +767 -0
  126. package/qtty-js/qtty-web/Cargo.toml +21 -0
  127. package/qtty-js/qtty-web/index.d.ts +140 -0
  128. package/qtty-js/qtty-web/index.js +20 -0
  129. package/qtty-js/qtty-web/lib/DerivedQuantity.js +58 -0
  130. package/qtty-js/qtty-web/lib/Quantity.js +75 -0
  131. package/qtty-js/qtty-web/lib/backend.js +80 -0
  132. package/qtty-js/qtty-web/package.json +45 -0
  133. package/qtty-js/qtty-web/src/lib.rs +111 -0
  134. package/qtty-js/scripts/ci.sh +73 -0
  135. package/scripts/ci.sh +123 -0
  136. package/siderust-core/Cargo.lock +787 -0
  137. package/siderust-core/Cargo.toml +18 -0
  138. package/siderust-core/DEDUPLICATION.md +124 -0
  139. package/siderust-core/src/body.rs +120 -0
  140. package/siderust-core/src/events.rs +184 -0
  141. package/siderust-core/src/lib.rs +20 -0
  142. package/siderust-core/src/observer.rs +55 -0
  143. package/siderust-core/src/position.rs +213 -0
  144. package/siderust-node/.prettierignore +7 -0
  145. package/siderust-node/.prettierrc.json +6 -0
  146. package/siderust-node/Cargo.lock +906 -0
  147. package/siderust-node/Cargo.toml +29 -0
  148. package/siderust-node/README.md +109 -0
  149. package/siderust-node/__test__/index.test.mjs +248 -0
  150. package/siderust-node/build.rs +5 -0
  151. package/siderust-node/c8.config.json +3 -0
  152. package/siderust-node/eslint.config.js +31 -0
  153. package/siderust-node/examples/01_basic_coordinates.mjs +24 -0
  154. package/siderust-node/examples/02_coordinate_transformations.mjs +25 -0
  155. package/siderust-node/examples/03_all_frames_conversions.mjs +26 -0
  156. package/siderust-node/examples/04_all_center_conversions.mjs +24 -0
  157. package/siderust-node/examples/05_target_tracking.mjs +22 -0
  158. package/siderust-node/examples/06_night_events.mjs +18 -0
  159. package/siderust-node/examples/07_moon_properties.mjs +21 -0
  160. package/siderust-node/examples/08_solar_system.mjs +19 -0
  161. package/siderust-node/examples/09_star_observability.mjs +22 -0
  162. package/siderust-node/examples/10_time_periods.mjs +9 -0
  163. package/siderust-node/examples/11_serialization.mjs +31 -0
  164. package/siderust-node/examples/12_runtime_ephemeris.mjs +27 -0
  165. package/siderust-node/examples/13_coordinate_operations.mjs +20 -0
  166. package/siderust-node/index.d.ts +623 -0
  167. package/siderust-node/index.js +79 -0
  168. package/siderust-node/lib/Observer.js +112 -0
  169. package/siderust-node/lib/Star.js +118 -0
  170. package/siderust-node/lib/backend.js +63 -0
  171. package/siderust-node/lib/wrappers.js +566 -0
  172. package/siderust-node/main.js +20 -0
  173. package/siderust-node/native.cjs +360 -0
  174. package/siderust-node/package-lock.json +3261 -0
  175. package/siderust-node/package.json +71 -0
  176. package/siderust-node/src/body.rs +74 -0
  177. package/siderust-node/src/coordinates.rs +372 -0
  178. package/siderust-node/src/ephemeris.rs +462 -0
  179. package/siderust-node/src/events.rs +577 -0
  180. package/siderust-node/src/lib.rs +43 -0
  181. package/siderust-node/src/observer.rs +132 -0
  182. package/siderust-node/src/phase.rs +218 -0
  183. package/siderust-node/src/position.rs +292 -0
  184. package/siderust-node/src/star.rs +200 -0
  185. package/siderust-web/Cargo.lock +855 -0
  186. package/siderust-web/Cargo.toml +34 -0
  187. package/siderust-web/README.md +100 -0
  188. package/siderust-web/__test__/index.test.mjs +118 -0
  189. package/siderust-web/examples/github-pages/README.md +31 -0
  190. package/siderust-web/examples/github-pages/index.html +135 -0
  191. package/siderust-web/index.d.ts +311 -0
  192. package/siderust-web/index.js +66 -0
  193. package/siderust-web/lib/Observer.js +103 -0
  194. package/siderust-web/lib/Star.js +116 -0
  195. package/siderust-web/lib/backend.js +400 -0
  196. package/siderust-web/lib/wrappers.js +512 -0
  197. package/siderust-web/package.json +55 -0
  198. package/siderust-web/src/body.rs +69 -0
  199. package/siderust-web/src/coordinates.rs +302 -0
  200. package/siderust-web/src/ephemeris.rs +456 -0
  201. package/siderust-web/src/events.rs +520 -0
  202. package/siderust-web/src/lib.rs +51 -0
  203. package/siderust-web/src/observer.rs +117 -0
  204. package/siderust-web/src/phase.rs +190 -0
  205. package/siderust-web/src/position.rs +291 -0
  206. package/siderust-web/src/star.rs +178 -0
  207. package/tempoch-js/.github/workflows/ci.yml +142 -0
  208. package/tempoch-js/.gitmodules +3 -0
  209. package/tempoch-js/CHANGELOG.md +25 -0
  210. package/tempoch-js/LICENSE +661 -0
  211. package/tempoch-js/README.md +126 -0
  212. package/tempoch-js/package.json +20 -0
  213. package/tempoch-js/scripts/ci.sh +73 -0
  214. package/tempoch-js/tempoch/.github/workflows/ci.yml +113 -0
  215. package/tempoch-js/tempoch/CHANGELOG.md +82 -0
  216. package/tempoch-js/tempoch/Cargo.lock +947 -0
  217. package/tempoch-js/tempoch/Cargo.toml +3 -0
  218. package/tempoch-js/tempoch/LICENSE +661 -0
  219. package/tempoch-js/tempoch/README.md +76 -0
  220. package/tempoch-js/tempoch/tempoch/Cargo.toml +27 -0
  221. package/tempoch-js/tempoch/tempoch/examples/periods.rs +45 -0
  222. package/tempoch-js/tempoch/tempoch/examples/quickstart.rs +13 -0
  223. package/tempoch-js/tempoch/tempoch/src/lib.rs +49 -0
  224. package/tempoch-js/tempoch/tempoch/tests/integration.rs +57 -0
  225. package/tempoch-js/tempoch/tempoch-core/Cargo.toml +24 -0
  226. package/tempoch-js/tempoch/tempoch-core/src/delta_t.rs +345 -0
  227. package/tempoch-js/tempoch/tempoch-core/src/instant.rs +811 -0
  228. package/tempoch-js/tempoch/tempoch-core/src/julian_date_ext.rs +142 -0
  229. package/tempoch-js/tempoch/tempoch-core/src/lib.rs +81 -0
  230. package/tempoch-js/tempoch/tempoch-core/src/period.rs +1168 -0
  231. package/tempoch-js/tempoch/tempoch-core/src/scales.rs +779 -0
  232. package/tempoch-js/tempoch/tempoch-ffi/Cargo.lock +889 -0
  233. package/tempoch-js/tempoch/tempoch-ffi/Cargo.toml +26 -0
  234. package/tempoch-js/tempoch/tempoch-ffi/build.rs +24 -0
  235. package/tempoch-js/tempoch/tempoch-ffi/cbindgen.toml +30 -0
  236. package/tempoch-js/tempoch/tempoch-ffi/src/error.rs +19 -0
  237. package/tempoch-js/tempoch/tempoch-ffi/src/lib.rs +82 -0
  238. package/tempoch-js/tempoch/tempoch-ffi/src/period.rs +101 -0
  239. package/tempoch-js/tempoch/tempoch-ffi/src/time.rs +711 -0
  240. package/tempoch-js/tempoch/tempoch-ffi/tests/ffi.rs +265 -0
  241. package/tempoch-js/tempoch-node/.prettierignore +6 -0
  242. package/tempoch-js/tempoch-node/.prettierrc.json +6 -0
  243. package/tempoch-js/tempoch-node/Cargo.lock +496 -0
  244. package/tempoch-js/tempoch-node/Cargo.toml +29 -0
  245. package/tempoch-js/tempoch-node/README.md +265 -0
  246. package/tempoch-js/tempoch-node/__test__/index.test.mjs +598 -0
  247. package/tempoch-js/tempoch-node/build.rs +5 -0
  248. package/tempoch-js/tempoch-node/c8.config.json +3 -0
  249. package/tempoch-js/tempoch-node/eslint.config.js +31 -0
  250. package/tempoch-js/tempoch-node/examples/periods.mjs +79 -0
  251. package/tempoch-js/tempoch-node/examples/quickstart.mjs +71 -0
  252. package/tempoch-js/tempoch-node/examples/timescales.mjs +92 -0
  253. package/tempoch-js/tempoch-node/index.d.ts +280 -0
  254. package/tempoch-js/tempoch-node/index.js +32 -0
  255. package/tempoch-js/tempoch-node/lib/JulianDate.js +176 -0
  256. package/tempoch-js/tempoch-node/lib/ModifiedJulianDate.js +156 -0
  257. package/tempoch-js/tempoch-node/lib/Period.js +133 -0
  258. package/tempoch-js/tempoch-node/lib/backend.js +38 -0
  259. package/tempoch-js/tempoch-node/lib/qttyCompat.js +92 -0
  260. package/tempoch-js/tempoch-node/native.cjs +317 -0
  261. package/tempoch-js/tempoch-node/package-lock.json +3223 -0
  262. package/tempoch-js/tempoch-node/package.json +56 -0
  263. package/tempoch-js/tempoch-node/src/lib.rs +573 -0
  264. package/tempoch-js/tempoch-web/Cargo.toml +23 -0
  265. package/tempoch-js/tempoch-web/index.d.ts +95 -0
  266. package/tempoch-js/tempoch-web/index.js +27 -0
  267. package/tempoch-js/tempoch-web/lib/JulianDate.js +170 -0
  268. package/tempoch-js/tempoch-web/lib/ModifiedJulianDate.js +145 -0
  269. package/tempoch-js/tempoch-web/lib/Period.js +121 -0
  270. package/tempoch-js/tempoch-web/lib/backend.js +118 -0
  271. package/tempoch-js/tempoch-web/package.json +46 -0
  272. package/tempoch-js/tempoch-web/src/lib.rs +184 -0
@@ -0,0 +1,1126 @@
1
+ /**
2
+ * @file qtty_ffi.h
3
+ * @brief C-compatible FFI bindings for qtty physical quantities and unit conversions.
4
+ *
5
+ * This header provides the C API for the qtty-ffi library, enabling C/C++ code
6
+ * to construct and convert physical quantities using qtty's conversion logic.
7
+ *
8
+ * # Example Usage
9
+ *
10
+ * @code{.c}
11
+ * #include "qtty_ffi.h"
12
+ * #include <stdio.h>
13
+ *
14
+ * int main() {
15
+ * qtty_quantity_t meters, kilometers;
16
+ *
17
+ * // Create a quantity: 1000 meters
18
+ * int32_t status = qtty_quantity_make(1000.0, UNIT_ID_METER, &meters);
19
+ * if (status != QTTY_OK) {
20
+ * fprintf(stderr, "Failed to create quantity\n");
21
+ * return 1;
22
+ * }
23
+ *
24
+ * // Convert to kilometers
25
+ * status = qtty_quantity_convert(meters, UNIT_ID_KILOMETER, &kilometers);
26
+ * if (status == QTTY_OK) {
27
+ * printf("1000 meters = %.2f kilometers\n", kilometers.value);
28
+ * }
29
+ *
30
+ * return 0;
31
+ * }
32
+ * @endcode
33
+ *
34
+ * # Thread Safety
35
+ *
36
+ * All functions are thread-safe. The library contains no global mutable state.
37
+ *
38
+ * # ABI Stability
39
+ *
40
+ * Enum discriminant values and struct layouts are part of the ABI contract
41
+ * and will not change in backward-compatible releases.
42
+ *
43
+ * @version 1.0
44
+ */
45
+
46
+
47
+ #ifndef QTTY_FFI_H
48
+ #define QTTY_FFI_H
49
+
50
+ #include <stdarg.h>
51
+ #include <stdbool.h>
52
+ #include <stddef.h>
53
+ #include <stdint.h>
54
+ #include <stdlib.h>
55
+
56
+ /*
57
+ Success status code.
58
+ */
59
+ #define QTTY_OK 0
60
+
61
+ /*
62
+ Error: the provided unit ID is not recognized/valid.
63
+ */
64
+ #define QTTY_ERR_UNKNOWN_UNIT -1
65
+
66
+ /*
67
+ Error: conversion requested between incompatible dimensions.
68
+ */
69
+ #define QTTY_ERR_INCOMPATIBLE_DIM -2
70
+
71
+ /*
72
+ Error: a required output pointer was null.
73
+ */
74
+ #define QTTY_ERR_NULL_OUT -3
75
+
76
+ /*
77
+ Error: the provided value is invalid (reserved for future use).
78
+ */
79
+ #define QTTY_ERR_INVALID_VALUE -4
80
+
81
+ /*
82
+ Error: the provided output buffer is too small.
83
+ */
84
+ #define QTTY_ERR_BUFFER_TOO_SMALL -5
85
+
86
+ /*
87
+ Format flag: default decimal notation (e.g. `"1234.57 m"`).
88
+ */
89
+ #define QTTY_FMT_DEFAULT 0
90
+
91
+ /*
92
+ Format flag: scientific notation with lowercase `e` (e.g. `"1.23e3 m"`).
93
+ */
94
+ #define QTTY_FMT_LOWER_EXP 1
95
+
96
+ /*
97
+ Format flag: scientific notation with uppercase `E` (e.g. `"1.23E3 m"`).
98
+ */
99
+ #define QTTY_FMT_UPPER_EXP 2
100
+
101
+ /*
102
+ Unit identifier for FFI.
103
+
104
+ Each variant corresponds to a specific unit supported by the FFI layer.
105
+ All discriminant values are explicitly assigned and are part of the ABI contract.
106
+ */
107
+ enum UnitId
108
+ #ifdef __cplusplus
109
+ : uint32_t
110
+ #endif // __cplusplus
111
+ {
112
+ /*
113
+ PlanckLength (l_P)
114
+ */
115
+ UNIT_ID_PLANCK_LENGTH = 10000,
116
+ /*
117
+ Yoctometer (ym)
118
+ */
119
+ UNIT_ID_YOCTOMETER = 10001,
120
+ /*
121
+ Zeptometer (zm)
122
+ */
123
+ UNIT_ID_ZEPTOMETER = 10002,
124
+ /*
125
+ Attometer (am)
126
+ */
127
+ UNIT_ID_ATTOMETER = 10003,
128
+ /*
129
+ Femtometer (fm)
130
+ */
131
+ UNIT_ID_FEMTOMETER = 10004,
132
+ /*
133
+ Picometer (pm)
134
+ */
135
+ UNIT_ID_PICOMETER = 10005,
136
+ /*
137
+ Nanometer (nm)
138
+ */
139
+ UNIT_ID_NANOMETER = 10006,
140
+ /*
141
+ Micrometer (µm)
142
+ */
143
+ UNIT_ID_MICROMETER = 10007,
144
+ /*
145
+ Millimeter (mm)
146
+ */
147
+ UNIT_ID_MILLIMETER = 10008,
148
+ /*
149
+ Centimeter (cm)
150
+ */
151
+ UNIT_ID_CENTIMETER = 10009,
152
+ /*
153
+ Decimeter (dm)
154
+ */
155
+ UNIT_ID_DECIMETER = 10010,
156
+ /*
157
+ Meter (m)
158
+ */
159
+ UNIT_ID_METER = 10011,
160
+ /*
161
+ Decameter (dam)
162
+ */
163
+ UNIT_ID_DECAMETER = 10012,
164
+ /*
165
+ Hectometer (hm)
166
+ */
167
+ UNIT_ID_HECTOMETER = 10013,
168
+ /*
169
+ Kilometer (km)
170
+ */
171
+ UNIT_ID_KILOMETER = 10014,
172
+ /*
173
+ Megameter (Mm)
174
+ */
175
+ UNIT_ID_MEGAMETER = 10015,
176
+ /*
177
+ Gigameter (Gm)
178
+ */
179
+ UNIT_ID_GIGAMETER = 10016,
180
+ /*
181
+ Terameter (Tm)
182
+ */
183
+ UNIT_ID_TERAMETER = 10017,
184
+ /*
185
+ Petameter (Pm)
186
+ */
187
+ UNIT_ID_PETAMETER = 10018,
188
+ /*
189
+ Exameter (Em)
190
+ */
191
+ UNIT_ID_EXAMETER = 10019,
192
+ /*
193
+ Zettameter (Zm)
194
+ */
195
+ UNIT_ID_ZETTAMETER = 10020,
196
+ /*
197
+ Yottameter (Ym)
198
+ */
199
+ UNIT_ID_YOTTAMETER = 10021,
200
+ /*
201
+ BohrRadius (a₀)
202
+ */
203
+ UNIT_ID_BOHR_RADIUS = 11000,
204
+ /*
205
+ ClassicalElectronRadius (r_e)
206
+ */
207
+ UNIT_ID_CLASSICAL_ELECTRON_RADIUS = 11001,
208
+ /*
209
+ ElectronReducedComptonWavelength (λ̄_e)
210
+ */
211
+ UNIT_ID_ELECTRON_REDUCED_COMPTON_WAVELENGTH = 11002,
212
+ /*
213
+ AstronomicalUnit (au)
214
+ */
215
+ UNIT_ID_ASTRONOMICAL_UNIT = 11003,
216
+ /*
217
+ LightYear (ly)
218
+ */
219
+ UNIT_ID_LIGHT_YEAR = 11004,
220
+ /*
221
+ Parsec (pc)
222
+ */
223
+ UNIT_ID_PARSEC = 11005,
224
+ /*
225
+ Kiloparsec (kpc)
226
+ */
227
+ UNIT_ID_KILOPARSEC = 11006,
228
+ /*
229
+ Megaparsec (Mpc)
230
+ */
231
+ UNIT_ID_MEGAPARSEC = 11007,
232
+ /*
233
+ Gigaparsec (Gpc)
234
+ */
235
+ UNIT_ID_GIGAPARSEC = 11008,
236
+ /*
237
+ Inch (in)
238
+ */
239
+ UNIT_ID_INCH = 12000,
240
+ /*
241
+ Foot (ft)
242
+ */
243
+ UNIT_ID_FOOT = 12001,
244
+ /*
245
+ Yard (yd)
246
+ */
247
+ UNIT_ID_YARD = 12002,
248
+ /*
249
+ Mile (mi)
250
+ */
251
+ UNIT_ID_MILE = 12003,
252
+ /*
253
+ Link (lk)
254
+ */
255
+ UNIT_ID_LINK = 13000,
256
+ /*
257
+ Fathom (ftm)
258
+ */
259
+ UNIT_ID_FATHOM = 13001,
260
+ /*
261
+ Rod (rd)
262
+ */
263
+ UNIT_ID_ROD = 13002,
264
+ /*
265
+ Chain (ch)
266
+ */
267
+ UNIT_ID_CHAIN = 13003,
268
+ /*
269
+ NauticalMile (nmi)
270
+ */
271
+ UNIT_ID_NAUTICAL_MILE = 13004,
272
+ /*
273
+ NominalLunarRadius (R_☾)
274
+ */
275
+ UNIT_ID_NOMINAL_LUNAR_RADIUS = 15000,
276
+ /*
277
+ NominalLunarDistance (LD)
278
+ */
279
+ UNIT_ID_NOMINAL_LUNAR_DISTANCE = 15001,
280
+ /*
281
+ NominalEarthPolarRadius (R_⊕pol)
282
+ */
283
+ UNIT_ID_NOMINAL_EARTH_POLAR_RADIUS = 15002,
284
+ /*
285
+ NominalEarthRadius (R_⊕)
286
+ */
287
+ UNIT_ID_NOMINAL_EARTH_RADIUS = 15003,
288
+ /*
289
+ NominalEarthEquatorialRadius (R_⊕eq)
290
+ */
291
+ UNIT_ID_NOMINAL_EARTH_EQUATORIAL_RADIUS = 15004,
292
+ /*
293
+ EarthMeridionalCircumference (C_mer)
294
+ */
295
+ UNIT_ID_EARTH_MERIDIONAL_CIRCUMFERENCE = 15005,
296
+ /*
297
+ EarthEquatorialCircumference (C_eq)
298
+ */
299
+ UNIT_ID_EARTH_EQUATORIAL_CIRCUMFERENCE = 15006,
300
+ /*
301
+ NominalJupiterRadius (R_♃)
302
+ */
303
+ UNIT_ID_NOMINAL_JUPITER_RADIUS = 15007,
304
+ /*
305
+ NominalSolarRadius (R_☉)
306
+ */
307
+ UNIT_ID_NOMINAL_SOLAR_RADIUS = 15008,
308
+ /*
309
+ NominalSolarDiameter (D_☉)
310
+ */
311
+ UNIT_ID_NOMINAL_SOLAR_DIAMETER = 15009,
312
+ /*
313
+ Attosecond (as)
314
+ */
315
+ UNIT_ID_ATTOSECOND = 20000,
316
+ /*
317
+ Femtosecond (fs)
318
+ */
319
+ UNIT_ID_FEMTOSECOND = 20001,
320
+ /*
321
+ Picosecond (ps)
322
+ */
323
+ UNIT_ID_PICOSECOND = 20002,
324
+ /*
325
+ Nanosecond (ns)
326
+ */
327
+ UNIT_ID_NANOSECOND = 20003,
328
+ /*
329
+ Microsecond (µs)
330
+ */
331
+ UNIT_ID_MICROSECOND = 20004,
332
+ /*
333
+ Millisecond (ms)
334
+ */
335
+ UNIT_ID_MILLISECOND = 20005,
336
+ /*
337
+ Centisecond (cs)
338
+ */
339
+ UNIT_ID_CENTISECOND = 20006,
340
+ /*
341
+ Decisecond (ds)
342
+ */
343
+ UNIT_ID_DECISECOND = 20007,
344
+ /*
345
+ Second (s)
346
+ */
347
+ UNIT_ID_SECOND = 20008,
348
+ /*
349
+ Decasecond (das)
350
+ */
351
+ UNIT_ID_DECASECOND = 20009,
352
+ /*
353
+ Hectosecond (hs)
354
+ */
355
+ UNIT_ID_HECTOSECOND = 20010,
356
+ /*
357
+ Kilosecond (ks)
358
+ */
359
+ UNIT_ID_KILOSECOND = 20011,
360
+ /*
361
+ Megasecond (Ms)
362
+ */
363
+ UNIT_ID_MEGASECOND = 20012,
364
+ /*
365
+ Gigasecond (Gs)
366
+ */
367
+ UNIT_ID_GIGASECOND = 20013,
368
+ /*
369
+ Terasecond (Ts)
370
+ */
371
+ UNIT_ID_TERASECOND = 20014,
372
+ /*
373
+ Minute (min)
374
+ */
375
+ UNIT_ID_MINUTE = 21000,
376
+ /*
377
+ Hour (h)
378
+ */
379
+ UNIT_ID_HOUR = 21001,
380
+ /*
381
+ Day (d)
382
+ */
383
+ UNIT_ID_DAY = 21002,
384
+ /*
385
+ Week (wk)
386
+ */
387
+ UNIT_ID_WEEK = 21003,
388
+ /*
389
+ Fortnight (fn)
390
+ */
391
+ UNIT_ID_FORTNIGHT = 21004,
392
+ /*
393
+ Year (yr)
394
+ */
395
+ UNIT_ID_YEAR = 22000,
396
+ /*
397
+ Decade (dec)
398
+ */
399
+ UNIT_ID_DECADE = 22001,
400
+ /*
401
+ Century (c)
402
+ */
403
+ UNIT_ID_CENTURY = 22002,
404
+ /*
405
+ Millennium (mill)
406
+ */
407
+ UNIT_ID_MILLENNIUM = 22003,
408
+ /*
409
+ JulianYear (a)
410
+ */
411
+ UNIT_ID_JULIAN_YEAR = 22004,
412
+ /*
413
+ JulianCentury (jc)
414
+ */
415
+ UNIT_ID_JULIAN_CENTURY = 22005,
416
+ /*
417
+ SiderealDay (sd)
418
+ */
419
+ UNIT_ID_SIDEREAL_DAY = 23000,
420
+ /*
421
+ SynodicMonth (mo_s)
422
+ */
423
+ UNIT_ID_SYNODIC_MONTH = 23001,
424
+ /*
425
+ SiderealYear (yr_s)
426
+ */
427
+ UNIT_ID_SIDEREAL_YEAR = 23002,
428
+ /*
429
+ Milliradian (mrad)
430
+ */
431
+ UNIT_ID_MILLIRADIAN = 30000,
432
+ /*
433
+ Radian (rad)
434
+ */
435
+ UNIT_ID_RADIAN = 30001,
436
+ /*
437
+ MicroArcsecond (µas)
438
+ */
439
+ UNIT_ID_MICRO_ARCSECOND = 31000,
440
+ /*
441
+ MilliArcsecond (mas)
442
+ */
443
+ UNIT_ID_MILLI_ARCSECOND = 31001,
444
+ /*
445
+ Arcsecond (″)
446
+ */
447
+ UNIT_ID_ARCSECOND = 31002,
448
+ /*
449
+ Arcminute (′)
450
+ */
451
+ UNIT_ID_ARCMINUTE = 31003,
452
+ /*
453
+ Degree (°)
454
+ */
455
+ UNIT_ID_DEGREE = 31004,
456
+ /*
457
+ Gradian (gon)
458
+ */
459
+ UNIT_ID_GRADIAN = 32000,
460
+ /*
461
+ Turn (tr)
462
+ */
463
+ UNIT_ID_TURN = 32001,
464
+ /*
465
+ HourAngle (ʰ)
466
+ */
467
+ UNIT_ID_HOUR_ANGLE = 32002,
468
+ /*
469
+ Yoctogram (yg)
470
+ */
471
+ UNIT_ID_YOCTOGRAM = 40000,
472
+ /*
473
+ Zeptogram (zg)
474
+ */
475
+ UNIT_ID_ZEPTOGRAM = 40001,
476
+ /*
477
+ Attogram (ag)
478
+ */
479
+ UNIT_ID_ATTOGRAM = 40002,
480
+ /*
481
+ Femtogram (fg)
482
+ */
483
+ UNIT_ID_FEMTOGRAM = 40003,
484
+ /*
485
+ Picogram (pg)
486
+ */
487
+ UNIT_ID_PICOGRAM = 40004,
488
+ /*
489
+ Nanogram (ng)
490
+ */
491
+ UNIT_ID_NANOGRAM = 40005,
492
+ /*
493
+ Microgram (µg)
494
+ */
495
+ UNIT_ID_MICROGRAM = 40006,
496
+ /*
497
+ Milligram (mg)
498
+ */
499
+ UNIT_ID_MILLIGRAM = 40007,
500
+ /*
501
+ Centigram (cg)
502
+ */
503
+ UNIT_ID_CENTIGRAM = 40008,
504
+ /*
505
+ Decigram (dg)
506
+ */
507
+ UNIT_ID_DECIGRAM = 40009,
508
+ /*
509
+ Gram (g)
510
+ */
511
+ UNIT_ID_GRAM = 40010,
512
+ /*
513
+ Decagram (dag)
514
+ */
515
+ UNIT_ID_DECAGRAM = 40011,
516
+ /*
517
+ Hectogram (hg)
518
+ */
519
+ UNIT_ID_HECTOGRAM = 40012,
520
+ /*
521
+ Kilogram (kg)
522
+ */
523
+ UNIT_ID_KILOGRAM = 40013,
524
+ /*
525
+ Megagram (Mg)
526
+ */
527
+ UNIT_ID_MEGAGRAM = 40014,
528
+ /*
529
+ Gigagram (Gg)
530
+ */
531
+ UNIT_ID_GIGAGRAM = 40015,
532
+ /*
533
+ Teragram (Tg)
534
+ */
535
+ UNIT_ID_TERAGRAM = 40016,
536
+ /*
537
+ Petagram (Pg)
538
+ */
539
+ UNIT_ID_PETAGRAM = 40017,
540
+ /*
541
+ Exagram (Eg)
542
+ */
543
+ UNIT_ID_EXAGRAM = 40018,
544
+ /*
545
+ Zettagram (Zg)
546
+ */
547
+ UNIT_ID_ZETTAGRAM = 40019,
548
+ /*
549
+ Yottagram (Yg)
550
+ */
551
+ UNIT_ID_YOTTAGRAM = 40020,
552
+ /*
553
+ Grain (gr)
554
+ */
555
+ UNIT_ID_GRAIN = 41000,
556
+ /*
557
+ Ounce (oz)
558
+ */
559
+ UNIT_ID_OUNCE = 41001,
560
+ /*
561
+ Pound (lb)
562
+ */
563
+ UNIT_ID_POUND = 41002,
564
+ /*
565
+ Stone (st)
566
+ */
567
+ UNIT_ID_STONE = 41003,
568
+ /*
569
+ ShortTon (ton)
570
+ */
571
+ UNIT_ID_SHORT_TON = 41004,
572
+ /*
573
+ LongTon (ton_l)
574
+ */
575
+ UNIT_ID_LONG_TON = 41005,
576
+ /*
577
+ Carat (ct)
578
+ */
579
+ UNIT_ID_CARAT = 42000,
580
+ /*
581
+ Tonne (t)
582
+ */
583
+ UNIT_ID_TONNE = 42001,
584
+ /*
585
+ AtomicMassUnit (u)
586
+ */
587
+ UNIT_ID_ATOMIC_MASS_UNIT = 42002,
588
+ /*
589
+ SolarMass (M_☉)
590
+ */
591
+ UNIT_ID_SOLAR_MASS = 42003,
592
+ /*
593
+ Yoctowatt (yW)
594
+ */
595
+ UNIT_ID_YOCTOWATT = 50000,
596
+ /*
597
+ Zeptowatt (zW)
598
+ */
599
+ UNIT_ID_ZEPTOWATT = 50001,
600
+ /*
601
+ Attowatt (aW)
602
+ */
603
+ UNIT_ID_ATTOWATT = 50002,
604
+ /*
605
+ Femtowatt (fW)
606
+ */
607
+ UNIT_ID_FEMTOWATT = 50003,
608
+ /*
609
+ Picowatt (pW)
610
+ */
611
+ UNIT_ID_PICOWATT = 50004,
612
+ /*
613
+ Nanowatt (nW)
614
+ */
615
+ UNIT_ID_NANOWATT = 50005,
616
+ /*
617
+ Microwatt (µW)
618
+ */
619
+ UNIT_ID_MICROWATT = 50006,
620
+ /*
621
+ Milliwatt (mW)
622
+ */
623
+ UNIT_ID_MILLIWATT = 50007,
624
+ /*
625
+ Deciwatt (dW)
626
+ */
627
+ UNIT_ID_DECIWATT = 50008,
628
+ /*
629
+ Watt (W)
630
+ */
631
+ UNIT_ID_WATT = 50009,
632
+ /*
633
+ Decawatt (daW)
634
+ */
635
+ UNIT_ID_DECAWATT = 50010,
636
+ /*
637
+ Hectowatt (hW)
638
+ */
639
+ UNIT_ID_HECTOWATT = 50011,
640
+ /*
641
+ Kilowatt (kW)
642
+ */
643
+ UNIT_ID_KILOWATT = 50012,
644
+ /*
645
+ Megawatt (MW)
646
+ */
647
+ UNIT_ID_MEGAWATT = 50013,
648
+ /*
649
+ Gigawatt (GW)
650
+ */
651
+ UNIT_ID_GIGAWATT = 50014,
652
+ /*
653
+ Terawatt (TW)
654
+ */
655
+ UNIT_ID_TERAWATT = 50015,
656
+ /*
657
+ Petawatt (PW)
658
+ */
659
+ UNIT_ID_PETAWATT = 50016,
660
+ /*
661
+ Exawatt (EW)
662
+ */
663
+ UNIT_ID_EXAWATT = 50017,
664
+ /*
665
+ Zettawatt (ZW)
666
+ */
667
+ UNIT_ID_ZETTAWATT = 50018,
668
+ /*
669
+ Yottawatt (YW)
670
+ */
671
+ UNIT_ID_YOTTAWATT = 50019,
672
+ /*
673
+ ErgPerSecond (erg/s)
674
+ */
675
+ UNIT_ID_ERG_PER_SECOND = 51000,
676
+ /*
677
+ HorsepowerMetric (PS)
678
+ */
679
+ UNIT_ID_HORSEPOWER_METRIC = 51001,
680
+ /*
681
+ HorsepowerElectric (hp_e)
682
+ */
683
+ UNIT_ID_HORSEPOWER_ELECTRIC = 51002,
684
+ /*
685
+ SolarLuminosity (L_☉)
686
+ */
687
+ UNIT_ID_SOLAR_LUMINOSITY = 51003,
688
+ };
689
+ #ifndef __cplusplus
690
+ typedef uint32_t UnitId;
691
+ #endif // __cplusplus
692
+
693
+ /*
694
+ Dimension identifier for FFI.
695
+
696
+ Represents the physical dimension of a quantity. All discriminant values are
697
+ explicitly assigned and are part of the ABI contract.
698
+
699
+ # ABI Contract
700
+
701
+ **Discriminant values must never change.** New dimensions may be added with
702
+ new explicit discriminant values.
703
+ */
704
+ enum DimensionId
705
+ #ifdef __cplusplus
706
+ : uint32_t
707
+ #endif // __cplusplus
708
+ {
709
+ /*
710
+ Length dimension (e.g., meters, kilometers).
711
+ */
712
+ DIMENSION_ID_LENGTH = 1,
713
+ /*
714
+ Time dimension (e.g., seconds, hours).
715
+ */
716
+ DIMENSION_ID_TIME = 2,
717
+ /*
718
+ Angle dimension (e.g., radians, degrees).
719
+ */
720
+ DIMENSION_ID_ANGLE = 3,
721
+ /*
722
+ Mass dimension (e.g., grams, kilograms).
723
+ */
724
+ DIMENSION_ID_MASS = 4,
725
+ /*
726
+ Power dimension (e.g., watts, kilowatts).
727
+ */
728
+ DIMENSION_ID_POWER = 5,
729
+ };
730
+ #ifndef __cplusplus
731
+ typedef uint32_t DimensionId;
732
+ #endif // __cplusplus
733
+
734
+ /*
735
+ A POD quantity carrier type suitable for FFI.
736
+
737
+ This struct represents a physical quantity as a value paired with its unit.
738
+ It is `#[repr(C)]` to ensure a stable, predictable memory layout across
739
+ language boundaries.
740
+
741
+ # Memory Layout
742
+
743
+ - `value`: 8 bytes (f64)
744
+ - `unit`: 4 bytes (u32 via UnitId)
745
+ - Padding: 4 bytes (for alignment)
746
+ - Total: 16 bytes on most platforms
747
+
748
+ # Example
749
+
750
+ ```rust
751
+ use qtty_ffi::{QttyQuantity, UnitId};
752
+
753
+ let q = QttyQuantity {
754
+ value: 1000.0,
755
+ unit: UnitId::Meter,
756
+ };
757
+ ```
758
+ */
759
+ typedef struct qtty_quantity_t {
760
+ /*
761
+ The numeric value of the quantity.
762
+ */
763
+ double value;
764
+ /*
765
+ The unit identifier for this quantity.
766
+ */
767
+ UnitId unit;
768
+ } qtty_quantity_t;
769
+
770
+ /*
771
+ A derived quantity representing a compound unit (numerator/denominator).
772
+
773
+ This is useful for quantities like velocity (m/s), frequency (rad/s), etc.
774
+
775
+ # ABI Stability
776
+
777
+ This struct has `#[repr(C)]` layout:
778
+ - `value` at offset 0 (8 bytes)
779
+ - `numerator` at offset 8 (4 bytes)
780
+ - `denominator` at offset 12 (4 bytes)
781
+ - Total size: 16 bytes
782
+
783
+ # Example
784
+
785
+ ```rust
786
+ use qtty_ffi::{QttyDerivedQuantity, UnitId};
787
+
788
+ // Create a velocity: 100 m/s
789
+ let velocity = QttyDerivedQuantity::new(100.0, UnitId::Meter, UnitId::Second);
790
+ assert_eq!(velocity.value, 100.0);
791
+ assert_eq!(velocity.numerator, UnitId::Meter);
792
+ assert_eq!(velocity.denominator, UnitId::Second);
793
+ ```
794
+ */
795
+ typedef struct qtty_derived_quantity_t {
796
+ /*
797
+ The numeric value of the derived quantity.
798
+ */
799
+ double value;
800
+ /*
801
+ The numerator unit identifier.
802
+ */
803
+ UnitId numerator;
804
+ /*
805
+ The denominator unit identifier.
806
+ */
807
+ UnitId denominator;
808
+ } qtty_derived_quantity_t;
809
+
810
+ #ifdef __cplusplus
811
+ extern "C" {
812
+ #endif // __cplusplus
813
+
814
+ /*
815
+ Checks if a unit ID is valid (recognized by the registry).
816
+
817
+ # Arguments
818
+
819
+ * `unit` - The unit ID to validate
820
+
821
+ # Returns
822
+
823
+ `true` if the unit is valid, `false` otherwise.
824
+
825
+ # Safety
826
+
827
+ This function is safe to call from any context.
828
+ */
829
+ bool qtty_unit_is_valid(UnitId unit);
830
+
831
+ /*
832
+ Gets the dimension of a unit.
833
+
834
+ # Arguments
835
+
836
+ * `unit` - The unit ID to query
837
+ * `out` - Pointer to store the dimension ID
838
+
839
+ # Returns
840
+
841
+ * `QTTY_OK` on success
842
+ * `QTTY_ERR_NULL_OUT` if `out` is null
843
+ * `QTTY_ERR_UNKNOWN_UNIT` if the unit is not recognized
844
+
845
+ # Safety
846
+
847
+ The caller must ensure that `out` points to valid, writable memory for a `DimensionId`,
848
+ or is null (in which case an error is returned).
849
+ */
850
+ int32_t qtty_unit_dimension(UnitId unit, DimensionId *out);
851
+
852
+ /*
853
+ Checks if two units are compatible (same dimension).
854
+
855
+ # Arguments
856
+
857
+ * `a` - First unit ID
858
+ * `b` - Second unit ID
859
+ * `out` - Pointer to store the result
860
+
861
+ # Returns
862
+
863
+ * `QTTY_OK` on success
864
+ * `QTTY_ERR_NULL_OUT` if `out` is null
865
+ * `QTTY_ERR_UNKNOWN_UNIT` if either unit is not recognized
866
+
867
+ # Safety
868
+
869
+ The caller must ensure that `out` points to valid, writable memory for a `bool`,
870
+ or is null (in which case an error is returned).
871
+ */
872
+ int32_t qtty_units_compatible(UnitId a, UnitId b, bool *out);
873
+
874
+ /*
875
+ Creates a new quantity with the given value and unit.
876
+
877
+ # Arguments
878
+
879
+ * `value` - The numeric value
880
+ * `unit` - The unit ID
881
+ * `out` - Pointer to store the resulting quantity
882
+
883
+ # Returns
884
+
885
+ * `QTTY_OK` on success
886
+ * `QTTY_ERR_NULL_OUT` if `out` is null
887
+ * `QTTY_ERR_UNKNOWN_UNIT` if the unit is not recognized
888
+
889
+ # Safety
890
+
891
+ The caller must ensure that `out` points to valid, writable memory for a `QttyQuantity`,
892
+ or is null (in which case an error is returned).
893
+ */
894
+ int32_t qtty_quantity_make(double value, UnitId unit, struct qtty_quantity_t *out);
895
+
896
+ /*
897
+ Converts a quantity to a different unit.
898
+
899
+ # Arguments
900
+
901
+ * `src` - The source quantity
902
+ * `dst_unit` - The target unit ID
903
+ * `out` - Pointer to store the converted quantity
904
+
905
+ # Returns
906
+
907
+ * `QTTY_OK` on success
908
+ * `QTTY_ERR_NULL_OUT` if `out` is null
909
+ * `QTTY_ERR_UNKNOWN_UNIT` if either unit is not recognized
910
+ * `QTTY_ERR_INCOMPATIBLE_DIM` if units have different dimensions
911
+
912
+ # Safety
913
+
914
+ The caller must ensure that `out` points to valid, writable memory for a `QttyQuantity`,
915
+ or is null (in which case an error is returned).
916
+ */
917
+ int32_t qtty_quantity_convert(struct qtty_quantity_t src,
918
+ UnitId dst_unit,
919
+ struct qtty_quantity_t *out);
920
+
921
+ /*
922
+ Converts a value from one unit to another.
923
+
924
+ This is a convenience function that operates on raw values instead of `QttyQuantity` structs.
925
+
926
+ # Arguments
927
+
928
+ * `value` - The numeric value to convert
929
+ * `src_unit` - The source unit ID
930
+ * `dst_unit` - The target unit ID
931
+ * `out_value` - Pointer to store the converted value
932
+
933
+ # Returns
934
+
935
+ * `QTTY_OK` on success
936
+ * `QTTY_ERR_NULL_OUT` if `out_value` is null
937
+ * `QTTY_ERR_UNKNOWN_UNIT` if either unit is not recognized
938
+ * `QTTY_ERR_INCOMPATIBLE_DIM` if units have different dimensions
939
+
940
+ # Safety
941
+
942
+ The caller must ensure that `out_value` points to valid, writable memory for an `f64`,
943
+ or is null (in which case an error is returned).
944
+ */
945
+ int32_t qtty_quantity_convert_value(double value,
946
+ UnitId src_unit,
947
+ UnitId dst_unit,
948
+ double *out_value);
949
+
950
+ /*
951
+ Gets the name of a unit as a NUL-terminated C string.
952
+
953
+ # Arguments
954
+
955
+ * `unit` - The unit ID to query
956
+
957
+ # Returns
958
+
959
+ A pointer to a static, NUL-terminated C string with the unit name,
960
+ or a null pointer if the unit is not recognized.
961
+
962
+ # Safety
963
+
964
+ The returned pointer points to static memory and is valid for the lifetime
965
+ of the program. The caller must not attempt to free or modify the returned string.
966
+ */
967
+ const char *qtty_unit_name(UnitId unit);
968
+
969
+ /*
970
+ Formats a quantity as a human-readable string into a caller-provided buffer.
971
+
972
+ Produces a string like `"1234.57 m"`, `"1.23e3 km"`, or `"1.23E3 km"` depending
973
+ on the `flags` parameter. The precision and format type mirror Rust's `{:.2}`,
974
+ `{:.4e}`, and `{:.4E}` format annotations, allowing callers to pass the same
975
+ format parameters that the Rust `Display`, `LowerExp`, and `UpperExp` trait impls
976
+ use internally.
977
+
978
+ # Arguments
979
+
980
+ * `qty` - The quantity (`value + unit`) to format.
981
+ * `precision` - Number of decimal digits after the point. Pass `-1` for the
982
+ default precision (shortest exact representation for floats).
983
+ * `flags` - Selects the notation:
984
+ - `QTTY_FMT_DEFAULT` (0): decimal notation, e.g. `"1234.568 m"`
985
+ - `QTTY_FMT_LOWER_EXP` (1): scientific with lowercase `e`, e.g. `"1.235e3 m"`
986
+ - `QTTY_FMT_UPPER_EXP` (2): scientific with uppercase `E`, e.g. `"1.235E3 m"`
987
+ * `buf` - Caller-allocated output buffer (must be non-null).
988
+ * `buf_len` - Size of `buf` in bytes (must include space for the NUL terminator).
989
+
990
+ # Returns
991
+
992
+ * Non-negative: number of bytes written, **excluding** the NUL terminator.
993
+ * `QTTY_ERR_NULL_OUT` if `buf` is null.
994
+ * `QTTY_ERR_UNKNOWN_UNIT` if `qty.unit` is not a recognized unit ID.
995
+ * `QTTY_ERR_BUFFER_TOO_SMALL` if `buf_len` is too small; the formatted string
996
+ (including the NUL terminator) requires `-return_value` bytes.
997
+
998
+ # Safety
999
+
1000
+ The caller must ensure that `buf` points to a writable allocation of at least
1001
+ `buf_len` bytes. The written string is always NUL-terminated on success.
1002
+ */
1003
+ int32_t qtty_quantity_format(struct qtty_quantity_t qty,
1004
+ int32_t precision,
1005
+ uint32_t flags,
1006
+ char *buf,
1007
+ size_t buf_len);
1008
+
1009
+ /*
1010
+ Frees a string previously allocated by one of the `qtty_*_to_json*` functions.
1011
+
1012
+ # Safety
1013
+
1014
+ The pointer must have been returned by a `qtty_*_to_json*` function and must
1015
+ not have been freed previously. Passing a null pointer is safe (no-op).
1016
+ */
1017
+ void qtty_string_free(char *s);
1018
+
1019
+ /*
1020
+ Serializes a quantity's value as a plain JSON number string (e.g. "123.45").
1021
+
1022
+ # Safety
1023
+
1024
+ The caller must ensure that `out` points to valid, writable memory for a `*mut c_char`,
1025
+ or is null (in which case an error is returned). The returned string must be freed
1026
+ with [`qtty_string_free`].
1027
+ */
1028
+ int32_t qtty_quantity_to_json_value(struct qtty_quantity_t src, char **out);
1029
+
1030
+ /*
1031
+ Deserializes a quantity from a plain JSON numeric string with an explicit unit.
1032
+
1033
+ # Safety
1034
+
1035
+ The caller must ensure that `json` points to a valid NUL-terminated C string,
1036
+ and `out` points to valid, writable memory for a `QttyQuantity`.
1037
+ */
1038
+ int32_t qtty_quantity_from_json_value(UnitId unit, const char *json, struct qtty_quantity_t *out);
1039
+
1040
+ /*
1041
+ Serializes a quantity to a full JSON object: `{"value":123.45,"unit":"Meter"}`.
1042
+
1043
+ # Safety
1044
+
1045
+ The caller must ensure that `out` points to valid, writable memory for a `*mut c_char`,
1046
+ or is null (in which case an error is returned). The returned string must be freed
1047
+ with [`qtty_string_free`].
1048
+ */
1049
+ int32_t qtty_quantity_to_json(struct qtty_quantity_t src, char **out);
1050
+
1051
+ /*
1052
+ Deserializes a quantity from a JSON object: `{"value":123.45,"unit":"Meter"}`.
1053
+
1054
+ # Safety
1055
+
1056
+ The caller must ensure that `json` points to a valid NUL-terminated C string,
1057
+ and `out` points to valid, writable memory for a `QttyQuantity`.
1058
+ */
1059
+ int32_t qtty_quantity_from_json(const char *json, struct qtty_quantity_t *out);
1060
+
1061
+ /*
1062
+ Creates a new derived quantity (compound unit like m/s).
1063
+
1064
+ # Safety
1065
+
1066
+ The caller must ensure that `out` points to valid, writable memory for a
1067
+ `QttyDerivedQuantity`, or is null (in which case an error is returned).
1068
+ */
1069
+ int32_t qtty_derived_make(double value,
1070
+ UnitId numerator,
1071
+ UnitId denominator,
1072
+ struct qtty_derived_quantity_t *out);
1073
+
1074
+ /*
1075
+ Converts a derived quantity to different units.
1076
+
1077
+ The numerator and denominator are converted independently while preserving
1078
+ the compound value. For example, 100 m/s → 360 km/h.
1079
+
1080
+ # Safety
1081
+
1082
+ The caller must ensure that `out` points to valid, writable memory for a
1083
+ `QttyDerivedQuantity`, or is null (in which case an error is returned).
1084
+ */
1085
+ int32_t qtty_derived_convert(struct qtty_derived_quantity_t src,
1086
+ UnitId target_num,
1087
+ UnitId target_den,
1088
+ struct qtty_derived_quantity_t *out);
1089
+
1090
+ /*
1091
+ Serializes a derived quantity to a JSON object.
1092
+
1093
+ # Safety
1094
+
1095
+ The caller must ensure that `out` points to valid, writable memory for a `*mut c_char`.
1096
+ The returned string must be freed with [`qtty_string_free`].
1097
+ */
1098
+ int32_t qtty_derived_to_json(struct qtty_derived_quantity_t src, char **out);
1099
+
1100
+ /*
1101
+ Deserializes a derived quantity from a JSON object.
1102
+
1103
+ # Safety
1104
+
1105
+ The caller must ensure that `json` points to a valid NUL-terminated C string,
1106
+ and `out` points to valid, writable memory for a `QttyDerivedQuantity`.
1107
+ */
1108
+ int32_t qtty_derived_from_json(const char *json, struct qtty_derived_quantity_t *out);
1109
+
1110
+ /*
1111
+ Returns the FFI ABI version.
1112
+
1113
+ This can be used by consumers to verify compatibility. The version is
1114
+ incremented when breaking changes are made to the ABI.
1115
+
1116
+ Current version: 1
1117
+ */
1118
+ uint32_t qtty_ffi_version(void);
1119
+
1120
+ #ifdef __cplusplus
1121
+ } // extern "C"
1122
+ #endif // __cplusplus
1123
+
1124
+ #endif /* QTTY_FFI_H */
1125
+
1126
+ /* End of qtty_ffi.h */