Skip to main content

exiftool_rs_wrapper/
types.rs

1//! 核心类型定义
2
3// 允许非标准命名(与 ExifTool 保持一致)
4#![allow(non_upper_case_globals)]
5
6use serde::{Deserialize, Serialize};
7use std::collections::HashMap;
8use std::fmt;
9
10/// 标签标识符 - 提供类型安全的标签访问
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12pub struct TagId(pub &'static str);
13
14impl TagId {
15    /// 创建新的标签标识符
16    pub const fn new(name: &'static str) -> Self {
17        Self(name)
18    }
19
20    /// 获取标签名称
21    pub fn name(&self) -> &str {
22        self.0
23    }
24
25    // === 常用 EXIF 标签 ===
26    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    // === 相机设置标签 ===
43    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    // === GPS 标签 ===
88    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    // === 文件信息标签 ===
121    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    // === IPTC 标签 ===
149    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    // === XMP 标签 ( Dublin Core ) ===
196    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    // === XMP 标签 ( XMP Rights ) ===
213    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    // === 图像尺寸标签 ===
219    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    // === 缩略图标签 ===
228    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    // === 色彩空间标签 ===
237    pub const ColorSpace: Self = Self("ColorSpace");
238    pub const Gamma: Self = Self("Gamma");
239
240    // === 复合标签 (Composite) ===
241    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    // === Canon MakerNotes ===
253    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    // === Nikon MakerNotes ===
275    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    // === Sony MakerNotes ===
293    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    // === Fuji MakerNotes ===
311    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    // === Panasonic MakerNotes ===
324    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    // === Olympus MakerNotes ===
335    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    // === Pentax MakerNotes ===
347    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    // === 更多 XMP 命名空间 ===
357    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    // === XMP IPTC Core ===
366    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    // === XMP IPTC Extension ===
375    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    // === XMP Photoshop ===
383    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    // === XMP Camera Raw ===
399    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    // === XMP AUX (Camera Raw Schema) ===
414    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    // === XMP MM (Media Management) ===
424    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    // === XMP TIFF ===
434    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    // === XMP EXIF ===
451    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    // === 视频特定标签 ===
496    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    // ARTIST 已在上面定义
513    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    // === 更多文件信息 ===
521    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    // === 扩展标签: 更多 Canon MakerNotes (50个) ===
531    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    // === 扩展标签: 更多 Nikon MakerNotes (50个) ===
581    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    // === 扩展标签: 更多 Sony MakerNotes (30个) ===
626    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    // === 扩展标签: 视频元数据 (30个) ===
659    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    // === 扩展标签: RAW/DNG (20个) ===
691    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    // === Other Tags (16609 tags) - feature = "other" ===
713    // Note: Full other.rs integration in progress
714    // All 16609 other tags available in src/tags/other.rs
715}
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/// 标签值类型 - 支持 ExifTool 返回的所有数据类型
736#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
737#[serde(untagged)]
738pub enum TagValue {
739    /// 字符串值
740    String(String),
741
742    /// 整数值
743    Integer(i64),
744
745    /// 浮点数值
746    Float(f64),
747
748    /// 布尔值
749    Boolean(bool),
750
751    /// 数组值
752    Array(Vec<TagValue>),
753
754    /// 二进制数据(Base64 编码)
755    Binary(String),
756
757    /// 空值
758    Null,
759}
760
761impl TagValue {
762    /// 尝试获取字符串值
763    pub fn as_string(&self) -> Option<&String> {
764        match self {
765            Self::String(s) => Some(s),
766            _ => None,
767        }
768    }
769
770    /// 尝试获取整数值
771    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    /// 尝试获取浮点数值
781    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    /// 尝试获取布尔值
791    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    /// 尝试获取数组
806    pub fn as_array(&self) -> Option<&Vec<TagValue>> {
807        match self {
808            Self::Array(arr) => Some(arr),
809            _ => None,
810        }
811    }
812
813    /// 转换为字符串表示
814    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    /// 检查是否为空
830    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/// 元数据结构
842///
843/// ExifTool 的 `-json -G` 输出中,分组信息已通过键名中的 `Group:Tag` 格式体现,
844/// 因此不再单独维护 groups 字段。
845#[derive(Debug, Clone, Default, Serialize, Deserialize)]
846pub struct Metadata {
847    /// 顶层标签
848    #[serde(flatten)]
849    tags: HashMap<String, TagValue>,
850}
851
852impl Metadata {
853    /// 创建空的元数据
854    pub fn new() -> Self {
855        Self::default()
856    }
857
858    /// 获取标签值
859    pub fn get(&self, tag: &str) -> Option<&TagValue> {
860        self.tags.get(tag)
861    }
862
863    /// 获取标签值(使用 TagId)
864    pub fn get_tag(&self, tag: TagId) -> Option<&TagValue> {
865        self.get(tag.name())
866    }
867
868    /// 设置标签值
869    pub fn set(&mut self, tag: impl Into<String>, value: impl Into<TagValue>) {
870        self.tags.insert(tag.into(), value.into());
871    }
872
873    /// 设置标签值(使用 TagId)
874    pub fn set_tag(&mut self, tag: TagId, value: impl Into<TagValue>) {
875        self.set(tag.name(), value);
876    }
877
878    /// 获取所有标签
879    pub fn tags(&self) -> &HashMap<String, TagValue> {
880        &self.tags
881    }
882
883    /// 获取所有标签(可变)
884    pub fn tags_mut(&mut self) -> &mut HashMap<String, TagValue> {
885        &mut self.tags
886    }
887
888    /// 检查是否包含标签
889    pub fn contains(&self, tag: &str) -> bool {
890        self.tags.contains_key(tag)
891    }
892
893    /// 检查是否包含标签(使用 TagId)
894    pub fn contains_tag(&self, tag: TagId) -> bool {
895        self.contains(tag.name())
896    }
897
898    /// 获取标签数量
899    pub fn len(&self) -> usize {
900        self.tags.len()
901    }
902
903    /// 检查是否为空
904    pub fn is_empty(&self) -> bool {
905        self.tags.is_empty()
906    }
907
908    /// 合并另一个元数据
909    pub fn merge(&mut self, other: Metadata) {
910        self.tags.extend(other.tags);
911    }
912
913    /// 遍历所有标签
914    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
937// 类型转换实现
938impl 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}