use TryFrom instead of From for downcasting because it could fail

This commit is contained in:
Tianyi 2020-10-27 22:55:45 +00:00
parent 0418d98955
commit 6e10a0b93d
6 changed files with 27 additions and 13 deletions

Binary file not shown.

View file

@ -1,10 +1,3 @@
#[macro_export]
macro_rules! downcast {
($tag:expr, $type:ty) => {
$tag.into_any().downcast_ref::<$type>().unwrap().into()
};
}
#[macro_export]
macro_rules! impl_audiotag_config {
($tag:ident) => {
@ -66,9 +59,25 @@ macro_rules! impl_tag {
}
}
impl From<Box<dyn AudioTag>> for $inner {
fn from(inp: Box<dyn AudioTag>) -> Self {
downcast!(inp, $tag)
// downcasting
// impl std::convert::TryFrom<Box<dyn AudioTag>> for &$tag {
// type Error = crate::Error;
// fn try_from(inp: Box<dyn AudioTag>) -> crate::Result<Self> {
// inp.into_any()
// .downcast_ref::<$tag>()
// .ok_or(crate::Error::DowncastError)
// }
// }
impl std::convert::TryFrom<Box<dyn AudioTag>> for $inner {
type Error = crate::Error;
fn try_from(inp: Box<dyn AudioTag>) -> crate::Result<Self> {
let t: &$tag = inp
.into_any()
.downcast_ref::<$tag>()
.ok_or(crate::Error::DowncastError)?;
Ok(t.into())
}
}
};

View file

@ -21,7 +21,9 @@ fn main() {
.expect("Fail to read!");
assert_eq!(id3tag_reload.title(), Some("title from metaflac::Tag"));
let mut id3tag_inner: id3::Tag = id3tag_reload.into();
let mut id3tag_inner: id3::Tag = id3tag_reload.try_into().unwrap();
// this would fail if `id3tag_reload` isn't really a id3 tag.
let timestamp = id3::Timestamp {
year: 2013,
month: Some(2u8),

View file

@ -1,6 +1,9 @@
/// Error types that could occur in this library.
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("")]
DowncastError,
/// Fail to guess the metadata format based on the file extension.
#[error("Fail to guess the metadata format based on the file extension.")]
UnknownFileExtension(String),

View file

@ -53,7 +53,7 @@ use std::convert::From;
use std::fs::File;
use std::path::Path;
use std::convert::{TryFrom, TryInto};
pub use std::convert::{TryFrom, TryInto};
#[derive(Clone, Copy, Debug)]
pub enum TagType {

View file

@ -17,7 +17,7 @@ fn test_inner() {
.expect("Fail to read!");
assert_eq!(id3tag_reload.title(), Some("title from metaflac::Tag"));
let mut id3tag_inner: id3::Tag = id3tag_reload.into();
let mut id3tag_inner: id3::Tag = id3tag_reload.try_into().unwrap();
let timestamp = id3::Timestamp {
year: 2013,
month: Some(2u8),