1#![allow(non_upper_case_globals)]
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fmt;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub struct TagId(pub &'static str);
13
14impl TagId {
15 pub const fn new(name: &'static str) -> Self {
17 Self(name)
18 }
19
20 pub fn name(&self) -> &str {
22 self.0
23 }
24
25 pub const Make: Self = Self("Make");
27 pub const Model: Self = Self("Model");
28 pub const DateTimeOriginal: Self = Self("DateTimeOriginal");
29 pub const CreateDate: Self = Self("CreateDate");
30 pub const ModifyDate: Self = Self("ModifyDate");
31 pub const ImageWidth: Self = Self("ImageWidth");
32 pub const ImageHeight: Self = Self("ImageHeight");
33 pub const Orientation: Self = Self("Orientation");
34 pub const XResolution: Self = Self("XResolution");
35 pub const YResolution: Self = Self("YResolution");
36 pub const ResolutionUnit: Self = Self("ResolutionUnit");
37 pub const Software: Self = Self("Software");
38 pub const Copyright: Self = Self("Copyright");
39 pub const Artist: Self = Self("Artist");
40 pub const ImageDescription: Self = Self("ImageDescription");
41
42 pub const ExposureTime: Self = Self("ExposureTime");
44 pub const FNumber: Self = Self("FNumber");
45 pub const ExposureProgram: Self = Self("ExposureProgram");
46 pub const Iso: Self = Self("ISO");
47 pub const SensitivityType: Self = Self("SensitivityType");
48 pub const RecommendedExposureIndex: Self = Self("RecommendedExposureIndex");
49 pub const ExifVersion: Self = Self("ExifVersion");
50 pub const DateTimeDigitized: Self = Self("DateTimeDigitized");
51 pub const ComponentConfiguration: Self = Self("ComponentConfiguration");
52 pub const ShutterSpeedValue: Self = Self("ShutterSpeedValue");
53 pub const ApertureValue: Self = Self("ApertureValue");
54 pub const BrightnessValue: Self = Self("BrightnessValue");
55 pub const ExposureCompensation: Self = Self("ExposureCompensation");
56 pub const MaxApertureValue: Self = Self("MaxApertureValue");
57 pub const SubjectDistance: Self = Self("SubjectDistance");
58 pub const MeteringMode: Self = Self("MeteringMode");
59 pub const LightSource: Self = Self("LightSource");
60 pub const Flash: Self = Self("Flash");
61 pub const FocalLength: Self = Self("FocalLength");
62 pub const FocalLengthIn35mmFormat: Self = Self("FocalLengthIn35mmFormat");
63 pub const FlashEnergy: Self = Self("FlashEnergy");
64 pub const SpatialFrequencyResponse: Self = Self("SpatialFrequencyResponse");
65 pub const FocalPlaneXResolution: Self = Self("FocalPlaneXResolution");
66 pub const FocalPlaneYResolution: Self = Self("FocalPlaneYResolution");
67 pub const FocalPlaneResolutionUnit: Self = Self("FocalPlaneResolutionUnit");
68 pub const SubjectLocation: Self = Self("SubjectLocation");
69 pub const ExposureIndex: Self = Self("ExposureIndex");
70 pub const SensingMethod: Self = Self("SensingMethod");
71 pub const FileSource: Self = Self("FileSource");
72 pub const SceneType: Self = Self("SceneType");
73 pub const CfaPattern: Self = Self("CFAPattern");
74 pub const CustomRendered: Self = Self("CustomRendered");
75 pub const ExposureMode: Self = Self("ExposureMode");
76 pub const WhiteBalance: Self = Self("WhiteBalance");
77 pub const DigitalZoomRatio: Self = Self("DigitalZoomRatio");
78 pub const FocalLength35efl: Self = Self("FocalLength35efl");
79 pub const SceneCaptureType: Self = Self("SceneCaptureType");
80 pub const GainControl: Self = Self("GainControl");
81 pub const Contrast: Self = Self("Contrast");
82 pub const Saturation: Self = Self("Saturation");
83 pub const Sharpness: Self = Self("Sharpness");
84 pub const DeviceSettingDescription: Self = Self("DeviceSettingDescription");
85 pub const SubjectDistanceRange: Self = Self("SubjectDistanceRange");
86
87 pub const GpsLatitudeRef: Self = Self("GPSLatitudeRef");
89 pub const GpsLatitude: Self = Self("GPSLatitude");
90 pub const GpsLongitudeRef: Self = Self("GPSLongitudeRef");
91 pub const GpsLongitude: Self = Self("GPSLongitude");
92 pub const GpsAltitudeRef: Self = Self("GPSAltitudeRef");
93 pub const GpsAltitude: Self = Self("GPSAltitude");
94 pub const GpsTimestamp: Self = Self("GPSTimeStamp");
95 pub const GpsSatellites: Self = Self("GPSSatellites");
96 pub const GpsStatus: Self = Self("GPSStatus");
97 pub const GpsMeasureMode: Self = Self("GPSMeasureMode");
98 pub const GpsDop: Self = Self("GPSDOP");
99 pub const GpsSpeedRef: Self = Self("GPSSpeedRef");
100 pub const GpsSpeed: Self = Self("GPSSpeed");
101 pub const GpsTrackRef: Self = Self("GPSTrackRef");
102 pub const GpsTrack: Self = Self("GPSTrack");
103 pub const GpsImgDirectionRef: Self = Self("GPSImgDirectionRef");
104 pub const GpsImgDirection: Self = Self("GPSImgDirection");
105 pub const GpsMapDatum: Self = Self("GPSMapDatum");
106 pub const GpsDestLatitudeRef: Self = Self("GPSDestLatitudeRef");
107 pub const GpsDestLatitude: Self = Self("GPSDestLatitude");
108 pub const GpsDestLongitudeRef: Self = Self("GPSDestLongitudeRef");
109 pub const GpsDestLongitude: Self = Self("GPSDestLongitude");
110 pub const GpsDestBearingRef: Self = Self("GPSDestBearingRef");
111 pub const GpsDestBearing: Self = Self("GPSDestBearing");
112 pub const GpsDestDistanceRef: Self = Self("GPSDestDistanceRef");
113 pub const GpsDestDistance: Self = Self("GPSDestDistance");
114 pub const GpsProcessingMethod: Self = Self("GPSProcessingMethod");
115 pub const GpsAreaInformation: Self = Self("GPSAreaInformation");
116 pub const GpsDateStamp: Self = Self("GPSDateStamp");
117 pub const GpsDifferential: Self = Self("GPSDifferential");
118 pub const GpsHPositioningError: Self = Self("GPSHPositioningError");
119
120 pub const FileName: Self = Self("FileName");
122 pub const Directory: Self = Self("Directory");
123 pub const FileSize: Self = Self("FileSize");
124 pub const FileModifyDate: Self = Self("FileModifyDate");
125 pub const FileAccessDate: Self = Self("FileAccessDate");
126 pub const FileInodeChangeDate: Self = Self("FileInodeChangeDate");
127 pub const FilePermissions: Self = Self("FilePermissions");
128 pub const FileType: Self = Self("FileType");
129 pub const FileTypeExtension: Self = Self("FileTypeExtension");
130 pub const MimeType: Self = Self("MIMEType");
131 pub const ExifByteOrder: Self = Self("ExifByteOrder");
132 pub const CurrentIccProfile: Self = Self("CurrentICCProfile");
133 pub const ProfileDateTime: Self = Self("ProfileDateTime");
134 pub const ProfileFileSignature: Self = Self("ProfileFileSignature");
135 pub const PrimaryPlatform: Self = Self("PrimaryPlatform");
136 pub const CmmType: Self = Self("CMMType");
137 pub const ProfileVersion: Self = Self("ProfileVersion");
138 pub const ProfileClass: Self = Self("ProfileClass");
139 pub const ColorSpaceData: Self = Self("ColorSpaceData");
140 pub const ProfileConnectionSpace: Self = Self("ProfileConnectionSpace");
141 pub const ProfileConnectionSpaceIlluminant: Self = Self("ProfileConnectionSpaceIlluminant");
142 pub const IccProfileCreator: Self = Self("ICCProfileCreator");
143 pub const IccProfileDescription: Self = Self("ICCProfileDescription");
144 pub const IccViewingConditionsDescription: Self = Self("ICCViewingConditionsDescription");
145 pub const IccDeviceModel: Self = Self("ICCDeviceModel");
146 pub const IccDeviceManufacturer: Self = Self("ICCDeviceManufacturer");
147
148 pub const IptcObjectName: Self = Self("ObjectName");
150 pub const IptcEditStatus: Self = Self("EditStatus");
151 pub const IptcEditorialUpdate: Self = Self("EditorialUpdate");
152 pub const IptcUrgency: Self = Self("Urgency");
153 pub const IptcSubjectReference: Self = Self("SubjectReference");
154 pub const IptcCategory: Self = Self("Category");
155 pub const IptcSupplementalCategory: Self = Self("SupplementalCategory");
156 pub const IptcFixtureIdentifier: Self = Self("FixtureIdentifier");
157 pub const IptcKeywords: Self = Self("Keywords");
158 pub const IptcContentLocationCode: Self = Self("ContentLocationCode");
159 pub const IptcContentLocationName: Self = Self("ContentLocationName");
160 pub const IptcReleaseDate: Self = Self("ReleaseDate");
161 pub const IptcReleaseTime: Self = Self("ReleaseTime");
162 pub const IptcExpirationDate: Self = Self("ExpirationDate");
163 pub const IptcExpirationTime: Self = Self("ExpirationTime");
164 pub const IptcSpecialInstructions: Self = Self("SpecialInstructions");
165 pub const IptcActionAdvised: Self = Self("ActionAdvised");
166 pub const IptcReferenceService: Self = Self("ReferenceService");
167 pub const IptcReferenceDate: Self = Self("ReferenceDate");
168 pub const IptcReferenceNumber: Self = Self("ReferenceNumber");
169 pub const IptcDateCreated: Self = Self("DateCreated");
170 pub const IptcTimeCreated: Self = Self("TimeCreated");
171 pub const IptcDigitalCreationDate: Self = Self("DigitalCreationDate");
172 pub const IptcDigitalCreationTime: Self = Self("DigitalCreationTime");
173 pub const IptcOriginatingProgram: Self = Self("OriginatingProgram");
174 pub const IptcProgramVersion: Self = Self("ProgramVersion");
175 pub const IptcObjectCycle: Self = Self("ObjectCycle");
176 pub const IptcByLine: Self = Self("By-line");
177 pub const IptcByLineTitle: Self = Self("By-lineTitle");
178 pub const IptcCity: Self = Self("City");
179 pub const IptcSubLocation: Self = Self("Sub-location");
180 pub const IptcProvinceState: Self = Self("Province-State");
181 pub const IptcCountryPrimaryLocationCode: Self = Self("Country-PrimaryLocationCode");
182 pub const IptcCountryPrimaryLocationName: Self = Self("Country-PrimaryLocationName");
183 pub const IptcOriginalTransmissionReference: Self = Self("OriginalTransmissionReference");
184 pub const IptcHeadline: Self = Self("Headline");
185 pub const IptcCredit: Self = Self("Credit");
186 pub const IptcSource: Self = Self("Source");
187 pub const IptcCopyrightNotice: Self = Self("CopyrightNotice");
188 pub const IptcContact: Self = Self("Contact");
189 pub const IptcCaptionAbstract: Self = Self("Caption-Abstract");
190 pub const IptcWriterEditor: Self = Self("Writer-Editor");
191 pub const IptcImageType: Self = Self("ImageType");
192 pub const IptcImageOrientation: Self = Self("ImageOrientation");
193 pub const IptcLanguageIdentifier: Self = Self("LanguageIdentifier");
194
195 pub const XmpDcTitle: Self = Self("Title");
197 pub const XmpDcCreator: Self = Self("Creator");
198 pub const XmpDcSubject: Self = Self("Subject");
199 pub const XmpDcDescription: Self = Self("Description");
200 pub const XmpDcPublisher: Self = Self("Publisher");
201 pub const XmpDcContributor: Self = Self("Contributor");
202 pub const XmpDcDate: Self = Self("Date");
203 pub const XmpDcType: Self = Self("Type");
204 pub const XmpDcFormat: Self = Self("Format");
205 pub const XmpDcIdentifier: Self = Self("Identifier");
206 pub const XmpDcSource: Self = Self("Source");
207 pub const XmpDcLanguage: Self = Self("Language");
208 pub const XmpDcRelation: Self = Self("Relation");
209 pub const XmpDcCoverage: Self = Self("Coverage");
210 pub const XmpDcRights: Self = Self("Rights");
211
212 pub const XmpXmpRightsManaged: Self = Self("RightsManaged");
214 pub const XmpXmpRightsMarked: Self = Self("RightsMarked");
215 pub const XmpXmpRightsWebStatement: Self = Self("WebStatement");
216 pub const XmpXmpRightsUsageTerms: Self = Self("UsageTerms");
217
218 pub const ImageSize: Self = Self("ImageSize");
220 pub const Megapixels: Self = Self("Megapixels");
221 pub const Quality: Self = Self("Quality");
222 pub const BitsPerSample: Self = Self("BitsPerSample");
223 pub const ColorComponents: Self = Self("ColorComponents");
224 pub const YCbCrSubSampling: Self = Self("YCbCrSubSampling");
225 pub const YCbCrPositioning: Self = Self("YCbCrPositioning");
226
227 pub const ThumbnailImage: Self = Self("ThumbnailImage");
229 pub const ThumbnailLength: Self = Self("ThumbnailLength");
230 pub const ThumbnailOffset: Self = Self("ThumbnailOffset");
231 pub const PreviewImage: Self = Self("PreviewImage");
232 pub const PreviewImageType: Self = Self("PreviewImageType");
233 pub const JpgFromRaw: Self = Self("JpgFromRaw");
234 pub const OtherImage: Self = Self("OtherImage");
235
236 pub const ColorSpace: Self = Self("ColorSpace");
238 pub const Gamma: Self = Self("Gamma");
239
240 pub const HyperfocalDistance: Self = Self("HyperfocalDistance");
242 pub const ScaleFactor35efl: Self = Self("ScaleFactor35efl");
243 pub const CircleOfConfusion: Self = Self("CircleOfConfusion");
244 pub const FieldOfView: Self = Self("FieldOfView");
245 pub const LensId: Self = Self("LensID");
246 pub const LensInfo: Self = Self("LensInfo");
247 pub const LensSpec: Self = Self("LensSpec");
248 pub const LensMake: Self = Self("LensMake");
249 pub const LensModel: Self = Self("LensModel");
250 pub const LensSerialNumber: Self = Self("LensSerialNumber");
251
252 pub const CanonModelId: Self = Self("CanonModelID");
254 pub const CanonExposureMode: Self = Self("CanonExposureMode");
255 pub const CanonFlashMode: Self = Self("CanonFlashMode");
256 pub const CanonLensType: Self = Self("CanonLensType");
257 pub const CanonLensModel: Self = Self("CanonLensModel");
258 pub const CanonImageSize: Self = Self("CanonImageSize");
259 pub const CanonImageQuality: Self = Self("CanonImageQuality");
260 pub const CanonSharpness: Self = Self("CanonSharpness");
261 pub const CanonContrast: Self = Self("CanonContrast");
262 pub const CanonSaturation: Self = Self("CanonSaturation");
263 pub const CanonColorTone: Self = Self("CanonColorTone");
264 pub const CanonColorSpace: Self = Self("CanonColorSpace");
265 pub const CanonPictureStyle: Self = Self("CanonPictureStyle");
266 pub const CanonDriveMode: Self = Self("CanonDriveMode");
267 pub const CanonFocusMode: Self = Self("CanonFocusMode");
268 pub const CanonMeteringMode: Self = Self("CanonMeteringMode");
269 pub const CanonAfPoint: Self = Self("CanonAFPoint");
270 pub const CanonSelfTimer: Self = Self("CanonSelfTimer");
271 pub const CanonImageStabilization: Self = Self("CanonImageStabilization");
272 pub const CanonWhiteBalance: Self = Self("CanonWhiteBalance");
273
274 pub const NikonMake: Self = Self("NikonMake");
276 pub const NikonQuality: Self = Self("NikonQuality");
277 pub const NikonColorMode: Self = Self("NikonColorMode");
278 pub const NikonImageAdjustment: Self = Self("NikonImageAdjustment");
279 pub const NikonCcdSensitivity: Self = Self("NikonCCDSensitivity");
280 pub const NikonWhiteBalanceFine: Self = Self("NikonWhiteBalanceFine");
281 pub const NikonIsoSetting: Self = Self("NikonISOSetting");
282 pub const NikonImageOptimization: Self = Self("NikonImageOptimization");
283 pub const NikonSaturationAdjust: Self = Self("NikonSaturationAdjust");
284 pub const NikonSharpnessAdjust: Self = Self("NikonSharpnessAdjust");
285 pub const NikonFocusMode: Self = Self("NikonFocusMode");
286 pub const NikonFlashMode: Self = Self("NikonFlashMode");
287 pub const NikonShootingMode: Self = Self("NikonShootingMode");
288 pub const NikonAutoBracketRelease: Self = Self("NikonAutoBracketRelease");
289 pub const NikonLensType: Self = Self("NikonLensType");
290 pub const NikonLens: Self = Self("NikonLens");
291
292 pub const SonyMake: Self = Self("SonyMake");
294 pub const SonyImageSize: Self = Self("SonyImageSize");
295 pub const SonyQuality: Self = Self("SonyQuality");
296 pub const SonyFlashMode: Self = Self("SonyFlashMode");
297 pub const SonyExposureMode: Self = Self("SonyExposureMode");
298 pub const SonyFocusMode: Self = Self("SonyFocusMode");
299 pub const SonyWhiteBalanceMode: Self = Self("SonyWhiteBalanceMode");
300 pub const SonyMacro: Self = Self("SonyMacro");
301 pub const SonySharpness: Self = Self("SonySharpness");
302 pub const SonySaturation: Self = Self("SonySaturation");
303 pub const SonyContrast: Self = Self("SonyContrast");
304 pub const SonyBrightness: Self = Self("SonyBrightness");
305 pub const SonyLongExposureNoiseReduction: Self = Self("SonyLongExposureNoiseReduction");
306 pub const SonyHighIsoNoiseReduction: Self = Self("SonyHighISONoiseReduction");
307 pub const SonyHdr: Self = Self("SonyHDR");
308 pub const SonyMultiFrameNr: Self = Self("SonyMultiFrameNR");
309
310 pub const FujiQuality: Self = Self("FujiQuality");
312 pub const FujiSaturation: Self = Self("FujiSaturation");
313 pub const FujiWhiteBalanceFineTune: Self = Self("FujiWhiteBalanceFineTune");
314 pub const FujiHighIs0NoiseReduction: Self = Self("FujiHighIS0NoiseReduction");
315 pub const FujiFocusMode: Self = Self("FujiFocusMode");
316 pub const FujiAfMode: Self = Self("FujiAFMode");
317 pub const FujiFocusPixel: Self = Self("FujiFocusPixel");
318 pub const FujiImageSize: Self = Self("FujiImageSize");
319 pub const FujiDualImageStabilization: Self = Self("FujiDualImageStabilization");
320 pub const FujiFaceDetection: Self = Self("FujiFaceDetection");
321 pub const FujiNumFaceElements: Self = Self("FujiNumFaceElements");
322
323 pub const PanasonicImageQuality: Self = Self("PanasonicImageQuality");
325 pub const PanasonicColorMode: Self = Self("PanasonicColorMode");
326 pub const PanasonicImageStabilization: Self = Self("PanasonicImageStabilization");
327 pub const PanasonicMacroMode: Self = Self("PanasonicMacroMode");
328 pub const PanasonicFocusMode: Self = Self("PanasonicFocusMode");
329 pub const PanasonicAfAreaMode: Self = Self("PanasonicAFAreaMode");
330 pub const PanasonicImageStabilization2: Self = Self("PanasonicImageStabilization2");
331 pub const PanasonicBabyAge: Self = Self("PanasonicBabyAge");
332 pub const PanasonicBabyName: Self = Self("PanasonicBabyName");
333
334 pub const OlympusImageQuality: Self = Self("OlympusImageQuality");
336 pub const OlympusMacroMode: Self = Self("OlympusMacroMode");
337 pub const OlympusDigitalZoom: Self = Self("OlympusDigitalZoom");
338 pub const OlympusVersion: Self = Self("OlympusVersion");
339 pub const OlympusImageProcessing: Self = Self("OlympusImageProcessing");
340 pub const OlympusFocusMode: Self = Self("OlympusFocusMode");
341 pub const OlympusAfArea: Self = Self("OlympusAFArea");
342 pub const OlympusAfPoint: Self = Self("OlympusAFPoint");
343 pub const OlympusImageStabilization: Self = Self("OlympusImageStabilization");
344 pub const OlympusColorSpace: Self = Self("OlympusColorSpace");
345
346 pub const PentaxModelType: Self = Self("PentaxModelType");
348 pub const PentaxImageSize: Self = Self("PentaxImageSize");
349 pub const PentaxQuality: Self = Self("PentaxQuality");
350 pub const PentaxImageProcessing: Self = Self("PentaxImageProcessing");
351 pub const PentaxFocusMode: Self = Self("PentaxFocusMode");
352 pub const PentaxAfPoint: Self = Self("PentaxAFPoint");
353 pub const PentaxAutoBracketing: Self = Self("PentaxAutoBracketing");
354 pub const PentaxWhiteBalance: Self = Self("PentaxWhiteBalance");
355
356 pub const XmpXmpCreateDate: Self = Self("xmp:CreateDate");
358 pub const XmpXmpModifyDate: Self = Self("xmp:ModifyDate");
359 pub const XmpXmpMetadataDate: Self = Self("xmp:MetadataDate");
360 pub const XmpXmpCreatorTool: Self = Self("xmp:CreatorTool");
361 pub const XmpXmpRating: Self = Self("xmp:Rating");
362 pub const XmpXmpLabel: Self = Self("xmp:Label");
363 pub const XmpXmpNickname: Self = Self("xmp:Nickname");
364
365 pub const XmpIptcCity: Self = Self("Iptc4xmpCore:City");
367 pub const XmpIptcCountry: Self = Self("Iptc4xmpCore:Country");
368 pub const XmpIptcCountryCode: Self = Self("Iptc4xmpCore:CountryCode");
369 pub const XmpIptcState: Self = Self("Iptc4xmpCore:State");
370 pub const XmpIptcLocation: Self = Self("Iptc4xmpCore:Location");
371 pub const XmpIptcSubjectCode: Self = Self("Iptc4xmpCore:SubjectCode");
372 pub const XmpIptcIntellectualGenre: Self = Self("Iptc4xmpCore:IntellectualGenre");
373
374 pub const XmpIptcExtDigitalSourceType: Self = Self("Iptc4xmpExt:DigitalSourceType");
376 pub const XmpIptcExtDigitalGuide: Self = Self("Iptc4xmpExt:DigitalGuide");
377 pub const XmpIptcExtEvent: Self = Self("Iptc4xmpExt:Event");
378 pub const XmpIptcExtOrganisationInImage: Self = Self("Iptc4xmpExt:OrganisationInImage");
379 pub const XmpIptcExtPersonInImage: Self = Self("Iptc4xmpExt:PersonInImage");
380 pub const XmpIptcExtLocationShown: Self = Self("Iptc4xmpExt:LocationShown");
381
382 pub const XmpPhotoshopDateCreated: Self = Self("photoshop:DateCreated");
384 pub const XmpPhotoshopCity: Self = Self("photoshop:City");
385 pub const XmpPhotoshopState: Self = Self("photoshop:State");
386 pub const XmpPhotoshopCountry: Self = Self("photoshop:Country");
387 pub const XmpPhotoshopCredit: Self = Self("photoshop:Credit");
388 pub const XmpPhotoshopSource: Self = Self("photoshop:Source");
389 pub const XmpPhotoshopInstructions: Self = Self("photoshop:Instructions");
390 pub const XmpPhotoshopTransmissionReference: Self = Self("photoshop:TransmissionReference");
391 pub const XmpPhotoshopUrgency: Self = Self("photoshop:Urgency");
392 pub const XmpPhotoshopCategory: Self = Self("photoshop:Category");
393 pub const XMP_PHOTOSHOP_SUPPLEMENTAL_CATEGORIES: Self =
394 Self("photoshop:SupplementalCategories");
395 pub const XmpPhotoshopHeadline: Self = Self("photoshop:Headline");
396 pub const XmpPhotoshopCaptionWriter: Self = Self("photoshop:CaptionWriter");
397
398 pub const XmpCrsVersion: Self = Self("crs:Version");
400 pub const XmpCrsWhiteBalance: Self = Self("crs:WhiteBalance");
401 pub const XmpCrsTemperature: Self = Self("crs:Temperature");
402 pub const XmpCrsTint: Self = Self("crs:Tint");
403 pub const XmpCrsExposure: Self = Self("crs:Exposure");
404 pub const XmpCrsShadows: Self = Self("crs:Shadows");
405 pub const XmpCrsBrightness: Self = Self("crs:Brightness");
406 pub const XmpCrsContrast: Self = Self("crs:Contrast");
407 pub const XmpCrsSaturation: Self = Self("crs:Saturation");
408 pub const XmpCrsSharpness: Self = Self("crs:Sharpness");
409 pub const XmpCrsLuminanceSmoothing: Self = Self("crs:LuminanceSmoothing");
410 pub const XmpCrsColorNoiseReduction: Self = Self("crs:ColorNoiseReduction");
411 pub const XmpCrsVignetteAmount: Self = Self("crs:VignetteAmount");
412
413 pub const XmpAuxSerialNumber: Self = Self("aux:SerialNumber");
415 pub const XmpAuxLensInfo: Self = Self("aux:LensInfo");
416 pub const XmpAuxLens: Self = Self("aux:Lens");
417 pub const XmpAuxLensId: Self = Self("aux:LensID");
418 pub const XmpAuxLensSerialNumber: Self = Self("aux:LensSerialNumber");
419 pub const XmpAuxImageNumber: Self = Self("aux:ImageNumber");
420 pub const XmpAuxFlashCompensation: Self = Self("aux:FlashCompensation");
421 pub const XmpAuxFirmware: Self = Self("aux:Firmware");
422
423 pub const XmpMmDocumentId: Self = Self("xmpMM:DocumentID");
425 pub const XmpMmInstanceId: Self = Self("xmpMM:InstanceID");
426 pub const XmpMmOriginalDocumentId: Self = Self("xmpMM:OriginalDocumentID");
427 pub const XmpMmRenditionClass: Self = Self("xmpMM:RenditionClass");
428 pub const XmpMmVersionId: Self = Self("xmpMM:VersionID");
429 pub const XmpMmVersionModifier: Self = Self("xmpMM:VersionModifier");
430 pub const XmpMmHistory: Self = Self("xmpMM:History");
431 pub const XmpMmDerivedFrom: Self = Self("xmpMM:DerivedFrom");
432
433 pub const XmpTiffMake: Self = Self("tiff:Make");
435 pub const XmpTiffModel: Self = Self("tiff:Model");
436 pub const XmpTiffImageWidth: Self = Self("tiff:ImageWidth");
437 pub const XmpTiffImageHeight: Self = Self("tiff:ImageHeight");
438 pub const XmpTiffBitsPerSample: Self = Self("tiff:BitsPerSample");
439 pub const XmpTiffCompression: Self = Self("tiff:Compression");
440 pub const XmpTiffPhotometricInterpretation: Self = Self("tiff:PhotometricInterpretation");
441 pub const XmpTiffOrientation: Self = Self("tiff:Orientation");
442 pub const XmpTiffSamplesPerPixel: Self = Self("tiff:SamplesPerPixel");
443 pub const XmpTiffPlanarConfiguration: Self = Self("tiff:PlanarConfiguration");
444 pub const XmpTiffYcbcrSubSampling: Self = Self("tiff:YCbCrSubSampling");
445 pub const XmpTiffYcbcrPositioning: Self = Self("tiff:YCbCrPositioning");
446 pub const XmpTiffXResolution: Self = Self("tiff:XResolution");
447 pub const XmpTiffYResolution: Self = Self("tiff:YResolution");
448 pub const XmpTiffResolutionUnit: Self = Self("tiff:ResolutionUnit");
449
450 pub const XmpExifExposureTime: Self = Self("exif:ExposureTime");
452 pub const XmpExifFNumber: Self = Self("exif:FNumber");
453 pub const XmpExifExposureProgram: Self = Self("exif:ExposureProgram");
454 pub const XmpExifSpectralSensitivity: Self = Self("exif:SpectralSensitivity");
455 pub const XmpExifIsoSpeedRatings: Self = Self("exif:ISOSpeedRatings");
456 pub const XmpExifDateTimeOriginal: Self = Self("exif:DateTimeOriginal");
457 pub const XmpExifDateTimeDigitized: Self = Self("exif:DateTimeDigitized");
458 pub const XmpExifComponentsConfiguration: Self = Self("exif:ComponentsConfiguration");
459 pub const XmpExifCompressedBitsPerPixel: Self = Self("exif:CompressedBitsPerPixel");
460 pub const XmpExifShutterSpeedValue: Self = Self("exif:ShutterSpeedValue");
461 pub const XmpExifApertureValue: Self = Self("exif:ApertureValue");
462 pub const XmpExifBrightnessValue: Self = Self("exif:BrightnessValue");
463 pub const XmpExifExposureBiasValue: Self = Self("exif:ExposureBiasValue");
464 pub const XmpExifMaxApertureValue: Self = Self("exif:MaxApertureValue");
465 pub const XmpExifSubjectDistance: Self = Self("exif:SubjectDistance");
466 pub const XmpExifMeteringMode: Self = Self("exif:MeteringMode");
467 pub const XmpExifLightSource: Self = Self("exif:LightSource");
468 pub const XmpExifFlash: Self = Self("exif:Flash");
469 pub const XmpExifFocalLength: Self = Self("exif:FocalLength");
470 pub const XmpExifFlashEnergy: Self = Self("exif:FlashEnergy");
471 pub const XmpExifSpatialFrequencyResponse: Self = Self("exif:SpatialFrequencyResponse");
472 pub const XmpExifFocalPlaneXResolution: Self = Self("exif:FocalPlaneXResolution");
473 pub const XmpExifFocalPlaneYResolution: Self = Self("exif:FocalPlaneYResolution");
474 pub const XmpExifFocalPlaneResolutionUnit: Self = Self("exif:FocalPlaneResolutionUnit");
475 pub const XmpExifSubjectLocation: Self = Self("exif:SubjectLocation");
476 pub const XmpExifExposureIndex: Self = Self("exif:ExposureIndex");
477 pub const XmpExifSensingMethod: Self = Self("exif:SensingMethod");
478 pub const XmpExifFileSource: Self = Self("exif:FileSource");
479 pub const XmpExifSceneType: Self = Self("exif:SceneType");
480 pub const XmpExifCfaPattern: Self = Self("exif:CFAPattern");
481 pub const XmpExifCustomRendered: Self = Self("exif:CustomRendered");
482 pub const XmpExifExposureMode: Self = Self("exif:ExposureMode");
483 pub const XmpExifWhiteBalance: Self = Self("exif:WhiteBalance");
484 pub const XmpExifDigitalZoomRatio: Self = Self("exif:DigitalZoomRatio");
485 pub const XmpExifFocalLengthIn35mmFilm: Self = Self("exif:FocalLengthIn35mmFilm");
486 pub const XmpExifSceneCaptureType: Self = Self("exif:SceneCaptureType");
487 pub const XmpExifGainControl: Self = Self("exif:GainControl");
488 pub const XmpExifContrast: Self = Self("exif:Contrast");
489 pub const XmpExifSaturation: Self = Self("exif:Saturation");
490 pub const XmpExifSharpness: Self = Self("exif:Sharpness");
491 pub const XmpExifDeviceSettingDescription: Self = Self("exif:DeviceSettingDescription");
492 pub const XmpExifSubjectDistanceRange: Self = Self("exif:SubjectDistanceRange");
493 pub const XmpExifImageUniqueId: Self = Self("exif:ImageUniqueID");
494
495 pub const Duration: Self = Self("Duration");
497 pub const VideoFrameRate: Self = Self("VideoFrameRate");
498 pub const VideoFrameCount: Self = Self("VideoFrameCount");
499 pub const VideoBitRate: Self = Self("VideoBitRate");
500 pub const AudioBitRate: Self = Self("AudioBitRate");
501 pub const VideoCompression: Self = Self("VideoCompression");
502 pub const AudioCompression: Self = Self("AudioCompression");
503 pub const TrackNumber: Self = Self("TrackNumber");
504 pub const TrackType: Self = Self("TrackType");
505 pub const TrackCreateDate: Self = Self("TrackCreateDate");
506 pub const TrackModifyDate: Self = Self("TrackModifyDate");
507 pub const MediaCreateDate: Self = Self("MediaCreateDate");
508 pub const MediaModifyDate: Self = Self("MediaModifyDate");
509 pub const MediaDataSize: Self = Self("MediaDataSize");
510 pub const MediaDataOffset: Self = Self("MediaDataOffset");
511 pub const Genre: Self = Self("Genre");
512 pub const Album: Self = Self("Album");
514 pub const Year: Self = Self("Year");
515 pub const Comment: Self = Self("Comment");
516 pub const Lyrics: Self = Self("Lyrics");
517 pub const Composer: Self = Self("Composer");
518 pub const Publisher: Self = Self("Publisher");
519
520 pub const FileDescription: Self = Self("FileDescription");
522 pub const FileVersion: Self = Self("FileVersion");
523 pub const InternalVersionNumber: Self = Self("InternalVersionNumber");
524 pub const CompanyName: Self = Self("CompanyName");
525 pub const LegalCopyright: Self = Self("LegalCopyright");
526 pub const ProductName: Self = Self("ProductName");
527 pub const ProductVersion: Self = Self("ProductVersion");
528 pub const MimeEncoding: Self = Self("MIMEEncoding");
529
530 pub const CanonSerialNumberExt: Self = Self("SerialNumber");
532 pub const CanonFirmwareVersionExt: Self = Self("FirmwareVersion");
533 pub const CanonOwnerNameExt: Self = Self("OwnerName");
534 pub const CanonTimeZoneExt: Self = Self("TimeZone");
535 pub const CanonDaylightSavingExt: Self = Self("DaylightSaving");
536 pub const CanonAfMicroAdjustment: Self = Self("AFMicroadjustment");
537 pub const CanonFlashExposureCompExt: Self = Self("FlashExposureComp");
538 pub const CanonBracketModeExt: Self = Self("BracketMode");
539 pub const CanonBracketValueExt: Self = Self("BracketValue");
540 pub const CanonRawJpgQualityExt: Self = Self("RawJpgQuality");
541 pub const CanonRawJpgSizeExt: Self = Self("RawJpgSize");
542 pub const CanonNoiseReductionExt: Self = Self("NoiseReduction");
543 pub const CanonWbShiftGm: Self = Self("WBShiftGM");
544 pub const CanonWbShiftAb: Self = Self("WBShiftAB");
545 pub const CanonColorTemperatureExt: Self = Self("ColorTemperature");
546 pub const CanonLensSerialNumberExt: Self = Self("LensSerialNumber");
547 pub const CanonAfPointsInFocusExt: Self = Self("AFPointsInFocus");
548 pub const CanonAfPointsSelectedExt: Self = Self("AFPointsSelected");
549 pub const CanonAfPointsActiveExt: Self = Self("AFPointsActive");
550 pub const CanonFocusDistanceUpperExt: Self = Self("FocusDistanceUpper");
551 pub const CanonFocusDistanceLowerExt: Self = Self("FocusDistanceLower");
552 pub const CanonFlashBitsExt: Self = Self("FlashBits");
553 pub const CanonFocusContinuousExt: Self = Self("FocusContinuous");
554 pub const CanonAeSettingExt: Self = Self("AESetting");
555 pub const CanonDisplayApertureExt: Self = Self("DisplayAperture");
556 pub const CanonZoomSourceWidthExt: Self = Self("ZoomSourceWidth");
557 pub const CanonZoomTargetWidthExt: Self = Self("ZoomTargetWidth");
558 pub const CanonSpotMeteringModeExt: Self = Self("SpotMeteringMode");
559 pub const CanonPhotoEffectExt: Self = Self("PhotoEffect");
560 pub const CanonManualFlashOutputExt: Self = Self("ManualFlashOutput");
561 pub const CanonSrawQualityExt: Self = Self("SRAWQuality");
562 pub const CanonGammaExt: Self = Self("Gamma");
563 pub const CanonHighSpeedSync: Self = Self("HighSpeedSync");
564 pub const CanonAfPointsInfo: Self = Self("AFPointsInfo");
565 pub const CanonMeasureRoll: Self = Self("MeasureRoll");
566 pub const CanonMeasurePitch: Self = Self("MeasurePitch");
567 pub const CanonMeasureYaw: Self = Self("MeasureYaw");
568 pub const CanonMeasureAccelX: Self = Self("MeasureAccelX");
569 pub const CanonMeasureAccelY: Self = Self("MeasureAccelY");
570 pub const CanonMeasureAccelZ: Self = Self("MeasureAccelZ");
571 pub const CanonDateStampMode: Self = Self("DateStampMode");
572 pub const CanonMyColorsModeExt: Self = Self("MyColorsMode");
573 pub const CanonFirmwareRevision: Self = Self("FirmwareRevision");
574 pub const CanonImageUniqueIdExt: Self = Self("ImageUniqueID");
575 pub const CanonHdrSettingExt: Self = Self("HDRSetting");
576 pub const CanonMultipleExposureExt: Self = Self("MultipleExposure");
577 pub const CanonFilterEffectExt: Self = Self("FilterEffect");
578 pub const CanonToningEffectExt: Self = Self("ToningEffect");
579
580 pub const NikonWhiteBalanceFineTuneExt: Self = Self("WhiteBalanceFineTune");
582 pub const NikonColorSpaceExt: Self = Self("ColorSpace");
583 pub const NikonVignetteControlExt: Self = Self("VignetteControl");
584 pub const NikonAutoDistortionControlExt: Self = Self("AutoDistortionControl");
585 pub const NikonPictureControlExt: Self = Self("PictureControl");
586 pub const NikonHighIsoNrExt: Self = Self("HighISONoiseReduction");
587 pub const NikonLongExposureNrExt: Self = Self("LongExposureNoiseReduction");
588 pub const NikonActiveDLightingExt: Self = Self("ActiveDLighting");
589 pub const NikonMultipleExposureModeExt: Self = Self("MultipleExposureMode");
590 pub const NikonMultiExposureShotsExt: Self = Self("MultiExposureShots");
591 pub const NikonHdrExt: Self = Self("HDR");
592 pub const NikonVrModeExt: Self = Self("VRMode");
593 pub const NikonVrInfoExt: Self = Self("VRInfo");
594 pub const NikonFirmwareVersionExt: Self = Self("NikonFirmwareVersion");
595 pub const NikonAfPointsUsedExt: Self = Self("AFPointsUsed");
596 pub const NikonAfPointsInFocusExt: Self = Self("AFPointsInFocus");
597 pub const NikonAfPointsSelectedExt: Self = Self("AFPointsSelected");
598 pub const NikonSceneModeExt: Self = Self("SceneMode");
599 pub const NikonLightingTypeExt: Self = Self("LightingType");
600 pub const NikonShutterCountExt: Self = Self("ShutterCount");
601 pub const NikonElectronicShutterCountExt: Self = Self("ElectronicShutterCount");
602 pub const NikonNefBitDepthExt: Self = Self("NEFBitDepth");
603 pub const NikonOptimizationExt: Self = Self("Optimization");
604 pub const NikonSaturationExt: Self = Self("NikonSaturation");
605 pub const NikonAfAreaXPositionExt: Self = Self("AFAreaXPosition");
606 pub const NikonAfAreaYPositionExt: Self = Self("AFAreaYPosition");
607 pub const NikonPhaseDetectAfExt: Self = Self("PhaseDetectAF");
608 pub const NikonPrimaryAfPointExt: Self = Self("PrimaryAFPoint");
609 pub const NikonContrastDetectAfExt: Self = Self("ContrastDetectAF");
610 pub const NikonAfAreaPointsExt: Self = Self("AFAreaPoints");
611 pub const NikonSerialNumber2Ext: Self = Self("NikonSerialNumber2");
612 pub const NikonShutterCount2Ext: Self = Self("NikonShutterCount2");
613 pub const NikonFlashMode2Ext: Self = Self("NikonFlashMode2");
614 pub const NikonFlashControlModeExt: Self = Self("FlashControlMode");
615 pub const NikonFlashExposureComp2Ext: Self = Self("NikonFlashExposureComp2");
616 pub const NikonFlashExposureBracketValueExt: Self = Self("FlashExposureBracketValue");
617 pub const NikonExternalFlashBounceExt: Self = Self("ExternalFlashBounce");
618 pub const NikonExternalFlashZoomExt: Self = Self("ExternalFlashZoom");
619 pub const NikonExternalFlashModeExt: Self = Self("ExternalFlashMode");
620 pub const NikonExternalFlashCompensationExt: Self = Self("ExternalFlashCompensation");
621 pub const NikonCommanderChannelExt: Self = Self("CommanderChannel");
622 pub const NikonCommanderGroupAModeExt: Self = Self("CommanderGroupAMode");
623 pub const NikonCommanderGroupACompensationExt: Self = Self("CommanderGroupACompensation");
624
625 pub const SonyLensSpecExt: Self = Self("SonyLensSpec");
627 pub const SonyColorTemperatureExt: Self = Self("SonyColorTemperature");
628 pub const SonyColorCompensationFilterExt: Self = Self("SonyColorCompensationFilter");
629 pub const SonyWhiteBalanceFineTuneExt: Self = Self("SonyWhiteBalanceFineTune");
630 pub const SonyImageStabilizationStateExt: Self = Self("SonyImageStabilizationState");
631 pub const SonyDynamicRangeOptimizerExt: Self = Self("DynamicRangeOptimizer");
632 pub const SonyIntelligentAutoExt: Self = Self("IntelligentAuto");
633 pub const SonyFlashLevelExt: Self = Self("FlashLevel");
634 pub const SonyReleaseModeExt: Self = Self("ReleaseMode");
635 pub const SonySequenceNumberExt: Self = Self("SequenceNumber");
636 pub const SonyFocusStatusExt: Self = Self("FocusStatus");
637 pub const SonyAfAidedExt: Self = Self("AFAided");
638 pub const SonyAfAreaModeExt: Self = Self("AFAreaMode");
639 pub const SonyAfPointSelectedExt: Self = Self("AFPointSelected");
640 pub const SonyAfStatusExt: Self = Self("AFStatus");
641 pub const SonyLensMountExt: Self = Self("SonyLensMount");
642 pub const SonyLensFormatExt: Self = Self("SonyLensFormat");
643 pub const SonyDistortionCorrectionExt: Self = Self("DistortionCorrection");
644 pub const SONY_CHROMATIC_ABERRATION_CORRECTION_EXT: Self =
645 Self("ChromaticAberrationCorrection");
646 pub const SonyVignettingCorrectionExt: Self = Self("VignettingCorrection");
647 pub const SonyShadingCompensationExt: Self = Self("ShadingCompensation");
648 pub const SonyHdrSettingExt: Self = Self("SonyHDRSetting");
649 pub const SonyHdrAlignmentExt: Self = Self("HDRAlignment");
650 pub const SonyPanoramaDirectionExt: Self = Self("PanoramaDirection");
651 pub const SonyPanoramaAngleExt: Self = Self("PanoramaAngle");
652 pub const SonyMultiFrameNrExt: Self = Self("MultiFrameNoiseReduction");
653 pub const SonyPictureEffectExt: Self = Self("PictureEffect");
654 pub const SonySoftSkinEffectExt: Self = Self("SoftSkinEffect");
655 pub const SonyAutoPortraitFramedExt: Self = Self("AutoPortraitFramed");
656 pub const SonyAfIlluminatorExt: Self = Self("AFIlluminator");
657
658 pub const VideoTrackCreateDateExt: Self = Self("TrackCreateDate");
660 pub const VideoTrackModifyDateExt: Self = Self("TrackModifyDate");
661 pub const VideoMediaCreateDateExt: Self = Self("MediaCreateDate");
662 pub const VideoMediaModifyDateExt: Self = Self("MediaModifyDate");
663 pub const VideoHandlerTypeExt: Self = Self("HandlerType");
664 pub const VideoHandlerDescriptionExt: Self = Self("HandlerDescription");
665 pub const VideoCompressorIdExt: Self = Self("CompressorID");
666 pub const VideoBitsPerComponentExt: Self = Self("BitsPerComponent");
667 pub const VideoColorProfileExt: Self = Self("VideoColorProfile");
668 pub const VideoAudioFormatExt: Self = Self("AudioFormat");
669 pub const VideoAudioChannelsExt: Self = Self("AudioChannels");
670 pub const VideoAudioBitsPerSampleExt: Self = Self("AudioBitsPerSample");
671 pub const VideoAudioSampleRateExt: Self = Self("AudioSampleRate");
672 pub const VideoDurationExt: Self = Self("Duration");
673 pub const VideoMovieHeaderVersionExt: Self = Self("MovieHeaderVersion");
674 pub const VideoTimeScaleExt: Self = Self("TimeScale");
675 pub const VideoPreferredRateExt: Self = Self("PreferredRate");
676 pub const VideoPreferredVolumeExt: Self = Self("PreferredVolume");
677 pub const VideoPreviewTimeExt: Self = Self("PreviewTime");
678 pub const VideoPreviewDurationExt: Self = Self("PreviewDuration");
679 pub const VideoPosterTimeExt: Self = Self("PosterTime");
680 pub const VideoSelectionTimeExt: Self = Self("SelectionTime");
681 pub const VideoSelectionDurationExt: Self = Self("SelectionDuration");
682 pub const VideoCurrentTimeExt: Self = Self("CurrentTime");
683 pub const VideoNextTrackIdExt: Self = Self("NextTrackID");
684 pub const VideoTrackIdExt: Self = Self("VideoTrackID");
685 pub const VideoTrackLayerExt: Self = Self("VideoTrackLayer");
686 pub const VideoTrackVolumeExt: Self = Self("VideoTrackVolume");
687 pub const VideoTrackDurationExt: Self = Self("VideoTrackDuration");
688 pub const VideoWidthExt: Self = Self("VideoWidth");
689
690 pub const DngVersionExt: Self = Self("DNGVersion");
692 pub const DngBackwardVersionExt: Self = Self("DNGBackwardVersion");
693 pub const UniqueCameraModelExt: Self = Self("UniqueCameraModel");
694 pub const LocalizedCameraModelExt: Self = Self("LocalizedCameraModel");
695 pub const CfaPlaneColorExt: Self = Self("CFAPlaneColor");
696 pub const CfaLayoutExt: Self = Self("CFALayout");
697 pub const LinearizationTableExt: Self = Self("LinearizationTable");
698 pub const BlackLevelExt: Self = Self("BlackLevel");
699 pub const WhiteLevelExt: Self = Self("WhiteLevel");
700 pub const DefaultScaleExt: Self = Self("DefaultScale");
701 pub const BestQualityScaleExt: Self = Self("BestQualityScale");
702 pub const DefaultCropOriginExt: Self = Self("DefaultCropOrigin");
703 pub const DefaultCropSizeExt: Self = Self("DefaultCropSize");
704 pub const CalibrationIlluminant1Ext: Self = Self("CalibrationIlluminant1");
705 pub const CalibrationIlluminant2Ext: Self = Self("CalibrationIlluminant2");
706 pub const ColorMatrix1Ext: Self = Self("ColorMatrix1");
707 pub const ColorMatrix2Ext: Self = Self("ColorMatrix2");
708 pub const CameraCalibration1Ext: Self = Self("CameraCalibration1");
709 pub const CameraCalibration2Ext: Self = Self("CameraCalibration2");
710 pub const AnalogBalanceExt: Self = Self("AnalogBalance");
711
712 }
716
717impl fmt::Display for TagId {
718 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719 write!(f, "{}", self.0)
720 }
721}
722
723impl From<&'static str> for TagId {
724 fn from(name: &'static str) -> Self {
725 Self(name)
726 }
727}
728
729impl AsRef<str> for TagId {
730 fn as_ref(&self) -> &str {
731 self.0
732 }
733}
734
735#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
737#[serde(untagged)]
738pub enum TagValue {
739 String(String),
741
742 Integer(i64),
744
745 Float(f64),
747
748 Boolean(bool),
750
751 Array(Vec<TagValue>),
753
754 Binary(String),
756
757 Null,
759}
760
761impl TagValue {
762 pub fn as_string(&self) -> Option<&String> {
764 match self {
765 Self::String(s) => Some(s),
766 _ => None,
767 }
768 }
769
770 pub fn as_integer(&self) -> Option<i64> {
772 match self {
773 Self::Integer(i) => Some(*i),
774 Self::Float(f) => Some(*f as i64),
775 Self::String(s) => s.parse().ok(),
776 _ => None,
777 }
778 }
779
780 pub fn as_float(&self) -> Option<f64> {
782 match self {
783 Self::Float(f) => Some(*f),
784 Self::Integer(i) => Some(*i as f64),
785 Self::String(s) => s.parse().ok(),
786 _ => None,
787 }
788 }
789
790 pub fn as_bool(&self) -> Option<bool> {
792 match self {
793 Self::Boolean(b) => Some(*b),
794 Self::Integer(0) => Some(false),
795 Self::Integer(_) => Some(true),
796 Self::String(s) => match s.to_lowercase().as_str() {
797 "true" | "yes" | "1" | "on" => Some(true),
798 "false" | "no" | "0" | "off" => Some(false),
799 _ => None,
800 },
801 _ => None,
802 }
803 }
804
805 pub fn as_array(&self) -> Option<&Vec<TagValue>> {
807 match self {
808 Self::Array(arr) => Some(arr),
809 _ => None,
810 }
811 }
812
813 pub fn to_string_lossy(&self) -> String {
815 match self {
816 Self::String(s) => s.clone(),
817 Self::Integer(i) => i.to_string(),
818 Self::Float(f) => f.to_string(),
819 Self::Boolean(b) => b.to_string(),
820 Self::Array(arr) => {
821 let items: Vec<String> = arr.iter().map(|v| v.to_string_lossy()).collect();
822 format!("[{}]", items.join(", "))
823 }
824 Self::Binary(b) => format!("[binary: {} bytes]", b.len()),
825 Self::Null => "null".to_string(),
826 }
827 }
828
829 pub fn is_null(&self) -> bool {
831 matches!(self, Self::Null)
832 }
833}
834
835impl fmt::Display for TagValue {
836 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
837 write!(f, "{}", self.to_string_lossy())
838 }
839}
840
841#[derive(Debug, Clone, Default, Serialize, Deserialize)]
846pub struct Metadata {
847 #[serde(flatten)]
849 tags: HashMap<String, TagValue>,
850}
851
852impl Metadata {
853 pub fn new() -> Self {
855 Self::default()
856 }
857
858 pub fn get(&self, tag: &str) -> Option<&TagValue> {
860 self.tags.get(tag)
861 }
862
863 pub fn get_tag(&self, tag: TagId) -> Option<&TagValue> {
865 self.get(tag.name())
866 }
867
868 pub fn set(&mut self, tag: impl Into<String>, value: impl Into<TagValue>) {
870 self.tags.insert(tag.into(), value.into());
871 }
872
873 pub fn set_tag(&mut self, tag: TagId, value: impl Into<TagValue>) {
875 self.set(tag.name(), value);
876 }
877
878 pub fn tags(&self) -> &HashMap<String, TagValue> {
880 &self.tags
881 }
882
883 pub fn tags_mut(&mut self) -> &mut HashMap<String, TagValue> {
885 &mut self.tags
886 }
887
888 pub fn contains(&self, tag: &str) -> bool {
890 self.tags.contains_key(tag)
891 }
892
893 pub fn contains_tag(&self, tag: TagId) -> bool {
895 self.contains(tag.name())
896 }
897
898 pub fn len(&self) -> usize {
900 self.tags.len()
901 }
902
903 pub fn is_empty(&self) -> bool {
905 self.tags.is_empty()
906 }
907
908 pub fn merge(&mut self, other: Metadata) {
910 self.tags.extend(other.tags);
911 }
912
913 pub fn iter(&self) -> impl Iterator<Item = (&String, &TagValue)> {
915 self.tags.iter()
916 }
917}
918
919impl IntoIterator for Metadata {
920 type Item = (String, TagValue);
921 type IntoIter = std::collections::hash_map::IntoIter<String, TagValue>;
922
923 fn into_iter(self) -> Self::IntoIter {
924 self.tags.into_iter()
925 }
926}
927
928impl<'a> IntoIterator for &'a Metadata {
929 type Item = (&'a String, &'a TagValue);
930 type IntoIter = std::collections::hash_map::Iter<'a, String, TagValue>;
931
932 fn into_iter(self) -> Self::IntoIter {
933 self.tags.iter()
934 }
935}
936
937impl From<String> for TagValue {
939 fn from(s: String) -> Self {
940 Self::String(s)
941 }
942}
943
944impl From<&str> for TagValue {
945 fn from(s: &str) -> Self {
946 Self::String(s.to_string())
947 }
948}
949
950impl From<i64> for TagValue {
951 fn from(i: i64) -> Self {
952 Self::Integer(i)
953 }
954}
955
956impl From<i32> for TagValue {
957 fn from(i: i32) -> Self {
958 Self::Integer(i as i64)
959 }
960}
961
962impl From<f64> for TagValue {
963 fn from(f: f64) -> Self {
964 Self::Float(f)
965 }
966}
967
968impl From<f32> for TagValue {
969 fn from(f: f32) -> Self {
970 Self::Float(f as f64)
971 }
972}
973
974impl From<bool> for TagValue {
975 fn from(b: bool) -> Self {
976 Self::Boolean(b)
977 }
978}
979
980impl From<Vec<TagValue>> for TagValue {
981 fn from(arr: Vec<TagValue>) -> Self {
982 Self::Array(arr)
983 }
984}
985
986impl<T: Into<TagValue>> From<Option<T>> for TagValue {
987 fn from(opt: Option<T>) -> Self {
988 match opt {
989 Some(v) => v.into(),
990 None => Self::Null,
991 }
992 }
993}
994
995#[cfg(test)]
996mod tests {
997 use super::*;
998
999 #[test]
1000 fn test_tag_id() {
1001 assert_eq!(TagId::Make.name(), "Make");
1002 assert_eq!(TagId::Model.name(), "Model");
1003 }
1004
1005 #[test]
1006 fn test_tag_value_conversions() {
1007 let str_val: TagValue = "test".into();
1008 assert_eq!(str_val.as_string(), Some(&"test".to_string()));
1009
1010 let int_val: TagValue = 42i64.into();
1011 assert_eq!(int_val.as_integer(), Some(42));
1012
1013 let float_val: TagValue = std::f64::consts::PI.into();
1014 assert_eq!(float_val.as_float(), Some(std::f64::consts::PI));
1015
1016 let bool_val: TagValue = true.into();
1017 assert_eq!(bool_val.as_bool(), Some(true));
1018 }
1019
1020 #[test]
1021 fn test_metadata() {
1022 let mut meta = Metadata::new();
1023 meta.set("Make", "Canon");
1024 meta.set("Model", "EOS 5D");
1025
1026 assert_eq!(meta.len(), 2);
1027 assert!(meta.contains("Make"));
1028 assert_eq!(
1029 meta.get("Make"),
1030 Some(&TagValue::String("Canon".to_string()))
1031 );
1032 }
1033
1034 #[test]
1035 fn test_metadata_iteration() {
1036 let mut meta = Metadata::new();
1037 meta.set("A", 1);
1038 meta.set("B", 2);
1039
1040 let mut count = 0;
1041 for (key, _value) in &meta {
1042 count += 1;
1043 assert!(key == "A" || key == "B");
1044 }
1045 assert_eq!(count, 2);
1046 }
1047}