#![warn(missing_docs)]
#![forbid(unsafe_code)]
pub mod advanced_examples;
#[cfg(feature = "approx")]
pub mod animation;
pub mod developer_tools;
#[cfg(feature = "approx")]
pub mod easing;
pub mod ecosystem_integration;
pub mod engine;
#[cfg(feature = "approx")]
pub mod interpolation;
#[cfg(feature = "approx")]
pub mod math;
pub mod tdd_engine;
pub mod time;
pub mod timeline;
pub mod types;
pub mod values;
#[macro_use]
pub mod macros;
#[cfg(feature = "futures")]
pub mod lazy_loading;
pub mod memory_optimization;
pub mod minimal_engine;
pub mod performance;
pub mod simplified_engine;
#[cfg(feature = "approx")]
pub mod spring;
#[cfg(test)]
mod memory_optimization_tests;
#[cfg(test)]
mod basic_functionality_tests;
#[cfg(test)]
mod bundle_size_tests;
#[cfg(test)]
mod dependency_investigation_tests;
#[cfg(test)]
mod dependency_optimization_tests;
#[cfg(test)]
mod error_handling_tdd_tests;
#[cfg(test)]
mod feature_flags_tests;
mod minimal_serialization;
#[cfg(test)]
mod performance_optimization_tdd_tests;
#[cfg(test)]
mod performance_tests;
#[cfg(test)]
mod serde_replacement_tests;
#[cfg(test)]
mod tree_shaking_tests;
#[cfg(test)]
mod wasm_browser_tdd_tests;
#[cfg(test)]
mod wasm_optimization_tests;
#[cfg(test)]
mod bundle_size_optimization_tests;
#[cfg(test)]
mod feature_flags_optimization_tests;
#[cfg(test)]
mod tree_shaking_optimization_tests;
#[cfg(test)]
mod wasm_test_setup;
#[cfg(test)]
mod web_sys_optimization_tests;
#[cfg(feature = "approx")]
pub use animation::presets::AnimationPresets;
#[cfg(feature = "approx")]
pub use animation::presets::SlideDirection;
#[cfg(feature = "approx")]
pub use animation::presets::easings;
#[cfg(feature = "approx")]
pub use animation::presets::springs;
#[cfg(feature = "approx")]
pub use animation::{AnimationBuilder, AnimationConfig, Variants};
#[cfg(feature = "approx")]
pub use easing::EasingFn;
#[cfg(feature = "web-sys")]
pub use engine::WaapiEngine;
pub use engine::{AnimationEngine, OptimizedHybridEngine, PlaybackState, RafEngine};
#[cfg(feature = "approx")]
pub use interpolation::Interpolate;
#[cfg(feature = "approx")]
pub use math::{clamp, distance_2d, map_range, smooth_step, smoother_step};
#[cfg(feature = "web-sys")]
pub use time::Timer;
#[cfg(feature = "approx")]
pub use types::SpringConfig;
pub use types::{
AnimationHandle, AnimationTarget, AnimationValue, ComplexValue, Easing, RepeatConfig,
StaggerConfig, StaggerFrom, Transform, Transition,
};
#[cfg(feature = "leptos-integration")]
pub use values::{MotionNumber, MotionTransform, MotionValue, MotionValues};
#[cfg(feature = "futures")]
pub use lazy_loading::{
AnimationLazyLoader, FeatureModuleLoader, LazyLoadingConfig, LazyModule, get_lazy_loader,
};
pub use minimal_engine::MinimalEngine;
pub use simplified_engine::SimplifiedAnimationEngine;
#[cfg(feature = "approx")]
pub use spring::{SpringSimulator, SpringState};
#[cfg(feature = "performance-metrics")]
pub use performance::*;
#[cfg(feature = "memory-optimization")]
pub use memory_optimization::*;
#[cfg(feature = "lazy-loading")]
pub use lazy_loading::*;
#[cfg(feature = "simplified-engine")]
pub use simplified_engine::*;
#[cfg(feature = "minimal-serialization")]
pub use minimal_serialization::*;
pub use tdd_engine::{
AnimationConfig as TDDAnimationConfig, AnimationEngine as TDDAnimationEngine, MemoryStats,
TDDAnimationHandle,
};
pub use timeline::{Timeline, TimelineKeyframe, TimelinePerformanceMetrics};
pub use developer_tools::*;
pub use advanced_examples::*;
pub use ecosystem_integration::*;
pub type Result<T> = std::result::Result<T, AnimationError>;
#[derive(Debug, Clone)]
pub struct ErrorContext {
pub operation: String,
pub component: Option<String>,
pub timestamp: std::time::Instant,
pub additional_info: std::collections::HashMap<String, String>,
}
impl ErrorContext {
pub fn new(operation: impl Into<String>) -> Self {
Self {
operation: operation.into(),
component: None,
timestamp: std::time::Instant::now(),
additional_info: std::collections::HashMap::new(),
}
}
pub fn with_component(mut self, component: impl Into<String>) -> Self {
self.component = Some(component.into());
self
}
pub fn with_info(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.additional_info.insert(key.into(), value.into());
self
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum RecoveryStrategy {
Retry,
Fallback,
Skip,
Abort,
}
pub trait ErrorHandler {
fn handle_error(&self, error: &AnimationError, context: &ErrorContext) -> RecoveryStrategy;
fn log_error(&self, error: &AnimationError, context: &ErrorContext);
fn user_message(&self, error: &AnimationError) -> String;
}
#[derive(Debug, Clone)]
pub struct DefaultErrorHandler {
pub log_errors: bool,
pub show_user_messages: bool,
}
impl Default for DefaultErrorHandler {
fn default() -> Self {
Self {
log_errors: true,
show_user_messages: false,
}
}
}
impl ErrorHandler for DefaultErrorHandler {
fn handle_error(&self, error: &AnimationError, context: &ErrorContext) -> RecoveryStrategy {
if self.log_errors {
self.log_error(error, context);
}
match error {
AnimationError::EngineUnavailable(_) => RecoveryStrategy::Fallback,
AnimationError::InvalidProperty { property: _ } => RecoveryStrategy::Skip,
AnimationError::AlreadyRunning { handle: _ } => RecoveryStrategy::Skip,
AnimationError::NotFound { handle: _ } => RecoveryStrategy::Abort,
AnimationError::DomError(_) => RecoveryStrategy::Retry,
AnimationError::MathError(_) => RecoveryStrategy::Skip,
AnimationError::PerformanceBudgetExceeded(_) => RecoveryStrategy::Fallback,
AnimationError::InvalidConfig(_) => RecoveryStrategy::Fallback,
AnimationError::MemoryError(_) => RecoveryStrategy::Abort,
AnimationError::TimingError(_) => RecoveryStrategy::Retry,
AnimationError::NotImplemented(_) => RecoveryStrategy::Abort,
AnimationError::InvalidValue(_) => RecoveryStrategy::Skip,
}
}
fn log_error(&self, error: &AnimationError, context: &ErrorContext) {
eprintln!("Animation Error: {:?}", error);
eprintln!("Context: {:?}", context);
}
fn user_message(&self, error: &AnimationError) -> String {
if !self.show_user_messages {
return String::new();
}
match error {
AnimationError::EngineUnavailable(_) => {
"Animation system temporarily unavailable".to_string()
}
AnimationError::InvalidProperty { property: _ } => {
"Invalid animation property".to_string()
}
AnimationError::AlreadyRunning { handle: _ } => {
"Animation already in progress".to_string()
}
AnimationError::NotFound { handle: _ } => "Animation not found".to_string(),
AnimationError::DomError(_) => "Animation display error".to_string(),
AnimationError::MathError(_) => "Animation calculation error".to_string(),
AnimationError::PerformanceBudgetExceeded(_) => {
"Animation performance limit reached".to_string()
}
AnimationError::InvalidConfig(_) => "Invalid animation configuration".to_string(),
AnimationError::MemoryError(_) => "Animation memory error".to_string(),
AnimationError::TimingError(_) => "Animation timing error".to_string(),
AnimationError::NotImplemented(_) => "Feature not yet available".to_string(),
AnimationError::InvalidValue(_) => "Invalid animation value".to_string(),
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum AnimationError {
#[error("Animation engine not available: {0}")]
EngineUnavailable(String),
#[error("Invalid animation property: {property}")]
InvalidProperty {
property: String,
},
#[error("Animation already running with handle: {handle:?}")]
AlreadyRunning {
handle: AnimationHandle,
},
#[error("Animation not found: {handle:?}")]
NotFound {
handle: AnimationHandle,
},
#[error("DOM operation failed: {0}")]
DomError(String),
#[error("Math error: {0}")]
MathError(String),
#[error("Performance budget exceeded: {0}")]
PerformanceBudgetExceeded(String),
#[error("Invalid animation configuration: {0}")]
InvalidConfig(String),
#[error("Memory allocation failed: {0}")]
MemoryError(String),
#[error("Animation timing error: {0}")]
TimingError(String),
#[error("Feature not yet implemented: {0}")]
NotImplemented(String),
#[error("Invalid animation value: {0}")]
InvalidValue(String),
}
#[cfg(test)]
mod simplified_engine_tests {
include!("simplified_engine_tests.rs");
}