Created
May 6, 2025 18:19
fe jam 5 de mayo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use ingot::codec::{Encode, Decode} | |
use ingot::operators::{Add, Sub, AddAssign, SubAssign} | |
use ingot::default::{Default} | |
pub trait Hasher { | |
type Output | |
fn hash<T: Encode>(mut self, key: T) -> Self::Output | |
} | |
impl Hasher for Sha1 { | |
type Output = Sha1Hash | |
fn hash<T: Encode>(mut self, key: T) -> Self::Output { | |
let bytes = ... | |
Sha1Hash(bytes) | |
} | |
} | |
// error | |
impl Hasher for Sha1 { | |
type Output = Sha2Hash | |
... | |
} | |
pub struct Sha1Hash([u8; 16]) | |
fn hash<H: Hasher>(val: ..., hasher: H) -> H::Output { | |
} | |
//Hasher<u256> | |
//Hasher<Sha1Hash> | |
//... | |
pub trait Hasher<Output> { | |
fn hash<T: Encode>(mut self, key: T) -> Output | |
} | |
impl Hasher<Sha1Hash> for Sha1 { | |
fn hash<T: Encode>(mut self, key: T) -> Sha1Hash { | |
let bytes = ... | |
Sha1Hash(bytes) | |
} | |
} | |
impl Hasher<Sha2Hash> for Sha1 { | |
fn hash<T: Encode>(mut self, key: T) -> Sha2Hash { | |
let bytes = ... | |
Sha2Hash(bytes) | |
} | |
} | |
//Foo<u32> | |
//Foo<u64> | |
struct Foo<T> { | |
inner: T | |
} | |
fn hash_to_u256<T, H: Hasher<u256>>(val: ..., hasher: H) -> u256 { | |
} | |
fn hash<T, H: Hasher<T>>(val: ..., hasher: H) -> T { | |
} | |
trait Add<T> { | |
type Output // unique for a given (Self, T) | |
fn add(self, other: T) -> Self::Output | |
} | |
impl Add<u64> for u32 { // Self = u32, T = u64 | |
type Output = u64 // | |
fn add... | |
} | |
// typeclass Add a, b, |-> output | |
let x: u32 = 10 | |
let y: u64 = 20 | |
let z = 10 + 20 // always u64 | |
trait Add<T, Ouput> { | |
fn add(self, other: T) -> Output | |
} | |
impl Add<u64, u64> for u32 { | |
fn add... | |
} | |
impl Add<u64, u128> for u32 { | |
fn add... | |
} | |
let x: u32 = 10 | |
let y: u64 = 20 | |
let z = 10 + 20 // unknown type!! | |
trait Abi { | |
type Selector: Encode<Self> | |
type Encoder | |
} | |
struct SolAbi {} | |
impl Abi for SolAbi { | |
type Selector = [u8; 4] | |
type Encoder = SolEncoder | |
} | |
impl<T> Iterator for Vec<T> { | |
type Item = &T; | |
} | |
for x in myvec { | |
} | |
let x = foo(10u32) // x is definitely u64 | |
fn foo<T: Add<u64>>(val: T) -> T::Output | |
pub trait MapStorage<T, U> { | |
fn get(mut self, key: T) -> U | |
fn set(mut self, key: T, value: U) -> bool | |
fn entry(mut self, key: T) -> Entry<T, U, Self> | |
} | |
pub struct Map<T, U, S: MapStorage<T, U>> { | |
pub storage: S | |
} | |
impl<T, U, S: MapStorage<T, U>> Map<T, U, S> | |
where T: Encode, U: Encode, U: Decode | |
{ | |
pub fn get(mut self, key: T) -> U { | |
self.storage.get(key) | |
} | |
pub fn set(mut self, key: T, value: U) -> bool { | |
self.storage.set(key, value) | |
} | |
pub fn entry(mut self, key: T) -> Entry<T, U, S> { | |
self.storage.entry(key) | |
} | |
} | |
pub enum Entry<T, U, S: MapStorage<T, U>> { | |
Occupied { pub key: T, pub value: U, pub index: u256, pub storage: S }, | |
Vacant { pub key: T, pub storage: S } | |
} | |
impl<T, U, S: MapStorage<T, U>> Entry<T, U, S> | |
where U: Default | |
{ | |
pub fn or_insert(mut self, value: U) -> U { | |
match self { | |
Entry::Occupied { value: v, .. } => v | |
Entry::Vacant { key, mut storage } => { | |
storage.set(key, value) | |
value | |
} | |
} | |
} | |
pub fn value(self) -> U { | |
match self { | |
Entry::Occupied { value, .. } => value | |
Entry::Vacant { .. } => U::default() | |
} | |
} | |
} | |
impl<K, V, S> AddAssign<V> for Entry<K, V, S> | |
where | |
S: MapStorage<K, V>, | |
V: Add | |
{ | |
fn add_assign(mut self, rhs: V) { | |
match self { | |
Entry::Occupied { key, value, index, mut storage } => { | |
let new_value = value.add(rhs: rhs) | |
storage.set(key: key, value: new_value) | |
self = Entry::Occupied { key, value: new_value, index, storage } | |
} | |
Entry::Vacant { key, storage } => { | |
self = Entry::Vacant { key, storage } | |
} | |
} | |
} | |
} | |
impl<K, V, S> SubAssign<V> for Entry<K, V, S> | |
where | |
S: MapStorage<K, V>, | |
V: Sub | |
{ | |
fn sub_assign(mut self, rhs: V) { | |
match self { | |
Entry::Occupied { key, value, index, mut storage } => { | |
let new_value = value.sub(rhs: rhs) | |
storage.set(key: key, value: new_value) | |
self = Entry::Occupied { key, value: new_value, index, storage } | |
} | |
Entry::Vacant { key, storage } => { | |
self = Entry::Vacant { key, storage } | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment