1#![allow(clippy::should_implement_trait)]
2
3use crate::{asm, primitives::Bytes32, storage::Value};
4use core::ops::Sub;
5
6#[repr(C)]
10#[derive(Clone, Copy, PartialEq, PartialOrd, Debug)]
11pub struct U256(Bytes32);
12
13impl U256 {
14    pub const fn empty() -> Self {
16        U256(Bytes32::empty())
17    }
18
19    #[inline(always)]
21    pub fn add(self, other: Self) -> Self {
22        unsafe { asm::ext::u256_add(self, other) }
23    }
24
25    #[inline(always)]
27    pub fn lt(self, other: Self) -> bool {
28        unsafe { asm::ext::u256_lt(other, self) }
29    }
30
31    #[inline(always)]
33    pub fn eq(self, other: Self) -> bool {
34        self.0.eq(other.0)
35    }
36
37    #[inline(always)]
39    pub fn sub(self, other: Self) -> Self {
40        unsafe { asm::ext::u256_sub(other, self) }
41    }
42
43    #[inline(always)]
45    pub fn div(self, other: Self) -> Self {
46        unsafe { asm::ext::u256_div(self, other) }
47    }
48
49    #[inline(always)]
51    pub fn max() -> Self {
52        unsafe { asm::ext::u256_max() }
53    }
54
55    pub fn to_bytes32(&self) -> Bytes32 {
56        self.0
57    }
58
59    #[cfg(not(target_family = "wasm"))]
60    pub fn bytes32(&self) -> [u8; 32] {
61        self.0 .0 }
63
64    #[inline(always)]
65    pub fn addmod(self, other: Self, modulus: Self) -> Self {
66        unsafe { asm::ext::u256_addmod(modulus, other, self) }
67    }
68
69    #[inline(always)]
71    pub fn mulmod(self, other: Self, modulus: Self) -> Self {
72        unsafe { asm::ext::u256_mulmod(modulus, other, self) }
73    }
74}
75
76impl Sub for U256 {
77    type Output = Self;
78
79    #[inline(always)]
80    fn sub(self, other: Self) -> Self::Output {
81        unsafe { asm::ext::u256_sub(self, other) }
82    }
83}
84
85impl Value for U256 {
86    #[inline(always)]
87    fn tload() -> Self {
88        Self(unsafe { asm::bytes::tload_bytes32() })
89    }
90
91    #[inline(always)]
92    fn sload() -> Self {
93        Self(unsafe { asm::bytes::sload_bytes32() })
94    }
95
96    #[inline(always)]
97    fn push(self) {
98        unsafe { asm::bytes::push_bytes32(self.0) }
99    }
100
101    #[cfg(not(target_family = "wasm"))]
102    fn bytes32(&self) -> [u8; 32] {
103        self.bytes32() }
105}
106
107impl From<u64> for U256 {
108    fn from(value: u64) -> Self {
109        #[cfg(target_family = "wasm")]
110        {
111            U256(Bytes32(value as i32))
112        }
113        #[cfg(not(target_family = "wasm"))]
114        {
115            let mut bytes = [0u8; 32];
117            bytes[24..32].copy_from_slice(&value.to_be_bytes());
118            U256(Bytes32(bytes))
119        }
120    }
121}