英文:
Declaring and using a module without a struct
问题
您可以在lib.rs
文件中声明模块并将其导出,然后在其他文件中引用它,而不需要在每个文件中都声明模块。这意味着您只需在lib.rs
中声明img_util
模块一次,然后可以在其他文件中引用它,无需在每个文件中都重复声明。
英文:
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:
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?
答案1
得分: 1
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();
英文:
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();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论