stitchy_core/files/
mod.rs1pub mod builder;
2
3#[cfg(unix)]
4pub mod fd;
5
6pub mod image_types;
7pub mod path;
8pub mod raw;
9pub mod util;
10
11use image::{
12 codecs::{jpeg::JpegDecoder, webp::WebPDecoder},
13 metadata::Orientation,
14 DynamicImage, ImageDecoder, ImageError, ImageFormat,
15};
16use std::io::{BufRead, Seek};
17use std::time::SystemTime;
18
19pub trait FileLocation<P: FileProperties> {
21 fn is_file(&self) -> Result<bool, String>;
22 fn extension(&self) -> Result<String, String>;
23 fn into_properties(self) -> Result<P, String>;
24}
25
26pub trait FileProperties {
30 fn infer_format(&self) -> Option<ImageFormat>;
31 fn into_image_contents(self, print_info: bool) -> Result<DynamicImage, String>;
32 fn file_size(&self) -> u64;
33 fn modify_time(&self) -> SystemTime;
34 fn full_path(&self) -> Option<&String>;
35 fn orientation(&self) -> Result<Orientation, String>;
36
37 fn decode_orientation<R: BufRead + Seek>(&self, source: R) -> Result<Orientation, String> {
38 let format = match self.infer_format() {
39 Some(format) => format,
40 None => {
41 return Ok(Orientation::NoTransforms);
42 }
43 };
44
45 let full_path_label = match self.full_path() {
46 Some(string) => string.as_str(),
47 None => "(path unknown)",
48 };
49
50 match format {
51 ImageFormat::Jpeg => {
52 Self::decode_orientation_from_codec(full_path_label, JpegDecoder::new(source))
53 }
54 ImageFormat::WebP => {
55 Self::decode_orientation_from_codec(full_path_label, WebPDecoder::new(source))
56 }
57 _ => Ok(Orientation::NoTransforms),
58 }
59 }
60
61 fn decode_orientation_from_codec<T: ImageDecoder>(
62 full_path_label: &str,
63 decoder_result: Result<T, ImageError>,
64 ) -> Result<Orientation, String> {
65 let mut decoder =
66 decoder_result.map_err(|e| format!("Error decoding {}: {:?}", full_path_label, e))?;
67 let orientation = decoder
68 .orientation()
69 .map_err(|e| format!("Cannot decode metadata in {}: {:?}", full_path_label, e))?;
70 Ok(orientation)
71 }
72}