Preserve unknown LibVLC enum values
parent
90729e2bd4
commit
55d8bb3128
34
src/core.rs
34
src/core.rs
|
|
@ -259,6 +259,8 @@ pub fn clearerr() {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Event {
|
||||
/// An event type not known to this version of vlc-rs.
|
||||
Unknown(EventType),
|
||||
MediaMetaChanged(Meta),
|
||||
MediaSubItemAdded,
|
||||
MediaDurationChanged(i64),
|
||||
|
|
@ -325,7 +327,7 @@ pub struct EventManager<'a> {
|
|||
|
||||
impl<'a> EventManager<'a> {
|
||||
pub fn detach(&self, event_type: EventType, registered_callback: *mut c_void) {
|
||||
unsafe { sys::libvlc_event_detach(self.ptr, event_type as i32, Some(event_manager_callback), registered_callback) }
|
||||
unsafe { sys::libvlc_event_detach(self.ptr, event_type.raw() as i32, Some(event_manager_callback), registered_callback) }
|
||||
}
|
||||
|
||||
pub fn attach<F>(&self, event_type: EventType, callback: F) -> Result<*mut c_void, ()>
|
||||
|
|
@ -339,7 +341,7 @@ impl<'a> EventManager<'a> {
|
|||
|
||||
let result = unsafe{
|
||||
sys::libvlc_event_attach(
|
||||
self.ptr, event_type as i32, Some(event_manager_callback),
|
||||
self.ptr, event_type.raw() as i32, Some(event_manager_callback),
|
||||
raw)
|
||||
};
|
||||
|
||||
|
|
@ -362,7 +364,9 @@ unsafe extern "C" fn event_manager_callback(pe: *const sys::libvlc_event_t, data
|
|||
f(conv_event(pe), VLCObject{ ptr: (*pe).p_obj });
|
||||
}
|
||||
|
||||
// Convert c-style libvlc_event_t to Event
|
||||
// Convert c-style libvlc_event_t to Event.
|
||||
// Unknown event types are preserved instead of panicking so newer LibVLC
|
||||
// releases remain safe to use with this crate.
|
||||
fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
|
||||
let event_type: EventType = (unsafe{ (*pe).type_ } as u32).into();
|
||||
|
||||
|
|
@ -390,7 +394,7 @@ fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
|
|||
},
|
||||
EventType::MediaStateChanged => {
|
||||
unsafe{
|
||||
let new_state: sys::libvlc_state_t = (*pe).u.media_state_changed.new_state.try_into().unwrap();
|
||||
let new_state = (*pe).u.media_state_changed.new_state as sys::libvlc_state_t;
|
||||
Event::MediaStateChanged(new_state.into())
|
||||
}
|
||||
},
|
||||
|
|
@ -555,6 +559,27 @@ fn conv_event(pe: *const sys::libvlc_event_t) -> Event {
|
|||
Event::VlmMediaInstanceStatusError(from_cstr((*pe).u.vlm_media_event.psz_instance_name), from_cstr((*pe).u.vlm_media_event.psz_media_name))
|
||||
}
|
||||
},
|
||||
EventType::Unknown(_) => Event::Unknown(event_type),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{conv_event, Event, EventType, sys};
|
||||
use std::ptr;
|
||||
|
||||
#[test]
|
||||
fn conv_event_preserves_an_unknown_event_type() {
|
||||
let event = sys::libvlc_event_t {
|
||||
type_: 9999,
|
||||
p_obj: ptr::null_mut(),
|
||||
u: unsafe { std::mem::zeroed() },
|
||||
};
|
||||
|
||||
match conv_event(&event) {
|
||||
Event::Unknown(EventType::Unknown(9999)) => (),
|
||||
other => panic!("expected unknown event, got {:?}", other),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -579,4 +604,3 @@ impl Log {
|
|||
self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
56
src/enums.rs
56
src/enums.rs
|
|
@ -6,12 +6,29 @@ use vlc_sys as sys;
|
|||
|
||||
macro_rules! define_enum {
|
||||
($enum_name:ident, $original_type:ident; $($value:ident = $c_value:ident,)*) => {
|
||||
/// A LibVLC enumeration value.
|
||||
///
|
||||
/// Values added by a newer LibVLC release are represented by `Unknown`
|
||||
/// rather than causing a panic. Use `raw()` when passing a value back to
|
||||
/// LibVLC; this replaces casting the enum with `as`.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
#[repr(C)]
|
||||
pub enum $enum_name {
|
||||
$(
|
||||
$value = sys::$c_value as isize,
|
||||
$value,
|
||||
)*
|
||||
Unknown(sys::$original_type),
|
||||
}
|
||||
|
||||
impl $enum_name {
|
||||
/// Returns the raw LibVLC value.
|
||||
pub fn raw(self) -> sys::$original_type {
|
||||
match self {
|
||||
$(
|
||||
Self::$value => sys::$c_value,
|
||||
)*
|
||||
Self::Unknown(value) => value,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<sys::$original_type> for $enum_name {
|
||||
|
|
@ -20,7 +37,7 @@ macro_rules! define_enum {
|
|||
$(
|
||||
sys::$c_value => Self::$value,
|
||||
)*
|
||||
_ => unreachable!(),
|
||||
_ => Self::Unknown(a),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -170,3 +187,36 @@ define_enum!(
|
|||
VlmMediaInstanceStatusEnd = libvlc_event_e_libvlc_VlmMediaInstanceStatusEnd,
|
||||
VlmMediaInstanceStatusError = libvlc_event_e_libvlc_VlmMediaInstanceStatusError,
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{EventType, LogLevel, TrackType};
|
||||
use vlc_sys as sys;
|
||||
|
||||
#[test]
|
||||
fn converts_known_raw_values_to_named_variants() {
|
||||
assert_eq!(
|
||||
LogLevel::from(sys::libvlc_log_level_LIBVLC_NOTICE),
|
||||
LogLevel::Dotice,
|
||||
);
|
||||
assert_eq!(
|
||||
TrackType::from(sys::libvlc_track_type_t_libvlc_track_video),
|
||||
TrackType::Video,
|
||||
);
|
||||
assert_eq!(
|
||||
EventType::from(sys::libvlc_event_e_libvlc_MediaPlayerPlaying),
|
||||
EventType::MediaPlayerPlaying,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preserves_unknown_raw_values() {
|
||||
assert_eq!(LogLevel::from(u32::MAX), LogLevel::Unknown(u32::MAX));
|
||||
assert_eq!(TrackType::from(-42), TrackType::Unknown(-42));
|
||||
assert_eq!(
|
||||
EventType::from(u32::MAX),
|
||||
EventType::Unknown(u32::MAX),
|
||||
);
|
||||
assert_eq!(EventType::Unknown(u32::MAX).raw(), u32::MAX);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ impl Media {
|
|||
/// If the media has not yet been parsed this will return None.
|
||||
pub fn get_meta(&self, meta: Meta) -> Option<String> {
|
||||
unsafe{
|
||||
let p_str = sys::libvlc_media_get_meta(self.ptr, meta as u32);
|
||||
let p_str = sys::libvlc_media_get_meta(self.ptr, meta.raw());
|
||||
let s = from_cstr(p_str);
|
||||
sys::libvlc_free(p_str as *mut ::libc::c_void);
|
||||
s
|
||||
|
|
@ -89,7 +89,7 @@ impl Media {
|
|||
/// (This function will not save the meta, call save_meta in order to save the meta)
|
||||
pub fn set_meta(&self, meta: Meta, value: &str) {
|
||||
unsafe{
|
||||
sys::libvlc_media_set_meta(self.ptr, meta as u32, to_cstr(value).as_ptr());
|
||||
sys::libvlc_media_set_meta(self.ptr, meta.raw(), to_cstr(value).as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -236,4 +236,3 @@ pub struct VideoTrack {
|
|||
pub struct SubtitleTrack {
|
||||
pub encoding: Option<String>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -311,7 +311,7 @@ impl MediaPlayer {
|
|||
|
||||
/// Set if, and how, the video title will be shown when media is played.
|
||||
pub fn set_video_title_display(&self, position: Position, timeout: u32) {
|
||||
unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position as i32, timeout); }
|
||||
unsafe{ sys::libvlc_media_player_set_video_title_display(self.ptr, position.raw(), timeout); }
|
||||
}
|
||||
|
||||
/// Returns raw pointer
|
||||
|
|
@ -367,4 +367,3 @@ pub struct TrackDescription {
|
|||
pub id: i32,
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,15 +110,15 @@ impl MediaPlayerVideoEx for MediaPlayer {
|
|||
}
|
||||
}
|
||||
fn get_adjust_int(&self, option: VideoAdjustOption) -> i32 {
|
||||
unsafe{ sys::libvlc_video_get_adjust_int(self.ptr, option as u32) }
|
||||
unsafe{ sys::libvlc_video_get_adjust_int(self.ptr, option.raw()) }
|
||||
}
|
||||
fn set_adjust_int(&self, option: VideoAdjustOption, value: i32) {
|
||||
unsafe{ sys::libvlc_video_set_adjust_int(self.ptr, option as u32, value); }
|
||||
unsafe{ sys::libvlc_video_set_adjust_int(self.ptr, option.raw(), value); }
|
||||
}
|
||||
fn get_adjust_float(&self, option: VideoAdjustOption) -> f32 {
|
||||
unsafe{ sys::libvlc_video_get_adjust_float(self.ptr, option as u32) }
|
||||
unsafe{ sys::libvlc_video_get_adjust_float(self.ptr, option.raw()) }
|
||||
}
|
||||
fn set_adjust_float(&self, option: VideoAdjustOption, value: f32) {
|
||||
unsafe{ sys::libvlc_video_set_adjust_float(self.ptr, option as u32, value); }
|
||||
unsafe{ sys::libvlc_video_set_adjust_float(self.ptr, option.raw(), value); }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue