Skip to content

Commit 96853f7

Browse files
committed
Add branch-protection doc; update API, code & docs
Add .github/BRANCH_PROTECTION.md with UI and API instructions for protecting main and requiring Public API checks. Update CHANGELOG and CONTRACT to document facade-first CORE stabilization, public API governance (snapshots/CI), feature taxonomy and deprecation/migration timeline. Silence unused-symbol warnings by adding #[allow(dead_code)] to several rustapi-core helpers and path validation types/functions, and conditionally gate sqlx-related imports in rustapi-extras with feature cfgs. Refresh docs and examples to the new feature naming scheme (extras-*, protocol-*, core-*) and update performance wording to reflect the renamed simd-json feature.
1 parent 6ea5c73 commit 96853f7

12 files changed

Lines changed: 120 additions & 17 deletions

File tree

.github/BRANCH_PROTECTION.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Branch Protection Setup
2+
3+
Configure branch protection for `main` so public API checks are required.
4+
5+
## Required Status Checks
6+
7+
Add these checks as required:
8+
9+
- `Public API / Snapshot Drift`
10+
- `Public API / Label Gate`
11+
12+
## GitHub UI Path
13+
14+
1. Repository `Settings`
15+
2. `Branches`
16+
3. Edit rule for `main`
17+
4. Enable `Require status checks to pass before merging`
18+
5. Add the two checks above
19+
20+
## API Automation (optional)
21+
22+
Use a fine-grained token with `Administration: Read and write` for the repository.
23+
24+
```powershell
25+
$owner = "Tuntii"
26+
$repo = "RustAPI"
27+
$token = $env:GITHUB_TOKEN
28+
29+
$body = @{
30+
required_status_checks = @{
31+
strict = $true
32+
contexts = @(
33+
"Public API / Snapshot Drift",
34+
"Public API / Label Gate"
35+
)
36+
}
37+
enforce_admins = $true
38+
required_pull_request_reviews = @{
39+
required_approving_review_count = 1
40+
}
41+
restrictions = $null
42+
} | ConvertTo-Json -Depth 10
43+
44+
Invoke-RestMethod `
45+
-Method Put `
46+
-Uri "https://api.github.com/repos/$owner/$repo/branches/main/protection" `
47+
-Headers @{
48+
Authorization = "Bearer $token"
49+
Accept = "application/vnd.github+json"
50+
"X-GitHub-Api-Version" = "2022-11-28"
51+
} `
52+
-Body $body `
53+
-ContentType "application/json"
54+
```

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
- **Facade-first CORE stabilization**:
12+
- `rustapi-rs` public surface is now explicitly curated (`core`, `protocol`, `extras`, `prelude`).
13+
- Internal wiring moved behind `rustapi_rs::__private` for macro/runtime integration.
14+
- `rustapi-core` internal modules tightened (`pub(crate)`/private where applicable).
15+
- `Handler` trait sealed to prevent external implementation leakage.
16+
- **Feature taxonomy refresh**:
17+
- Canonical naming is now `core-*`, `protocol-*`, `extras-*`.
18+
- Meta features standardized: `core`, `protocol-all`, `extras-all`, `full`.
19+
- Legacy feature names remain as compatibility aliases and are deprecated.
20+
21+
### Added
22+
- **Public API governance**:
23+
- Snapshot files under `api/public/` for `rustapi-rs` (default + all-features).
24+
- New CI workflow `.github/workflows/public-api.yml`:
25+
- snapshot drift check
26+
- PR label gate requiring `breaking` or `feature` when snapshot changes.
27+
- **Compatibility contract**:
28+
- New `CONTRACT.md` defining SemVer, MSRV (1.78), deprecation and feature policies.
29+
30+
### Deprecated
31+
- Legacy facade paths and feature aliases are soft-deprecated and scheduled for removal no earlier than two minor releases after announcement.
32+
1033
## [0.1.300] - 2026-02-06
1134

1235
### Added

CONTRACT.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ Do not depend on internal crate APIs for long-term compatibility.
4141
- explicit migration path in docs/release notes
4242
- Minimum deprecation window before removal: 2 minor releases.
4343
- Removals occur only in major releases.
44+
- Current compatibility window for legacy aliases introduced in this cycle:
45+
- First eligible removal: `v0.3.0` (assuming deprecation introduced in `v0.1.x`).
4446

4547
## 5. Feature Flag Policy
4648

@@ -54,6 +56,10 @@ Do not depend on internal crate APIs for long-term compatibility.
5456
- `extras-all`
5557
- `full`
5658
- Legacy aliases may exist temporarily for migration but must be treated as deprecated and eventually removed on a published timeline.
59+
- Published timeline for this migration set:
60+
- `v0.1.x`: aliases available, deprecation warnings/documentation.
61+
- `v0.2.x`: aliases still available, migration reminders.
62+
- `v0.3.0+`: aliases may be removed.
5763

5864
## 6. Internal Leakage Rule
5965

crates/rustapi-core/src/auto_route.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub fn collect_auto_routes() -> Vec<Route> {
6767
/// Get the count of auto-registered routes without collecting them.
6868
///
6969
/// Useful for debugging and logging.
70+
#[allow(dead_code)]
7071
pub fn auto_route_count() -> usize {
7172
AUTO_ROUTES.len()
7273
}

crates/rustapi-core/src/auto_schema.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub fn apply_auto_schemas(spec: &mut rustapi_openapi::OpenApiSpec) {
2121
}
2222

2323
/// Get the count of auto-registered schema registration functions.
24+
#[allow(dead_code)]
2425
pub fn auto_schema_count() -> usize {
2526
AUTO_SCHEMAS.len()
2627
}

crates/rustapi-core/src/json.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub fn from_slice<T: DeserializeOwned>(slice: &[u8]) -> Result<T, JsonError> {
4949
/// This variant allows simd-json to parse in-place without copying,
5050
/// providing maximum performance.
5151
#[cfg(feature = "simd-json")]
52+
#[allow(dead_code)]
5253
pub fn from_slice_mut<T: DeserializeOwned>(slice: &mut [u8]) -> Result<T, JsonError> {
5354
simd_json::from_slice(slice).map_err(JsonError::SimdJson)
5455
}
@@ -57,6 +58,7 @@ pub fn from_slice_mut<T: DeserializeOwned>(slice: &mut [u8]) -> Result<T, JsonEr
5758
///
5859
/// Falls back to standard implementation when simd-json is disabled.
5960
#[cfg(not(feature = "simd-json"))]
61+
#[allow(dead_code)]
6062
pub fn from_slice_mut<T: DeserializeOwned>(slice: &mut [u8]) -> Result<T, JsonError> {
6163
serde_json::from_slice(slice).map_err(JsonError::SerdeJson)
6264
}
@@ -65,6 +67,7 @@ pub fn from_slice_mut<T: DeserializeOwned>(slice: &mut [u8]) -> Result<T, JsonEr
6567
///
6668
/// Uses pre-allocated buffer with estimated capacity for better performance.
6769
#[cfg(feature = "simd-json")]
70+
#[allow(dead_code)]
6871
pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
6972
simd_json::to_vec(value).map_err(JsonError::SimdJson)
7073
}
@@ -73,6 +76,7 @@ pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
7376
///
7477
/// Uses pre-allocated buffer with estimated capacity for better performance.
7578
#[cfg(not(feature = "simd-json"))]
79+
#[allow(dead_code)]
7680
pub fn to_vec<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
7781
serde_json::to_vec(value).map_err(JsonError::SerdeJson)
7882
}
@@ -106,6 +110,7 @@ pub fn to_vec_with_capacity<T: Serialize>(
106110
}
107111

108112
/// Serialize a value to a pretty-printed JSON byte vector.
113+
#[allow(dead_code)]
109114
pub fn to_vec_pretty<T: Serialize>(value: &T) -> Result<Vec<u8>, JsonError> {
110115
serde_json::to_vec_pretty(value).map_err(JsonError::SerdeJson)
111116
}

crates/rustapi-core/src/path_validation.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
/// Result of path validation
88
#[derive(Debug, Clone, PartialEq, Eq)]
9+
#[allow(dead_code)]
910
pub enum PathValidationError {
1011
/// Path must start with '/'
1112
MustStartWithSlash { path: String },
@@ -151,6 +152,7 @@ impl std::error::Error for PathValidationError {}
151152
/// assert!(validate_path("/users/{}").is_err()); // Empty parameter
152153
/// assert!(validate_path("/users/{123}").is_err()); // Parameter starts with digit
153154
/// ```
155+
#[allow(dead_code)]
154156
pub fn validate_path(path: &str) -> Result<(), PathValidationError> {
155157
// Path must start with /
156158
if !path.starts_with('/') {
@@ -250,6 +252,7 @@ pub fn validate_path(path: &str) -> Result<(), PathValidationError> {
250252
}
251253

252254
/// Check if a path is valid (convenience function)
255+
#[allow(dead_code)]
253256
pub fn is_valid_path(path: &str) -> bool {
254257
validate_path(path).is_ok()
255258
}

crates/rustapi-extras/src/sqlx/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,18 @@
4848
//! }
4949
//! ```
5050
51+
#[cfg(any(
52+
feature = "sqlx-postgres",
53+
feature = "sqlx-mysql",
54+
feature = "sqlx-sqlite"
55+
))]
5156
use rustapi_core::health::{HealthCheck, HealthCheckBuilder, HealthStatus};
5257
use rustapi_core::ApiError;
58+
#[cfg(any(
59+
feature = "sqlx-postgres",
60+
feature = "sqlx-mysql",
61+
feature = "sqlx-sqlite"
62+
))]
5363
use std::sync::Arc;
5464
use std::time::Duration;
5565
use thiserror::Error;

