Skip to main content

immich_lib/models/
exif.rs

1//! EXIF metadata response types.
2
3use serde::{Deserialize, Serialize};
4
5/// EXIF metadata for an asset.
6///
7/// Most fields are optional as EXIF data may be incomplete or missing.
8#[derive(Debug, Clone, Deserialize, Serialize)]
9#[serde(rename_all = "camelCase")]
10pub struct ExifInfo {
11    /// GPS latitude
12    pub latitude: Option<f64>,
13
14    /// GPS longitude
15    pub longitude: Option<f64>,
16
17    /// City name from GPS reverse geocoding
18    pub city: Option<String>,
19
20    /// State/province from GPS reverse geocoding
21    pub state: Option<String>,
22
23    /// Country from GPS reverse geocoding
24    pub country: Option<String>,
25
26    /// Timezone of the location
27    pub time_zone: Option<String>,
28
29    /// Original capture date/time from EXIF
30    pub date_time_original: Option<String>,
31
32    /// Camera manufacturer
33    pub make: Option<String>,
34
35    /// Camera model
36    pub model: Option<String>,
37
38    /// Lens model
39    pub lens_model: Option<String>,
40
41    /// Exposure time (e.g., "1/125")
42    pub exposure_time: Option<String>,
43
44    /// Aperture f-number
45    pub f_number: Option<f64>,
46
47    /// Focal length in mm
48    pub focal_length: Option<f64>,
49
50    /// ISO sensitivity
51    pub iso: Option<u32>,
52
53    /// Image width in pixels
54    pub exif_image_width: Option<u32>,
55
56    /// Image height in pixels
57    pub exif_image_height: Option<u32>,
58
59    /// File size in bytes
60    pub file_size_in_byte: Option<u64>,
61
62    /// Image description/caption
63    pub description: Option<String>,
64
65    /// User rating (1-5)
66    pub rating: Option<u8>,
67
68    /// Image orientation (e.g., "Rotate 90 CW")
69    #[serde(default)]
70    pub orientation: Option<String>,
71
72    /// File modification date
73    #[serde(default)]
74    pub modify_date: Option<String>,
75
76    /// Projection type for 360 photos
77    #[serde(default)]
78    pub projection_type: Option<String>,
79}
80
81impl ExifInfo {
82    /// Returns true if GPS coordinates are present
83    pub fn has_gps(&self) -> bool {
84        self.latitude.is_some() && self.longitude.is_some()
85    }
86
87    /// Returns true if camera make/model is present
88    pub fn has_camera_info(&self) -> bool {
89        self.make.is_some() || self.model.is_some()
90    }
91
92    /// Returns true if timezone information is present
93    pub fn has_timezone(&self) -> bool {
94        self.time_zone.is_some()
95    }
96
97    /// Returns true if original capture time is present
98    pub fn has_capture_time(&self) -> bool {
99        self.date_time_original.is_some()
100    }
101
102    /// Returns true if lens information is present
103    pub fn has_lens_info(&self) -> bool {
104        self.lens_model.is_some()
105    }
106
107    /// Returns true if location (city/country) is present
108    pub fn has_location(&self) -> bool {
109        self.city.is_some() || self.country.is_some()
110    }
111}