Saturday, December 26, 2020

Rat-Maze problem - Yew app built with rustwasm

 Backtracking Algorithms

I just started loving the algorithms , especially backtracking algorithms.This geekforgeeks page gives more details on backtracking 

https://www.geeksforgeeks.org/rat-in-a-maze-backtracking-2/

Solving this problem in Rust programming  will be  a little more interesting. Even more fun if we can build this as  Rust Wasm app. Webassembly (wasm) is one of the latest technology that web developers are interested in. So thought of building  the rat-maze as a Yew app.

Yew is a modern Rust framework for creating multi-threaded front-end web apps with WebAssembly

Read mroe about Yew here - https://yew.rs/docs/en/


I used following dependencies - 

yew="0.17"
wasm-bindgen="0.2.67"
web-sys = "0.3.46"
wasm-logger = "0.2.0"
log = "0.4.6"


Backtracking -

This is one of the algorithm every programmer should try and understand. It will involve recursion and push and pop values from Results.

In my program, "solve" is the method actually implemented this backtracking

///Actual method where the backtracking algorithm is implemented
/// this method will be recursively called based the choices
/// we will be adding the "path" in this algorithm, before calling the method recursively
/// if we couldn't solve the Maze, pop the added "path" and next choice we have.


Yew Component:



///Grid is our component which displays the maze
/// Its also contains the path , once we solve it
struct Grid{
link:ComponentLink<Self>,
cell:[[u8;4];4],
path:Vec<(usize,usize)>,

}


The full program is below for your reference:

Full Code for Rat Maze


Output:




Wednesday, December 9, 2020

How to make dereference for your struct in Rust

 Dereference operator ( *)  in Rust


Dereference operator we have seen in C programming language. Yes , I am talking about the ' * ' operator that we use for dereferencing a pointer in C.

I am not sure how * operator works behind the seen, but the it dereference the pointer and give us the value in that address. 

But in Rust implementation is more obvious  that the type has to implement the trait 'Deref".

https://doc.rust-lang.org/std/ops/trait.Deref.html 


So let's see how should be convert our struct to dereference the value whatever way that we like.


Rust  Deref example

This is simple program to use * operator on MyStruct. And it is only to demonstrate the capabilities of Deref trait, not an idiomatic code.

Here we are derefencing the second field value when we use * operator on MyStruct instance.

use std::ops::Deref; struct MyStruct{ x: i32, y:String, } impl Deref for MyStruct{ //the Deref trait implementation should have Target //associated type type Target = String; // trait mandotory function implementation fn deref(&self) -> &Self::Target{ &self.y } } fn main(){ let my = MyStruct { x:4,y:"hello".to_string() }; //derefencing our struct with * operator println!("{}",*my); }



Conclusion:

Even though references and dereferencing are essential part of most of the system programming languages, how they are implemented  are always hidden behind the language implementations ( in my knowledge) . But Rust gives that insight and flexibility to use them on custom references.



Saturday, November 14, 2020

Callbacks in Rust and Python



Callbacks

Following is the definition of callbacks from wiki https://en.wikipedia.org/wiki/Callback_(computer_programming)

callback in Rust

Whenever I read any web code, callbacks are important part of the code.
So tried to build a basic callback in rust to understand what is it .


I believe , callbacks are basically storing functions/closures in array and calling them whenever required. Actually it is a little difficult to build in Rust because of the syntax and type checks.
But it’s work , type of the functions will be verified in compile time.
For example , if I give x+2 , instead of x +=2 in the below code, rust comiplier gives compilation error.
below code


Rust callback


//create a callbacks list and make some basic operations like
//register a function and calling it etc.

//callbacks struct to store the vector( list of functions)
struct CallbackV1{
    callbacks:Vec<Box<FnMut(i32)>>
}

//implemenation of the CallbackV1
impl CallbackV1{

    fn new() ->Self{

        CallbackV1 {
            callbacks : Vec::new()
        }
    }
	
	//method to register functions in the callbacks vector
    fn register(&mut self,f:Box<FnMut(i32)>){
        self.callbacks.push(f)
    }

	//method to call the functions in the callbacks
    fn call(&mut self,p:i32){

		//iterate over the callbacks vector and take a mutable reference
        for callback in self.callbacks.iter_mut(){
			
			//dereference the callback function and call with passed argument.
            (&mut *callback)(p);
        }
    }
}

fn add(x:i32){

    println!("{}",x+1);
}

fn main() {
//   let mut x = 2;
   let mut  mycallbacks = CallbackV1::new();
   let f1 = |mut x:i32| { 
                            x += 2
                            // println!("{}",x) ;
            };
   let f2 = add;

   mycallbacks.register(Box::new(f1));
   mycallbacks.register(Box::new(f2));

   mycallbacks.call(4);


}


Callback in Python

Built the same code with Python as well. Its quite easy to build the same in python. But the type checks are not there . Its simply call the functions registered. I believe this can lead to vulnerabilities .

Python Callback code


#create a callbacks list and make some basic operations like
#register a function and calling it etc.

class CallbacksV1:
    
    def __init__(self):
        self.callbacks = []
    
    def register(self,f):
        self.callbacks.append(f)
    
    def call(self,value):
        
        callback =  self.callbacks.pop()
            
        callback(value)

    
def add(x):
    print(x+1)

def add_two(x):
    print(x+2)
    return (x+2) 

c = CallbacksV1()
c.register(add)
c.register(add_two)

c.call(3)
c.call(5)