docs/PHILOSOPHY.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,16 @@ rustapi-rs = "0.1.335"
117117
rustapi-rs = { version = "0.1.335", features = ["full"] }
118118

119119
# Pick what you need
120-
rustapi-rs = { version = "0.1.335", features = ["jwt", "cors", "toon"] }
120+
rustapi-rs = { version = "0.1.335", features = ["extras-jwt", "extras-cors", "protocol-toon"] }
121121
```
122122

123123
| Feature | What You Get |
124124
|---------|--------------|
125-
| `jwt` | JWT authentication with `AuthUser<T>` extractor |
126-
| `cors` | CORS middleware with builder pattern |
127-
| `rate-limit` | IP-based rate limiting |
128-
| `toon` | LLM-optimized TOON format |
129-
| `swagger-ui` | Auto-generated `/docs` endpoint |
125+
| `extras-jwt` | JWT authentication with `AuthUser<T>` extractor |
126+
| `extras-cors` | CORS middleware with builder pattern |
127+
| `extras-rate-limit` | IP-based rate limiting |
128+
| `protocol-toon` | LLM-optimized TOON format |
129+
| `core-openapi` | Auto-generated `/docs` endpoint |
130130
| `full` | All features enabled |
131131

132132
### 5. 🤖 LLM-First Design
@@ -219,7 +219,7 @@ async fn handler(Json(body): Json<T>) -> Json<R>
219219

220220
### Short Term (v0.x)
221221
- Polish existing features
222-
- Performance optimizations (simd-json, better allocations)
222+
- Performance optimizations (`core-simd-json`, better allocations)
223223
- More middleware (compression, static files)
224224

225225
### Medium Term (v1.0)

docs/cookbook/src/concepts/performance.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Performance is not a guessing game. Below are results from our internal benchmar
8080
| Framework | Requests/sec | Latency (avg) | Memory |
8181
|-----------|--------------|---------------|--------|
8282
| **RustAPI** | **~185,000** | **~0.54ms** | **~8MB** |
83-
| **RustAPI + simd-json** | **~220,000** | **~0.45ms** | **~8MB** |
83+
| **RustAPI + core-simd-json** | **~220,000** | **~0.45ms** | **~8MB** |
8484
| Actix-web | ~178,000 | ~0.56ms | ~10MB |
8585
| Axum | ~165,000 | ~0.61ms | ~12MB |
8686
| Rocket | ~95,000 | ~1.05ms | ~15MB |
@@ -105,7 +105,7 @@ cd benches
105105

106106
| Optimization | Description |
107107
|--------------|-------------|
108-
|**SIMD-JSON** | 2-4x faster JSON parsing with `simd-json` feature |
108+
|**SIMD-JSON** | 2-4x faster JSON parsing with `core-simd-json` feature |
109109
| 🔄 **Zero-copy parsing** | Direct memory access for path/query params |
110110
| 📦 **SmallVec PathParams** | Stack-optimized path parameters |
111111
| 🎯 **Compile-time dispatch** | All extractors resolved at compile time |

0 commit comments

Comments
 (0)