1#![doc = include_str!(".crate-docs.md")]
2use std::fmt::Debug;
3use std::sync::Arc;
4
5use easings::Linear;
6
7pub mod easings;
8
9#[derive(Debug, Clone, PartialEq)]
11pub struct EasingFunction(EasingKind);
12
13impl EasingFunction {
14 pub fn from_fn(func: fn(f32) -> f32) -> Self {
16 Self(EasingKind::Fn(func))
17 }
18
19 pub fn new<Easing>(easing: Easing) -> Self
21 where
22 Easing: crate::Easing + Debug + Clone,
23 {
24 Self(EasingKind::Custom(Arc::new(easing)))
25 }
26}
27
28impl Easing for EasingFunction {
29 fn ease(&self, progress: f32) -> f32 {
30 self.0.ease(progress)
31 }
32}
33
34impl Default for EasingFunction {
35 fn default() -> Self {
36 Self::from(Linear)
37 }
38}
39
40#[derive(Debug, Clone)]
41enum EasingKind {
42 Fn(fn(f32) -> f32),
44 Custom(Arc<dyn Easing>),
46}
47
48impl Easing for EasingKind {
49 fn ease(&self, progress: f32) -> f32 {
50 match self {
51 Self::Fn(func) => func(progress),
52 Self::Custom(func) => func.ease(progress),
53 }
54 }
55}
56
57impl PartialEq for EasingKind {
58 fn eq(&self, other: &Self) -> bool {
59 match (self, other) {
60 (Self::Fn(l0), Self::Fn(r0)) => l0 == r0,
61 (Self::Custom(l0), Self::Custom(r0)) => std::ptr::eq(&**l0, &**r0),
62 _ => false,
63 }
64 }
65}
66
67pub trait Easing: Debug + Send + Sync + 'static {
69 fn ease(&self, progress: f32) -> f32;
72}
73
74impl<T> Easing for T
75where
76 T: Fn(f32) -> f32 + Debug + Send + Sync + 'static,
77{
78 fn ease(&self, progress: f32) -> f32 {
79 self(progress)
80 }
81}