Jesús Pérez d3a47108af
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
chore: update gitignore and fix content
2026-02-08 20:07:09 +00:00

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.