Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Declaring and using a module without a struct

I have the following module without a struct:

img_util.rs:

pub mod img_util {
    use image::{ImageBuffer, Pixel};
    use std::{fs::File, io::BufWriter};

    fn get_color_type<P>() -> Result<png::ColorType, std::io::Error>
    where
        P: Pixel<Subpixel = u8>,
    {
        match <P as Pixel>::CHANNEL_COUNT {
            4 => Ok(png::ColorType::Rgba),
            3 => Ok(png::ColorType::Rgb),
            _ => Err(std::io::Error::new(
                std::io::ErrorKind::InvalidData,
                "Incorrect color channel count / format.",
            )),
        }
    }

    fn get_dpi_header_data(dpi: u32) -> Vec<u8> {
        let dpm = 39.370079 * dpi as f32;
        let rounded_dpm = dpm.round() as u32;

        let mut data: Vec<u8> = Vec::new();
        data.extend_from_slice(&rounded_dpm.to_be_bytes()); // Pixels per unit in X-direction.
        data.extend_from_slice(&rounded_dpm.to_be_bytes()); // Pixels per unit in Y-direction.

        data.push(1); // Indicate that meters are used as unit.
        data
    }

    pub fn save_png_with_dpi<P>(
        input_img: &ImageBuffer<P, Vec<u8>>,
        output_img: File,
        dpi: u32,
    ) -> Result<(), std::io::Error>
    where
        P: Pixel<Subpixel = u8>,
    {
        let w = &mut BufWriter::new(output_img);
        let (width, height) = input_img.dimensions();
        let mut encoder = png::Encoder::new(w, width, height);

        encoder.set_color(get_color_type::<P>()?);
        encoder.set_depth(png::BitDepth::Eight);
        encoder.set_compression(png::Compression::Best);

        let data = get_dpi_header_data(dpi);
        let mut writer = encoder.write_header()?;

        writer.write_chunk(png::chunk::pHYs, data.as_slice())?;
        writer.write_image_data(input_img)?;
        Ok(())
    }
}

lib.rs:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

pub mod img_util;

main.rs:

use visual_center::img_util::img_util;

img_util::save_png_with_dpi(
    // arguments
).unwrap();

I can use the module, but I feel strange about having to declare pub mod img_util twice (once in img_util.rs and another in lib.rs). Or maybe this is the only way to declare and use a module without a struct?

>Solution :

Since you have pub mod img_util; in lib.rs, the compiler will consider img_util.rs as a module of your crate.
Everything in img_util.rs is already in the img_util module.
If you state pub mod img_util { ... } in this module, this means that you provide (inline, not in another file) a submodule with the exact same name as its parent (this is a coincidence here, you could have named it differently).

You just have to remove this pub mod img_util { ... }.
Then you will use it in main.rs as

use visual_center::img_util; // one less

img_util::save_png_with_dpi(
    // arguments
).unwrap();
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading