Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
211 lines
6.0 KiB
Markdown
211 lines
6.0 KiB
Markdown
# Core Lib Template
|
|
|
|
This is a **template crate** for the core runtime library using trait-based dependency injection. It replaces the problematic code generation approach with clean, trait-based abstractions.
|
|
|
|
## Key Features
|
|
|
|
- **Zero Code Generation**: No build.rs, no environment variables, no generated code
|
|
- **Pure Dependency Injection**: Uses traits from the pure traits layer
|
|
- **Implementation Freedom**: Clone this template and customize as needed
|
|
- **No Circular Dependencies**: Clean dependency graph through trait abstractions
|
|
|
|
## Architecture
|
|
|
|
This template follows the new 3-layer architecture:
|
|
|
|
```
|
|
Layer 1: Pure Traits (../../../traits/)
|
|
↓
|
|
Layer 2: Templates (this template)
|
|
↓
|
|
Layer 3: Implementation (your cloned crate)
|
|
```
|
|
|
|
## Usage
|
|
|
|
### 1. Clone Template
|
|
|
|
```bash
|
|
# Clone this template to your implementation
|
|
cp -r templates/core-lib-template my-project/crates/core-lib
|
|
|
|
# Update Cargo.toml with your project name
|
|
sed -i 's/core-lib-template/core-lib/' my-project/crates/core-lib/Cargo.toml
|
|
```
|
|
|
|
### 2. Implement Providers
|
|
|
|
Create your concrete implementations:
|
|
|
|
```rust
|
|
use core_lib::*;
|
|
|
|
// Your page provider implementation
|
|
struct MyPageProvider {
|
|
components: HashMap<String, MyComponent>,
|
|
}
|
|
|
|
impl PageProvider for MyPageProvider {
|
|
type Component = MyComponent;
|
|
type View = AnyView;
|
|
type Props = ();
|
|
|
|
fn get_component(&self, id: &str) -> ComponentResult<Self::Component> {
|
|
self.components.get(id)
|
|
.cloned()
|
|
.ok_or_else(|| ComponentError::NotFound(id.to_string()))
|
|
}
|
|
|
|
fn render_component(
|
|
&self,
|
|
component: &Self::Component,
|
|
props: Self::Props,
|
|
language: &str
|
|
) -> ComponentResult<Self::View> {
|
|
// Your rendering logic here
|
|
Ok(component.render(language))
|
|
}
|
|
|
|
fn list_components(&self) -> Vec<String> {
|
|
self.components.keys().cloned().collect()
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Configure Application
|
|
|
|
```rust
|
|
// Create your application context
|
|
let page_provider = MyPageProvider::new();
|
|
let content_provider = MyContentProvider::new();
|
|
let localization_provider = MyLocalizationProvider::new();
|
|
let site_config = load_site_config();
|
|
|
|
let app_context = AppContext::new(
|
|
page_provider,
|
|
content_provider,
|
|
localization_provider,
|
|
site_config,
|
|
);
|
|
|
|
// Create route handler
|
|
let language_detector = ConfigurableLanguageDetector::from_site_config(&app_context.site_config);
|
|
let route_resolver = GenericRouteResolver::new(app_context.page_provider.clone(), language_detector);
|
|
```
|
|
|
|
## Modules
|
|
|
|
### Core Modules
|
|
|
|
- **`routing`**: Language detection, route resolution, generic route handling
|
|
- **`components`**: Layout providers, component rendering utilities
|
|
- **`content`**: Content item types, query builders
|
|
- **`i18n`**: Simple localization provider with HashMap storage
|
|
- **`errors`**: Comprehensive error handling with user-friendly messages
|
|
- **`utils`**: Path utilities, string formatting, configuration builders
|
|
|
|
### Feature Modules (Optional)
|
|
|
|
Enable via Cargo features:
|
|
|
|
- **`wasm`** (default): WASM utilities (console, DOM, storage, HTTP)
|
|
- **`time`**: Time formatting, timezone handling, duration parsing
|
|
- **`ids`**: UUID generation, slug utilities, content ID management
|
|
- **`content`**: Content processing utilities
|
|
- **`i18n`**: Internationalization helpers
|
|
|
|
## Benefits Over Code Generation
|
|
|
|
### Before (Problematic)
|
|
```rust
|
|
// Generated at build time, hardcoded dependencies
|
|
core_lib::generate_client_render_component!();
|
|
```
|
|
|
|
### After (Clean)
|
|
```rust
|
|
// Trait-based, implementation provides concrete types
|
|
impl<P: PageProvider> RouteRenderer for ClientRenderer<P> {
|
|
type View = AnyView;
|
|
type Component = P::Component;
|
|
|
|
fn render_component(&self, component: &Self::Component, ...) -> RoutingResult<Self::View> {
|
|
self.page_provider.render_component(component, (), language)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Example Implementation
|
|
|
|
See the comprehensive tests in each module for usage examples. Here's a minimal setup:
|
|
|
|
```rust
|
|
use core_lib::{*, routing::*, components::*, i18n::*};
|
|
|
|
// 1. Create providers
|
|
let mut page_provider = MyPageProvider::new();
|
|
page_provider.register_component("index", IndexComponent);
|
|
page_provider.register_component("about", AboutComponent);
|
|
|
|
let mut localization = SimpleLocalizationProvider::new("en".to_string());
|
|
localization.add_translation("en".to_string(), "welcome".to_string(), "Welcome".to_string());
|
|
|
|
// 2. Create language detector from config
|
|
let language_detector = ConfigurableLanguageDetector::new(languages, "en".to_string());
|
|
|
|
// 3. Create route resolver
|
|
let route_resolver = GenericRouteResolver::new(page_provider, language_detector);
|
|
|
|
// 4. Handle requests
|
|
let resolution = route_resolver.resolve_route("/about")?;
|
|
if let Some(component) = resolution.component {
|
|
let result = route_handler.handle_route(
|
|
Some(&component),
|
|
&resolution.path,
|
|
&resolution.language,
|
|
&resolution.parameters
|
|
)?;
|
|
println!("Rendered: {:?}", result.view);
|
|
}
|
|
```
|
|
|
|
## Migration from Foundation
|
|
|
|
When migrating from the old foundation crate:
|
|
|
|
1. **Remove build.rs**: No more code generation
|
|
2. **Replace generated code**: Use trait-based providers instead
|
|
3. **Inject dependencies**: Pass concrete implementations via constructors
|
|
4. **Remove environment dependencies**: Use configuration objects instead
|
|
|
|
## Features
|
|
|
|
Configure optional functionality via Cargo features:
|
|
|
|
```toml
|
|
[features]
|
|
default = ["wasm"]
|
|
full = ["wasm", "time", "ids", "content", "i18n"]
|
|
minimal = []
|
|
```
|
|
|
|
## Testing
|
|
|
|
Each module includes comprehensive tests. Run with:
|
|
|
|
```bash
|
|
cargo test
|
|
cargo test --all-features # Test with all features enabled
|
|
cargo test --no-default-features # Test minimal configuration
|
|
```
|
|
|
|
## Compatibility
|
|
|
|
- **Rust 2021 Edition**
|
|
- **WASM Compatible**: Conditional compilation for WASM vs native
|
|
- **Feature Gated**: Only compile what you need
|
|
- **Framework Agnostic**: Works with any Leptos application
|
|
|
|
---
|
|
|
|
This template solves the circular dependency and tight coupling issues while maintaining full implementation flexibility through trait-based dependency injection. |