Make the Unknown field optional
Several other uses that currently rely on num-traits for conversion have no Unknown representation. Thus, the converter now outputs only known variants or an error and the exposing function then can put the error value into an Unknown variant instead.
This commit is contained in:
1 parent
ffdeb62b9f
commit
f80f4a06d5
2 files changed
+30
-13
No files matched your search
+29
-12
@@ -13,7 +13,7 @@ macro_rules! tags {
|
|||||||
{
|
{
|
||||||
// Permit arbitrary meta items, which include documentation.
|
// Permit arbitrary meta items, which include documentation.
|
||||||
$( #[$enum_attr:meta] )*
|
$( #[$enum_attr:meta] )*
|
||||||
pub enum $name:ident($ty:ty) {
|
pub enum $name:ident($ty:ty) $(unknown($unknown_doc:literal))* {
|
||||||
// Each of the `Name = Val,` permitting documentation.
|
// Each of the `Name = Val,` permitting documentation.
|
||||||
$($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
|
$($(#[$ident_attr:meta])* $tag:ident = $val:expr,)*
|
||||||
}
|
}
|
||||||
@@ -22,22 +22,28 @@ macro_rules! tags {
|
|||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||||
pub enum $name {
|
pub enum $name {
|
||||||
$($(#[$ident_attr])* $tag,)*
|
$($(#[$ident_attr])* $tag,)*
|
||||||
Unknown($ty),
|
// FIXME: switch to non_exhaustive once stabilized and compiler requirement new enough
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
__NonExhaustive,
|
__NonExhaustive,
|
||||||
|
$(
|
||||||
|
#[doc = $unknown_doc]
|
||||||
|
Unknown($ty),
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $name {
|
impl $name {
|
||||||
fn __from_inner_type(n: u16) -> Self {
|
#[inline(always)]
|
||||||
$(if n == $val { $name::$tag } else)* {
|
fn __from_inner_type(n: u16) -> Result<Self, $ty> {
|
||||||
$name::Unknown(n)
|
$(if n == $val { Ok($name::$tag) } else)* {
|
||||||
|
Err(n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
fn __to_inner_type(&self) -> u16 {
|
fn __to_inner_type(&self) -> u16 {
|
||||||
match *self {
|
match *self {
|
||||||
$( $name::$tag => $val, )*
|
$( $name::$tag => $val, )*
|
||||||
$name::Unknown(n) => n,
|
$( $name::Unknown(n) => { $unknown_doc; n }, )*
|
||||||
$name::__NonExhaustive => unreachable!(),
|
$name::__NonExhaustive => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -48,7 +54,7 @@ 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
|
/// TIFF tags
|
||||||
pub enum Tag(u16) {
|
pub enum Tag(u16) unknown("A private or extension tag") {
|
||||||
// Baseline tags:
|
// Baseline tags:
|
||||||
Artist = 315,
|
Artist = 315,
|
||||||
// grayscale images PhotometricInterpretation 1 or 3
|
// grayscale images PhotometricInterpretation 1 or 3
|
||||||
@@ -95,7 +101,7 @@ pub enum Tag(u16) {
|
|||||||
|
|
||||||
impl Tag {
|
impl Tag {
|
||||||
pub fn from_u16(val: u16) -> Self {
|
pub fn from_u16(val: u16) -> Self {
|
||||||
Self::__from_inner_type(val)
|
Self::__from_inner_type(val).unwrap_or_else(Tag::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_u16(&self) -> u16 {
|
pub fn to_u16(&self) -> u16 {
|
||||||
@@ -103,8 +109,9 @@ impl Tag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, FromPrimitive)]
|
tags! {
|
||||||
pub enum Type {
|
/// The type of an IFD entry (a 2 byte field).
|
||||||
|
pub enum Type(u16) {
|
||||||
BYTE = 1,
|
BYTE = 1,
|
||||||
ASCII = 2,
|
ASCII = 2,
|
||||||
SHORT = 3,
|
SHORT = 3,
|
||||||
@@ -114,9 +121,19 @@ pub enum Type {
|
|||||||
SSHORT = 8,
|
SSHORT = 8,
|
||||||
SLONG = 9,
|
SLONG = 9,
|
||||||
SRATIONAL = 10,
|
SRATIONAL = 10,
|
||||||
#[doc(hidden)] // Do not match against this.
|
|
||||||
__NonExhaustive,
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Type {
|
||||||
|
pub fn from_u16(val: u16) -> Option<Self> {
|
||||||
|
Self::__from_inner_type(val).ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_u16(&self) -> u16 {
|
||||||
|
Self::__to_inner_type(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[allow(unused_qualifications)]
|
#[allow(unused_qualifications)]
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|||||||
+1
-1
@@ -454,7 +454,7 @@ impl<R: Read + Seek> Decoder<R> {
|
|||||||
// Value 4 bytes either a pointer the value itself
|
// Value 4 bytes either a pointer the value itself
|
||||||
fn read_entry(&mut self) -> TiffResult<Option<(ifd::Tag, ifd::Entry)>> {
|
fn read_entry(&mut self) -> TiffResult<Option<(ifd::Tag, ifd::Entry)>> {
|
||||||
let tag = ifd::Tag::from_u16(self.read_short()?);
|
let tag = ifd::Tag::from_u16(self.read_short()?);
|
||||||
let type_: ifd::Type = match FromPrimitive::from_u16(self.read_short()?) {
|
let type_ = match ifd::Type::from_u16(self.read_short()?) {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
None => {
|
None => {
|
||||||
// Unknown type. Skip this entry according to spec.
|
// Unknown type. Skip this entry according to spec.
|
||||||
|
|||||||
Reference in new issue
Block a user