Search code examples
arraysrustcalloc

How to create an array within a constructor in Rust


I want to migrate some code from C to Rust for learning purposes and to make my learning library a bit more multi-lingual.

The problem is that I know there's a way to integrate C libraries into Rust. That way I could use calloc in Rust to allow creating my array with a range specified at runtime.

But I don't want to use calloc here - I'd like to see the Rust way. But I really don't want to use vec! either; I had some stupid issues with it before so I don't want to use it just yet.

Here is the code:

pub struct Canvas {
    width: usize,
    height: usize,
    array: [char], // I want to declare its type but not its size yet
}

impl Canvas{
    pub fn new (&self, width: usize, height: usize) -> Canvas {
        Canvas {
            width: width,
            height: height,
            array: calloc(width, height), // alternative to calloc ?            }
    }
}

I hope my question is still idiomatic to the Rust way of code.


Solution

  • i want to access that array with coordinates style

    Something like this?

    pub struct Canvas {
        width: usize,
        height: usize,
        data: Vec<u8>,
    }
    
    impl Canvas {
        pub fn new(width: usize, height: usize) -> Canvas {
            Canvas {
                width: width,
                height: height,
                data: vec![0; width*height],
            }
        }
    
        fn coords_to_index(&self, x: usize, y: usize) -> Result<usize, &'static str> {
            if x<self.width && y<self.height {
                Ok(x+y*self.width)
            } else {
                Err("Coordinates are out of bounds")
            }
        }
    
        pub fn get(&self, x: usize, y: usize) -> Result<u8, &'static str> {
            self.coords_to_index(x, y).map(|index| self.data[index])
        }
    
        pub fn set(&mut self, x: usize, y: usize, new_value: u8) -> Result<(), &'static str>{
            self.coords_to_index(x, y).map(|index| {self.data[index]=new_value;})
        }
    }
    
    fn main() {
        let mut canvas = Canvas::new(100, 100);
        println!("{:?}", canvas.get(50, 50)); // Ok(0)
        println!("{:?}", canvas.get(101, 50)); // Err("Coordinates are out of bounds")
        println!("{:?}", canvas.set(50, 50, 128)); // Ok(())
        println!("{:?}", canvas.set(101, 50, 128)); // Err("Coordinates are out of bounds")
        println!("{:?}", canvas.get(50, 50)); // Ok(128)
    }