1#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
2pub struct TagIfd {
3 pub tag: Tag,
4 pub ifd: Ifd,
5}
6
7impl TagIfd {
8 pub fn new(tag: Tag, ifd: Ifd) -> Self {
9 Self { tag, ifd }
10 }
11}
12
13impl<T: Field> From<T> for TagIfd {
14 fn from(_value: T) -> Self {
15 TagIfd {
16 tag: T::TAG,
17 ifd: T::IFD,
18 }
19 }
20}
21
22pub trait Field {
23 const NAME: &'static str;
24 const TAG: Tag;
25 const IFD: Ifd;
26 const IFD_ENTRY: Option<Ifd> = None;
27}
28
29pub fn lookup_tag_name(tagifd: TagIfd) -> Option<&'static str> {
30 crate::field::TAG_NAMES
31 .get(&(tagifd.tag.0, tagifd.ifd))
32 .copied()
33}
34
35#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, PartialOrd, Ord)]
36pub struct Tag(pub u16);
37
38impl Tag {
39 pub const MAKER_NOTE: Self = Self(0x927C);
40
41 pub const EXIF_IFD_POINTER: Self = Self(0x8769);
42 pub const GPS_INFO_IFD_POINTER: Self = Self(0x8825);
43 pub const INTEROPERABILITY_IFD_POINTER: Self = Self(0xA005);
44
45 pub fn exif_specific_ifd(&self) -> Option<Ifd> {
49 match *self {
50 Self::EXIF_IFD_POINTER => Some(Ifd::Exif),
51 Self::GPS_INFO_IFD_POINTER => Some(Ifd::Gps),
52 Self::INTEROPERABILITY_IFD_POINTER => Some(Ifd::Interoperability),
53 _ => None,
54 }
55 }
56
57 pub fn is_exif_specific_ifd(&self) -> bool {
58 self.exif_specific_ifd().is_some()
59 }
60}
61
62#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
64pub enum Ifd {
65 Primary,
66 Thumbnail,
67 Exif,
68 Gps,
69 Interoperability,
70 MakerNote,
71}