calimero_runtime/
constraint.rs

1use core::marker::PhantomData;
2use core::ops::Deref;
3
4use thiserror::Error as ThisError;
5
6#[derive(Debug)]
7pub struct Constrained<T, R> {
8    value: T,
9    _phantom: PhantomData<R>,
10}
11
12impl<T: Copy, R> Copy for Constrained<T, R> {}
13
14impl<T: Clone, R> Clone for Constrained<T, R> {
15    fn clone(&self) -> Self {
16        Self {
17            value: self.value.clone(),
18            _phantom: PhantomData,
19        }
20    }
21}
22
23impl<T, R> Deref for Constrained<T, R> {
24    type Target = T;
25
26    fn deref(&self) -> &Self::Target {
27        &self.value
28    }
29}
30
31pub trait Constrains<T> {
32    type Error;
33
34    fn validate(value: T) -> Result<T, Self::Error>;
35}
36
37pub trait Constraint: Sized {
38    fn validate<R: Constrains<Self>>(self) -> Result<Constrained<Self, R>, R::Error>;
39}
40
41impl<T> Constraint for T {
42    fn validate<R: Constrains<T>>(self) -> Result<Constrained<T, R>, R::Error> {
43        Ok(Constrained {
44            value: R::validate(self)?,
45            _phantom: PhantomData,
46        })
47    }
48}
49
50#[derive(Debug, Clone)]
51pub struct MaxU64<const MAX: u64>;
52
53#[derive(Debug, ThisError)]
54#[error("value {0} is greater than the maximum {MAX}")]
55pub struct MaxU64Error<const MAX: u64>(u64);
56
57impl<const MAX: u64> Constrains<u64> for MaxU64<MAX> {
58    type Error = MaxU64Error<MAX>;
59
60    fn validate(value: u64) -> Result<u64, Self::Error> {
61        if value < MAX {
62            return Ok(value);
63        }
64
65        Err(MaxU64Error::<MAX>(value))
66    }
67}