Skip to content

Commit 63d0e26

Browse files
authored
Merge pull request #280 from MikeFalcon77/refactor/rust_2024_edition
chore(Rust): migrate to 2024 edition
2 parents 9bc8362 + 04a7c00 commit 63d0e26

188 files changed

Lines changed: 1326 additions & 1069 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ We welcome contributions in:
1616

1717
### 1.1 Prerequisites
1818

19-
- **Rust stable** with Cargo (Edition 2021)
19+
- **Rust stable** with Cargo (Edition 2024)
2020
- **Git** for version control
2121
- **Your favorite editor** (VS Code with rust-analyzer recommended)
2222

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace.package]
22
version = "0.1.0"
3-
edition = "2021"
3+
edition = "2024"
44
license = "Apache-2.0"
55
authors = ["Hypernetix"]
66
repository = "https://github.com/hypernetix/hyperspot"

apps/hyperspot-server/src/main.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ use anyhow::Result;
44
use clap::{Parser, Subcommand};
55
use figment::Figment;
66
use mimalloc::MiMalloc;
7+
use modkit::LocalProcessBackend;
78
use modkit::bootstrap::config::{
8-
get_module_runtime_config, render_module_config_for_oop, AppConfig, RuntimeKind,
9+
AppConfig, RuntimeKind, get_module_runtime_config, render_module_config_for_oop,
910
};
1011
use modkit::bootstrap::host::{init_logging_unified, normalize_executable_path};
11-
use modkit::LocalProcessBackend;
1212
use tokio_util::sync::CancellationToken;
1313

1414
use std::path::{Path, PathBuf};
@@ -23,7 +23,7 @@ static GLOBAL: MiMalloc = MiMalloc;
2323

2424
// Bring runner types & our per-module DB factory
2525
use modkit::runtime::{
26-
run, shutdown, DbOptions, OopModuleSpawnConfig, OopSpawnOptions, RunOptions, ShutdownOptions,
26+
DbOptions, OopModuleSpawnConfig, OopSpawnOptions, RunOptions, ShutdownOptions, run, shutdown,
2727
};
2828

