Skip to content

Instantly share code, notes, and snippets.

@Turupawn
Created May 6, 2025 18:19
fe jam 5 de mayo
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