hypercpu/
lib.rs

1#![warn(missing_docs)]
2
3//! # HyperCPU
4//! 
5//! HyperCPU is a library for creating and running
6//! any kind of calculation across instances. It
7//! allows you to share your calculation logic
8//! across threads, processes, and even machines.
9//!
10//! At the core of HyperCPU is the [`Moment`] trait.
11//! A `Moment` is a unit of work that can be
12//! resolved into a value. The `resolve` method
13//! is asynchronous, so values do not need to be
14//! immediately available.
15//!
16//! Thanks to the logic behind a `Moment`, calculations
17//! can be stacked without resolution. This allows
18//! machines to resolve values in parallel, even
19//! when they depend on each other.
20
21use std::error::Error;
22
23use async_trait::async_trait;
24
25/// Provides types and traits for converting between `Moment`s.
26/// 
27/// This module is almost always required when using HyperCPU.
28/// It provides the [`Convert`] and [`TryConvert`] traits,
29/// which allow you to convert between `Moment`s of different
30/// value types.
31pub mod convert;
32
33/// Provides types and traits for various operations on `Moment`s.
34/// 
35/// This module is almost always required when using HyperCPU.
36/// It provides the standard arithmetic and logical operators
37/// for `Moment`s.
38pub mod ops;
39
40/// Provides conditional logic for `Moment`s.
41/// 
42/// This module is not in the prelude, but is still
43/// a common requirement for HyperCPU. It provides
44/// the [`If`] struct, which allows you to branch
45/// calculations based on a condition.
46pub mod cond;
47
48/// Provides easy construction of `Moment`s.
49/// 
50/// This module provides the [`Value`] struct,
51/// which uses operator overloading to allow
52/// you to easily construct `Moment`s.
53pub mod value;
54
55mod hyper;
56
57/// Provides the HyperCPU prelude.
58pub mod prelude;
59
60/// A unit of work that can be resolved into a value.
61/// 
62/// Any type that implements `Moment` can be stacked with
63/// other `Moment`s to create a calculation. The calculation
64/// can be resolved in parallel, even when the `Moment`s
65/// depend on the output of each other.
66#[async_trait]
67pub trait Moment: Send + Sync + Sized + Clone {
68  /// The type of value that this `Moment` resolves to.
69  /// 
70  /// It must be thread friendly and sized.
71  type Value: Moment;
72
73  /// Resolve this `Moment` into its value.
74  /// 
75  /// This will resolve any dependencies of this `Moment`
76  /// and then resolve this `Moment` into its value. If
77  /// this `Moment` has no dependencies, it will resolve
78  /// immediately.
79  async fn resolve(self) -> Self::Value;
80}
81
82macro_rules! literal_moments {
83  ($($ty:ty),*) => {
84    $(
85      #[async_trait]
86      impl Moment for $ty {
87        type Value = $ty;
88
89        async fn resolve(self) -> Self::Value {
90          self
91        }
92      }
93    )*
94  }
95}
96
97literal_moments![
98  u8, u16, u32, u64, u128, usize,
99  i8, i16, i32, i64, i128, isize,
100  f32, f64,
101  bool,
102  char
103];
104
105#[async_trait]
106impl<T, E> Moment for Result<T, E>
107where
108  T: Moment,
109  E: Error + Send + Sync + Clone + 'static
110{
111  type Value = Result<T::Value, E>;
112
113  async fn resolve(self) -> Self::Value {
114    match self {
115      Ok(value) => Ok(value.resolve().await),
116      Err(error) => Err(error)
117    }
118  }
119}
120
121#[async_trait]
122impl<T> Moment for Option<T>
123where
124  T: Moment
125{
126  type Value = Option<T::Value>;
127
128  async fn resolve(self) -> Self::Value {
129    match self {
130      Some(value) => Some(value.resolve().await),
131      None => None
132    }
133  }
134}