You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/architecture.md
+60-2Lines changed: 60 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,10 @@
1
1
# Architecture Guide
2
2
3
-
This document provides a detailed overview of the Semantics library architecture, focusing on the SOLID principles and DRY practices implemented throughout the codebase.
3
+
This document covers the architecture of the **semantic strings, paths, and validation** subsystems. The physics quantities subsystem is metadata-driven and is documented separately:
4
+
5
+
-[`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md) — the unified `IVector0..IVector4` model.
6
+
-[`docs/physics-generator.md`](physics-generator.md) — `dimensions.json` schema and the source-generator pipeline.
7
+
- The [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation) section below provides a short orientation and links into those documents.
4
8
5
9
## Table of Contents
6
10
@@ -10,11 +14,12 @@ This document provides a detailed overview of the Semantics library architecture
The Semantics library is designed around clean architecture principles, with a focus on maintainability, extensibility, and testability. The core philosophy is to provide type-safe string wrappers while maintaining excellent separation of concerns and avoiding code duplication.
22
+
The Semantics library is built around three pillars — **semantic strings**, **semantic paths**, and **physics quantities** — sharing a single philosophy: replace primitive obsession with strongly-typed, self-validating domain models. Strings and paths use a hand-authored attribute → strategy → rule → factory pipeline (described in this document). Physics quantities are emitted at compile time by a Roslyn incremental generator from declarative metadata (described in [Physics Quantities: Metadata-Driven Generation](#physics-quantities-metadata-driven-generation)). All three subsystems target `net10.0`, `net9.0`, `net8.0`, `net7.0`.
18
23
19
24
## SOLID Principles Implementation
20
25
@@ -271,6 +276,59 @@ User Creates Semantic String
271
276
Return Valid Object or Throw Exception
272
277
```
273
278
279
+
## Physics Quantities: Metadata-Driven Generation
280
+
281
+
Unlike strings and paths — which are hand-authored — every physics quantity type, factory, operator, and constant is emitted by a Roslyn incremental generator. The single source of truth is `Semantics.SourceGenerators/Metadata/`:
282
+
283
+
| File | Contents |
284
+
|---|---|
285
+
|`dimensions.json`| Every physical dimension, the vector forms it supports (`Vector0`..`Vector4`), its `availableUnits`, semantic overloads (e.g. `Weight` over `ForceMagnitude`), and cross-dimensional relationships (`integrals`, `derivatives`, `dotProducts`, `crossProducts`). |
286
+
|`units.json`| Unit declarations with `factoryName` (plural) and a base-unit conversion expression. |
287
+
|`magnitudes.json`| SI magnitude prefixes for unit derivations. |
288
+
|`conversions.json`| Conversion factors between non-SI units and the SI base. |
289
+
|`domains.json`| Domain grouping for `PhysicalConstants` (e.g. `Fundamental`, `Chemistry`, `AngularMechanics`). |
└── StorageHelpersGenerator → DivideToStorage with DivideByZeroException
307
+
│
308
+
▼
309
+
Semantics.Quantities/Generated/ (committed source — diff before commit)
310
+
```
311
+
312
+
### Vector-form invariants
313
+
314
+
These are enforced structurally by the generated types and locked in by `Semantics.Test`:
315
+
316
+
1.`V0` magnitudes are non-negative; the SI factory throws `ArgumentException` on a negative value, and `V0 - V0` returns `T.Abs(a - b)` to preserve the invariant.
317
+
2. A V0 overload can opt into a strict-positive guard with `physicalConstraints: { "minExclusive": "0" }` (used by `Wavelength`, `Period`, `HalfLife`); `EnsurePositive` then rejects zero as well.
318
+
3. Semantic overloads widen implicitly to their base, narrow explicitly (`Weight.From(forceMagnitude)`).
319
+
4.`IVectorN.Magnitude()` for N ≥ 1 returns the corresponding `IVector0`.
320
+
321
+
### Generator diagnostics
322
+
323
+
Metadata errors fail the build rather than silently emitting wrong code:
324
+
325
+
-**SEM001** — a relationship references a dimension that does not exist.
326
+
-**SEM002** — schema-level metadata issue (missing `name` / `symbol`, empty `availableUnits`, duplicate type names, no vector forms declared).
327
+
-**SEM003** — a relationship's explicit `forms` list references a vector form not declared on a participating dimension.
328
+
-**SEM004** — a dimension's `availableUnits` array references a unit name that isn't declared in `units.json` (catches typos that would otherwise produce a wrong identity-conversion factory).
329
+
330
+
For the schema, an end-to-end "add a dimension" walk-through, and the design rationale, see [`docs/physics-generator.md`](physics-generator.md) and [`docs/strategy-unified-vector-quantities.md`](strategy-unified-vector-quantities.md).
0 commit comments