2929
fn ensure_drivers_linked() {
@@ -115,10 +115,10 @@ async fn main() -> Result<()> {
115115

116116
// One-time connectivity probe
117117
#[cfg(feature = "otel")]
118-
if let Some(tc) = modkit_tracing_config.as_ref() {
119-
if let Err(e) = modkit::telemetry::init::otel_connectivity_probe(tc) {
120-
tracing::error!(error = %e, "OTLP connectivity probe failed");
121-
}
118+
if let Some(tc) = modkit_tracing_config.as_ref()
119+
&& let Err(e) = modkit::telemetry::init::otel_connectivity_probe(tc)
120+
{
121+
tracing::error!(error = %e, "OTLP connectivity probe failed");
122122
}
123123

124124
// Smoke test span to confirm traces flow to Jaeger
@@ -285,41 +285,41 @@ fn build_oop_spawn_options(
285285
let mut modules = Vec::new();
286286

287287
for module_name in config.modules.keys() {
288-
if let Some(runtime_cfg) = get_module_runtime_config(config, module_name)? {
289-
if runtime_cfg.mod_type == RuntimeKind::Oop {
290-
let exec_cfg = runtime_cfg.execution.as_ref().ok_or_else(|| {
291-
anyhow::anyhow!(
292-
"module '{module_name}' is type=oop but execution config is missing"
293-
)
294-
})?;
295-
296-
let binary = normalize_executable_path(&exec_cfg.executable_path)?;
297-
298-
// Copy args from execution config as-is
299-
// User controls --config via execution.args in master config
300-
let spawn_args = exec_cfg.args.clone();
301-
302-
// Copy environment from execution config
303-
let env = exec_cfg.environment.clone();
304-
305-
// Render the complete module config (with resolved DB)
306-
let rendered_config = render_module_config_for_oop(config, module_name, &home_dir)?;
307-
let rendered_json = rendered_config.to_json()?;
308-
tracing::debug!(
309-
module = %module_name,
310-
"Prepared OoP module config: db={}",
311-
rendered_config.database.is_some()
312-
);
288+
if let Some(runtime_cfg) = get_module_runtime_config(config, module_name)?
289+
&& runtime_cfg.mod_type == RuntimeKind::Oop
290+
{
291+
let exec_cfg = runtime_cfg.execution.as_ref().ok_or_else(|| {
292+
anyhow::anyhow!(
293+
"module '{module_name}' is type=oop but execution config is missing"
294+
)
295+
})?;
296+
297+
let binary = normalize_executable_path(&exec_cfg.executable_path)?;
298+
299+
// Copy args from execution config as-is
300+
// User controls --config via execution.args in master config
301+
let spawn_args = exec_cfg.args.clone();
302+
303+
// Copy environment from execution config
304+
let env = exec_cfg.environment.clone();
305+
306+
// Render the complete module config (with resolved DB)
307+
let rendered_config = render_module_config_for_oop(config, module_name, &home_dir)?;
308+
let rendered_json = rendered_config.to_json()?;
309+
tracing::debug!(
310+
module = %module_name,
311+
"Prepared OoP module config: db={}",
312+
rendered_config.database.is_some()
313+
);
313314

314-
modules.push(OopModuleSpawnConfig {
315-
module_name: module_name.clone(),
316-
binary,
317-
args: spawn_args,
318-
env,
319-
working_directory: exec_cfg.working_directory.clone(),
320-
rendered_config_json: rendered_json,
321-
});
322-
}
315+
modules.push(OopModuleSpawnConfig {
316+
module_name: module_name.clone(),
317+
binary,
318+
args: spawn_args,
319+
env,
320+
working_directory: exec_cfg.working_directory.clone(),
321+
rendered_config_json: rendered_json,
322+
});
323323
}
324324
}
325325

docs/ODATA_MACRO_MIGRATION.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
# OData Macro Consolidation Migration Guide
2+
3+
## Overview
4+
5+
All OData-related procedural macros have been consolidated into a single crate: **`modkit-odata-macros`**.
6+
7+
## What Changed
8+
9+
### Before
10+
- `ODataSchema` was in `modkit-sdk-macros`
11+
- `ODataFilterable` was in `modkit-db-macros`
12+
- Confusion about which crate owns OData contract generation
13+
- Database crate (`modkit-db-macros`) contained protocol-level macros
14+
15+
### After
16+
- **All** OData macros are now in `modkit-odata-macros`
17+
- `ODataSchema` - Client-side query builder schema generation
18+
- `ODataFilterable` - Server-side filter field enum generation
19+
- Clear separation: Protocol macros in `modkit-odata-macros`, DB macros in `modkit-db-macros`
20+
- `modkit-sdk-macros` **removed** (no longer needed)
21+
- `modkit-db-macros` now contains only `Scopable` (SeaORM security)
22+
23+
## Architecture
24+
25+
```
26+
modkit-odata-macros/
27+
├── ODataSchema → Generates Schema trait for client query building
28+
└── ODataFilterable → Generates FilterField enum for server filtering
29+
30+
modkit-sdk-macros/ [REMOVED]
31+
modkit-db-macros/
32+
└── Scopable → SeaORM security scoping (non-OData)
33+
```
34+
35+
## Migration Steps
36+
37+
### For Server-Side Code (API/Service/Infra)
38+
39+
**Old:**
40+
```toml
41+
# Cargo.toml
42+
[dependencies]
43+
modkit-db-macros = { path = "../modkit-db-macros" }
44+
```
45+
46+
```rust
47+
// src/query/mod.rs
48+
use modkit_db_macros::ODataFilterable;
49+
50+
#[derive(ODataFilterable)]
51+
pub struct UserQuery {
52+
#[odata(filter(kind = "Uuid"))]
53+
pub id: Uuid,
54+
}
55+
```
56+
57+
**New:**
58+
```toml
59+
# Cargo.toml
60+
[dependencies]
61+
modkit-db-macros = { path = "../modkit-db-macros" } # Still needed for Scopable
62+
modkit-odata-macros = { path = "../modkit-odata-macros" } # NEW: For ODataFilterable
63+
```
64+
65+
```rust
66+
// src/query/mod.rs
67+
use modkit_odata_macros::ODataFilterable; // Changed import
68+
69+
#[derive(ODataFilterable)]
70+
pub struct UserQuery {
71+
#[odata(filter(kind = "Uuid"))]
72+
pub id: Uuid,
73+
}
74+
```
75+
76+
### For Client-Side Code (SDK)
77+
78+
**Old:**
79+
```toml
80+
# Cargo.toml
81+
[dependencies]
82+
modkit-sdk = { path = "../modkit-sdk", features = ["derive"] }
83+
```
84+
85+
```rust
86+
use modkit_sdk::ODataSchema; // Re-exported from modkit-sdk
87+
88+
#[derive(ODataSchema)]
89+
struct User {
90+
id: uuid::Uuid,
91+
email: String,
92+
}
93+
```
94+
95+
**New:**
96+
```toml
97+
# Cargo.toml
98+
[dependencies]
99+
modkit-sdk = { path = "../modkit-sdk", features = ["derive"] }
100+
# modkit-sdk now re-exports from modkit-odata-macros internally
101+
```
102+
103+
```rust
104+
use modkit_sdk::ODataSchema; // Still works! Now re-exports from modkit-odata-macros
105+
106+
#[derive(ODataSchema)]
107+
struct User {
108+
id: uuid::Uuid,
109+
email: String,
110+
}
111+
```
112+
113+
**OR** use directly:
114+
```rust
115+
use modkit_odata_macros::ODataSchema; // Direct import also works
116+
117+
#[derive(ODataSchema)]
118+
struct User {
119+
id: uuid::Uuid,
120+
email: String,
121+
}
122+
```
123+
124+
## Breaking Changes
125+
126+
### 1. `modkit-sdk-macros` is now empty
127+
128+
**Impact:** If you imported directly from `modkit-sdk-macros`, you **must** update.
129+
130+
```rust
131+
// ❌ OLD - Will not compile
132+
use modkit_sdk_macros::ODataSchema;
133+
134+
// ✅ NEW - Use modkit-odata-macros
135+
use modkit_odata_macros::ODataSchema;
136+
137+
// ✅ OR - Use modkit-sdk re-export
138+
use modkit_sdk::ODataSchema;
139+
```
140+
141+
### 2. `ODataFilterable` moved out of `modkit-db-macros`
142+
143+
**Impact:** Must add `modkit-odata-macros` dependency and update imports.
144+
145+
```rust
146+
// ❌ OLD - Will not compile
147+
use modkit_db_macros::ODataFilterable;
148+
149+
// ✅ NEW
150+
use modkit_odata_macros::ODataFilterable;
151+
```
152+
153+
## Rationale
154+
155+
### Problem
156+
1. **Layering violation**: `modkit-db-macros` contained protocol-level macros, not DB-specific
157+
2. **Confusion**: OData macros scattered across `modkit-db-macros` and `modkit-sdk-macros`
158+
3. **Wrong dependencies**: After moving filter DSL to `modkit-odata`, macros in `modkit-db-macros` referenced `modkit-odata` types, creating circular conceptual dependencies
159+
160+
### Solution
161+
1. **Single source of truth**: All OData protocol macros in `modkit-odata-macros`
162+
2. **Clear naming**: "odata-macros" explicitly indicates OData protocol
163+
3. **Correct layering**: DB macros (`Scopable`) stay in `modkit-db-macros`, OData macros move to `modkit-odata-macros`
164+
4. **No DB pollution**: OData macros don't pull in SeaORM or database dependencies
165+
166+
## Verification
167+
168+
After migration, verify with:
169+
```bash
170+
cargo check -p modkit-odata-macros
171+
cargo check -p modkit-sdk
172+
cargo check -p modkit-db-macros
173+
cargo check -p your-service
174+
```
175+
176+
## FAQ
177+
178+
**Q: Do I need to change my derive attributes?**
179+
A: No, `#[derive(ODataFilterable)]` and `#[derive(ODataSchema)]` work exactly the same way.
180+
181+
**Q: Can I still use `modkit-sdk::ODataSchema`?**
182+
A: Yes! `modkit-sdk` now re-exports from `modkit-odata-macros`, so existing code continues to work.
183+
184+
**Q: What happened to `modkit-sdk-macros`?**
185+
A: It has been completely removed. All OData macros are now in `modkit-odata-macros`.
186+
187+
**Q: Does this affect runtime behavior?**
188+
A: No, this is purely a compile-time/packaging change. Generated code is identical.
189+
190+
**Q: Do tests need to change?**
191+
A: Only test imports. Test assertions and behavior remain unchanged.
192+
193+
## Checklist
194+
195+
- [ ] Update `Cargo.toml` to add `modkit-odata-macros` dependency
196+
- [ ] Change `use modkit_db_macros::ODataFilterable` to `use modkit_odata_macros::ODataFilterable`
197+
- [ ] Change `use modkit_sdk_macros::*` to `use modkit_odata_macros::*` (if importing directly)
198+
- [ ] Run `cargo check` to verify compilation
199+
- [ ] Run tests to verify functionality
200+
- [ ] Update any documentation references
201+
202+
## References
203+
204+
- Filter DSL migration: See earlier migration that moved filter types from `modkit-db` to `modkit-odata`
205+
- Macro crate source: `libs/modkit-odata-macros/`
206+
- Generated code inspection: `cargo expand --package your-crate`

dylint_lints/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ resolver = "2"
1818

1919
[workspace.package]
2020
version = "0.1.0"
21-
edition = "2021"
21+
edition = "2024"
2222
license = "Apache-2.0"
2323
authors = ["Hypernetix"]
2424

dylint_lints/de01_contract_layer/de0101_no_serde_in_contract/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "de0101_no_serde_in_contract"
33
version = "0.1.0"
44
authors = ["authors go here"]
55
description = "description goes here"
6-
edition = "2024"
6+
edition.workspace = true
77
publish = false
88

99
[lib]

dylint_lints/de01_contract_layer/de0102_no_toschema_in_contract/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "de0102_no_toschema_in_contract"
33
version = "0.1.0"
44
authors = ["authors go here"]
55
description = "Contract models should not have ToSchema derive (DE0102)"
6-
edition = "2024"
6+
edition.workspace = true
77
publish = false
88

99
[lib]

dylint_lints/de01_contract_layer/de0103_no_http_types_in_contract/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "de0103_no_http_types_in_contract"
33
version = "0.1.0"
44
authors = ["authors go here"]
55
description = "Contract modules should not reference HTTP types (DE0103)"
6-
edition = "2024"
6+
edition.workspace = true
77
publish = false
88

99
[lib]

dylint_lints/de01_contract_layer/de0110_no_schema_for_on_gts_structs/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "de0110_no_schema_for_on_gts_structs"
33
version = "0.1.0"
44
authors = ["Hypernetix"]
55
description = "Prohibit using schemars::schema_for!() on GTS-wrapped structs"
6-
edition = "2024"
6+
edition.workspace = true
77
publish = false
88

99
[lib]

0 commit comments

Comments
 (0)