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}