truster 0.4.1

A ray tracing library based on the book 'The Ray Tracer Challenge' by Jamis Buck.
Documentation
use std::rc::Rc;

use truster::canvas::Canvas;
use truster::color::Color;
use truster::intersection::Hit;
use truster::light::PointLight;
use truster::material::Material;
use truster::matrix::Matrix;
use truster::ray::Ray;
use truster::shape::{sphere::Sphere, Shape};
use truster::texture::solid_color::SolidColor;
use truster::tuple::Tuple;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let ray_origin = Tuple::point(0.0, 0.0, -5.0);
    let wall_z = 10.0;
    let wall_size = 7.0;

    let canvas_pixels: usize = 100;
    let pixel_size = wall_size / canvas_pixels as f64;
    let half = wall_size / 2.0;

    let mut canvas = Canvas::new(canvas_pixels, canvas_pixels);
    let mut shape = Sphere::new();
    shape.set_transform(
        Matrix::shearing(1.0, 0.0, 0.0, 0.0, 0.0, 0.0) * &Matrix::scaling(0.5, 1.0, 1.0),
    );
    shape.set_material(Material {
        texture: Rc::new(SolidColor::new(Color::new(1.0, 0.2, 1.0))),
        ..Material::default()
    });
    let shape: Rc<dyn Shape> = Rc::new(shape);

    let light = PointLight::new(Tuple::point(-10.0, 10.0, -10.0), Color::new(1.0, 1.0, 1.0));

    for y in (0..canvas_pixels).rev() {
        let world_y = half - pixel_size * y as f64;

        for x in 0..canvas_pixels {
            let world_x = pixel_size * x as f64 - half;

            let position = Tuple::point(world_x, world_y, wall_z);

            let ray = Ray::new(ray_origin, (position - ray_origin).normalized());
            let intersections = shape.intersect(&ray);

            if let Some(hit) = intersections.hit() {
                let point = ray.at(hit.t());
                let normal = hit.shape().normal_at(point);
                let eye = -ray.direction();

                let color = hit.shape().material().lighting(
                    Rc::clone(&shape),
                    &light,
                    point,
                    eye,
                    normal,
                    false,
                );

                canvas[[x, y]] = color;
            }
        }
    }

    canvas.to_ppm(&mut std::io::stdout())?;

    Ok(())
}