Rework the tag macro to make it reusable

Factor out parts that are unique to instantiations such as the name, the
documentation, the underlying type, the public conversion methods.

Also adds the ability to document individual items and remodels the
syntax to more closely resemble ordinary enum definitions.
This commit is contained in:
Andreas Molzer committed 2019-11-01 01:35:18 +01:00
1 parent 6aea7b33c1
commit ffdeb62b9f
1 file changed
+79 -54
+79 -54
View File
@@ -10,27 +10,35 @@ use {TiffError, TiffFormatError, TiffResult, TiffUnsupportedError};
use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational}; use self::Value::{Ascii, List, Rational, Unsigned, Signed, SRational};
macro_rules! tags { macro_rules! tags {
{$( {
$tag:ident // Permit arbitrary meta items, which include documentation.
$val:expr; $( #[$enum_attr:meta] )*
)*} => { pub enum $name:ident($ty:ty) {
// Each of the `Name = Val,` permitting documentation.
/// TIFF tag $($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum Tag {
$($tag,)*
Unknown(u16)
} }
impl Tag { } => {
pub fn from_u16(n: u16) -> Tag { $( #[$enum_attr] )*
$(if n == $val { Tag::$tag } else)* { #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
Tag::Unknown(n) pub enum $name {
$($(#[$ident_attr])* $tag,)*
Unknown($ty),
#[doc(hidden)]
__NonExhaustive,
}
impl $name {
fn __from_inner_type(n: u16) -> Self {
$(if n == $val { $name::$tag } else)* {
$name::Unknown(n)
} }
} }
pub fn to_u16(&self) -> u16 {
fn __to_inner_type(&self) -> u16 {
match *self { match *self {
$( Tag::$tag => $val, )* $( $name::$tag => $val, )*
Tag::Unknown(n) => n, $name::Unknown(n) => n,
$name::__NonExhaustive => unreachable!(),
} }
} }
} }
@@ -39,47 +47,60 @@ macro_rules! tags {
// Note: These tags appear in the order they are mentioned in the TIFF reference // Note: These tags appear in the order they are mentioned in the TIFF reference
tags! { tags! {
/// TIFF tags
pub enum Tag(u16) {
// Baseline tags: // Baseline tags:
Artist 315; Artist = 315,
// grayscale images PhotometricInterpretation 1 or 3 // grayscale images PhotometricInterpretation 1 or 3
BitsPerSample 258; BitsPerSample = 258,
CellLength 265; // TODO add support CellLength = 265, // TODO add support
CellWidth 264; // TODO add support CellWidth = 264, // TODO add support
// palette-color images (PhotometricInterpretation 3) // palette-color images (PhotometricInterpretation 3)
ColorMap 320; // TODO add support ColorMap = 320, // TODO add support
Compression 259; // TODO add support for 2 and 32773 Compression = 259, // TODO add support for 2 and 32773
Copyright 33_432; Copyright = 33_432,
DateTime 306; DateTime = 306,
ExtraSamples 338; // TODO add support ExtraSamples = 338, // TODO add support
FillOrder 266; // TODO add support FillOrder = 266, // TODO add support
FreeByteCounts 289; // TODO add support FreeByteCounts = 289, // TODO add support
FreeOffsets 288; // TODO add support FreeOffsets = 288, // TODO add support
GrayResponseCurve 291; // TODO add support GrayResponseCurve = 291, // TODO add support
GrayResponseUnit 290; // TODO add support GrayResponseUnit = 290, // TODO add support
HostComputer 316; HostComputer = 316,
ImageDescription 270; ImageDescription = 270,
ImageLength 257; ImageLength = 257,
ImageWidth 256; ImageWidth = 256,
Make 271; Make = 271,
MaxSampleValue 281; // TODO add support MaxSampleValue = 281, // TODO add support
MinSampleValue 280; // TODO add support MinSampleValue = 280, // TODO add support
Model 272; Model = 272,
NewSubfileType 254; // TODO add support NewSubfileType = 254, // TODO add support
Orientation 274; // TODO add support Orientation = 274, // TODO add support
PhotometricInterpretation 262; PhotometricInterpretation = 262,
PlanarConfiguration 284; PlanarConfiguration = 284,
ResolutionUnit 296; // TODO add support ResolutionUnit = 296, // TODO add support
RowsPerStrip 278; RowsPerStrip = 278,
SamplesPerPixel 277; SamplesPerPixel = 277,
Software 305; Software = 305,
StripByteCounts 279; StripByteCounts = 279,
StripOffsets 273; StripOffsets = 273,
SubfileType 255; // TODO add support SubfileType = 255, // TODO add support
Threshholding 263; // TODO add support Threshholding = 263, // TODO add support
XResolution 282; XResolution = 282,
YResolution 283; YResolution = 283,
// Advanced tags // Advanced tags
Predictor 317; Predictor = 317,
}
}
impl Tag {
pub fn from_u16(val: u16) -> Self {
Self::__from_inner_type(val)
}
pub fn to_u16(&self) -> u16 {
Self::__to_inner_type(self)
}
} }
#[derive(Clone, Copy, Debug, FromPrimitive)] #[derive(Clone, Copy, Debug, FromPrimitive)]
@@ -93,6 +114,8 @@ pub enum Type {
SSHORT = 8, SSHORT = 8,
SLONG = 9, SLONG = 9,
SRATIONAL = 10, SRATIONAL = 10,
#[doc(hidden)] // Do not match against this.
__NonExhaustive,
} }
#[allow(unused_qualifications)] #[allow(unused_qualifications)]
@@ -104,6 +127,8 @@ pub enum Value {
Rational(u32, u32), Rational(u32, u32),
SRational(i32, i32), SRational(i32, i32),
Ascii(String), Ascii(String),
#[doc(hidden)] // Do not match against this.
__NonExhaustive,
} }
impl Value { impl Value {