Skip to content

Commit 66af2c3

Browse files
authored
ndk/media_error: Flatten MediaStatus and MediaError with catch_all (#432)
Since bumping our MSRV to 1.66 `num_enum` provides a `catch_all` variant which we can use to store yet-unknown or yet-unmapped error codes, rather than having them in a secondary `enum` which derives `thiserror`. This also allows us to get rid of a manual `match` statement, which can be (but could already have been...) generated by `num_enum` via `TryFromPrimitive` before.
1 parent b2daffa commit 66af2c3

File tree

3 files changed

+24
-54
lines changed

3 files changed

+24
-54
lines changed

ndk/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
- bitmap: Add `try_format()` to `AndroidBitmapInfo` to handle unexpected formats without panicking. (#395)
1313
- Add `Font` bindings. (#397)
1414
- **Breaking:** Upgrade `num_enum` crate from `0.5.1` to `0.7`. (#398, #419)
15-
- **Breaking:** Renamed and moved "`media`" error types and helpers to a new `media_error` module. (#399)
15+
- **Breaking:** Renamed, moved and flattened "`media`" error types and helpers to a new `media_error` module. (#399, #432)
1616
- **Breaking:** media_codec: Wrap common dequeued-buffer status codes in enum. (#401)
1717
- **Breaking:** media_codec: Return `MaybeUninit` bytes in `buffer_mut()`. (#403)
1818
- native_window: Add `lock()` to blit raw pixel data. (#404)

ndk/src/media/image_reader.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! [`AImage`]: https://developer.android.com/ndk/reference/group/media#aimage
55
#![cfg(feature = "api-level-24")]
66

7-
use crate::media_error::{construct, construct_never_null, MediaError, MediaStatus, Result};
7+
use crate::media_error::{construct, construct_never_null, MediaError, Result};
88
use crate::native_window::NativeWindow;
99
use crate::utils::abort_on_panic;
1010
use num_enum::{IntoPrimitive, TryFromPrimitive};
@@ -208,7 +208,7 @@ impl ImageReader {
208208

209209
match res {
210210
Ok(inner) => Ok(Some(Image { inner })),
211-
Err(MediaError::MediaStatus(MediaStatus::ImgreaderNoBufferAvailable)) => Ok(None),
211+
Err(MediaError::ImgreaderNoBufferAvailable) => Ok(None),
212212
Err(e) => Err(e),
213213
}
214214
}
@@ -240,7 +240,7 @@ impl ImageReader {
240240
ffi::AImageReader_acquireLatestImage(self.as_ptr(), res)
241241
});
242242

243-
if let Err(MediaError::MediaStatus(MediaStatus::ImgreaderNoBufferAvailable)) = res {
243+
if let Err(MediaError::ImgreaderNoBufferAvailable) = res {
244244
return Ok(None);
245245
}
246246

ndk/src/media_error.rs

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
// complex going forward. Allow them to be unused when compiling with certain feature combinations.
77
#![allow(dead_code)]
88

9-
use std::{convert::TryInto, mem::MaybeUninit, ptr::NonNull};
9+
use std::{fmt, mem::MaybeUninit, ptr::NonNull};
1010

11-
use thiserror::Error;
11+
use num_enum::{FromPrimitive, IntoPrimitive};
1212

1313
pub type Result<T, E = MediaError> = std::result::Result<T, E>;
1414

1515
/// Media Status codes for [`media_status_t`](https://developer.android.com/ndk/reference/group/media#group___media_1ga009a49041fe39f7bdc6d8b5cddbe760c)
1616
#[repr(i32)]
17-
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
18-
pub enum MediaStatus {
17+
#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, IntoPrimitive)]
18+
#[non_exhaustive]
19+
pub enum MediaError {
1920
CodecErrorInsufficientResource = ffi::media_status_t::AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE.0,
2021
CodecErrorReclaimed = ffi::media_status_t::AMEDIACODEC_ERROR_RECLAIMED.0,
2122
ErrorUnknown = ffi::media_status_t::AMEDIA_ERROR_UNKNOWN.0,
@@ -43,57 +44,29 @@ pub enum MediaStatus {
4344
ImgreaderCannotLockImage = ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE.0,
4445
ImgreaderCannotUnlockImage = ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE.0,
4546
ImgreaderImageNotLocked = ffi::media_status_t::AMEDIA_IMGREADER_IMAGE_NOT_LOCKED.0,
47+
// Use the OK discriminant, assuming no-one calls `as i32` and only uses the generated `From` implementation via `IntoPrimitive`
48+
#[num_enum(catch_all)]
49+
Unknown(i32) = 0,
4650
}
4751

48-
/// Media Status codes in [`MediaStatus`] or raw [`ffi::media_status_t`] if unknown.
49-
#[derive(Debug, Error)]
50-
pub enum MediaError {
51-
#[error("Media Status {0:?}")]
52-
MediaStatus(MediaStatus),
53-
#[error("Unknown Media Status {0:?}")]
54-
UnknownStatus(ffi::media_status_t),
52+
impl fmt::Display for MediaError {
53+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54+
write!(f, "{:?}", self)
55+
}
5556
}
5657

58+
impl std::error::Error for MediaError {}
59+
5760
impl MediaError {
5861
/// Returns [`Ok`] on [`ffi::media_status_t::AMEDIA_OK`], [`Err`] otherwise (including positive
5962
/// values).
6063
///
6164
/// Note that some known error codes (currently only for `AMediaCodec`) are positive.
6265
pub(crate) fn from_status(status: ffi::media_status_t) -> Result<()> {
63-
use MediaStatus::*;
64-
Err(Self::MediaStatus(match status {
65-
ffi::media_status_t::AMEDIA_OK => return Ok(()),
66-
ffi::media_status_t::AMEDIACODEC_ERROR_INSUFFICIENT_RESOURCE => {
67-
CodecErrorInsufficientResource
68-
}
69-
ffi::media_status_t::AMEDIACODEC_ERROR_RECLAIMED => CodecErrorReclaimed,
70-
ffi::media_status_t::AMEDIA_ERROR_UNKNOWN => ErrorUnknown,
71-
ffi::media_status_t::AMEDIA_ERROR_MALFORMED => ErrorMalformed,
72-
ffi::media_status_t::AMEDIA_ERROR_UNSUPPORTED => ErrorUnsupported,
73-
ffi::media_status_t::AMEDIA_ERROR_INVALID_OBJECT => ErrorInvalidObject,
74-
ffi::media_status_t::AMEDIA_ERROR_INVALID_PARAMETER => ErrorInvalidParameter,
75-
ffi::media_status_t::AMEDIA_ERROR_INVALID_OPERATION => ErrorInvalidOperation,
76-
ffi::media_status_t::AMEDIA_ERROR_END_OF_STREAM => ErrorEndOfStream,
77-
ffi::media_status_t::AMEDIA_ERROR_IO => ErrorIo,
78-
ffi::media_status_t::AMEDIA_ERROR_WOULD_BLOCK => ErrorWouldBlock,
79-
ffi::media_status_t::AMEDIA_DRM_ERROR_BASE => DrmErrorBase,
80-
ffi::media_status_t::AMEDIA_DRM_NOT_PROVISIONED => DrmNotProvisioned,
81-
ffi::media_status_t::AMEDIA_DRM_RESOURCE_BUSY => DrmResourceBusy,
82-
ffi::media_status_t::AMEDIA_DRM_DEVICE_REVOKED => DrmDeviceRevoked,
83-
ffi::media_status_t::AMEDIA_DRM_SHORT_BUFFER => DrmShortBuffer,
84-
ffi::media_status_t::AMEDIA_DRM_SESSION_NOT_OPENED => DrmSessionNotOpened,
85-
ffi::media_status_t::AMEDIA_DRM_TAMPER_DETECTED => DrmTamperDetected,
86-
ffi::media_status_t::AMEDIA_DRM_VERIFY_FAILED => DrmVerifyFailed,
87-
ffi::media_status_t::AMEDIA_DRM_NEED_KEY => DrmNeedKey,
88-
ffi::media_status_t::AMEDIA_DRM_LICENSE_EXPIRED => DrmLicenseExpired,
89-
ffi::media_status_t::AMEDIA_IMGREADER_ERROR_BASE => ImgreaderErrorBase,
90-
ffi::media_status_t::AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE => ImgreaderNoBufferAvailable,
91-
ffi::media_status_t::AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED => ImgreaderMaxImagesAcquired,
92-
ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE => ImgreaderCannotLockImage,
93-
ffi::media_status_t::AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE => ImgreaderCannotUnlockImage,
94-
ffi::media_status_t::AMEDIA_IMGREADER_IMAGE_NOT_LOCKED => ImgreaderImageNotLocked,
95-
_ => return Err(MediaError::UnknownStatus(status)),
96-
}))
66+
match status {
67+
ffi::media_status_t::AMEDIA_OK => Ok(()),
68+
x => Err(Self::from(x.0)),
69+
}
9770
}
9871

9972
/// Returns the original value in [`Ok`] if it is not negative, [`Err`] otherwise.
@@ -106,12 +79,9 @@ impl MediaError {
10679
if v >= 0 {
10780
Ok(value)
10881
} else {
109-
Err(Self::from_status(ffi::media_status_t(
110-
v.try_into().expect("Error code out of bounds"),
82+
Err(Self::from(
83+
i32::try_from(v).expect("Error code out of bounds"),
11184
))
112-
// This panic should be unreachable: the only case where Ok is returned is in
113-
// AMEDIA_OK=0 whose value is already handled above.
114-
.unwrap_err())
11585
}
11686
}
11787
}

0 commit comments

Comments
 (0)