Make the UriError a bit nicer

This commit is contained in:
Sebastian Dröge 2016-08-25 00:47:56 +03:00
parent df50617c87
commit 9ae934e48a
6 changed files with 81 additions and 33 deletions

View file

@ -66,7 +66,7 @@ impl Sink for FileSink {
&self.controller &self.controller
} }
fn set_uri(&self, uri: Option<Url>) -> Result<(), (UriError, String)> { fn set_uri(&self, uri: Option<Url>) -> Result<(), UriError> {
let location = &mut self.settings.lock().unwrap().location; let location = &mut self.settings.lock().unwrap().location;
match uri { match uri {
@ -82,8 +82,8 @@ impl Sink for FileSink {
} }
None => { None => {
*location = None; *location = None;
Err((UriError::UnsupportedProtocol, Err(UriError::new(UriErrorKind::UnsupportedProtocol,
format!("Unsupported file URI '{}'", uri.as_str()))) Some(format!("Unsupported file URI '{}'", uri.as_str()))))
} }
} }
} }

View file

@ -67,7 +67,7 @@ impl Source for FileSrc {
&self.controller &self.controller
} }
fn set_uri(&self, uri: Option<Url>) -> Result<(), (UriError, String)> { fn set_uri(&self, uri: Option<Url>) -> Result<(), UriError> {
let location = &mut self.settings.lock().unwrap().location; let location = &mut self.settings.lock().unwrap().location;
match uri { match uri {
@ -83,8 +83,8 @@ impl Source for FileSrc {
} }
None => { None => {
*location = None; *location = None;
Err((UriError::UnsupportedProtocol, Err(UriError::new(UriErrorKind::UnsupportedProtocol,
format!("Unsupported file URI '{}'", uri.as_str()))) Some(format!("Unsupported file URI '{}'", uri.as_str()))))
} }
} }
} }

View file

@ -145,7 +145,7 @@ impl Source for HttpSrc {
&self.controller &self.controller
} }
fn set_uri(&self, uri: Option<Url>) -> Result<(), (UriError, String)> { fn set_uri(&self, uri: Option<Url>) -> Result<(), UriError> {
let url = &mut self.settings.lock().unwrap().url; let url = &mut self.settings.lock().unwrap().url;
match uri { match uri {
@ -159,8 +159,8 @@ impl Source for HttpSrc {
Ok(()) Ok(())
} else { } else {
*url = None; *url = None;
Err((UriError::UnsupportedProtocol, Err(UriError::new(UriErrorKind::UnsupportedProtocol,
format!("Unsupported URI '{}'", uri.as_str()))) Some(format!("Unsupported URI '{}'", uri.as_str()))))
} }
} }
} }

View file

@ -41,7 +41,7 @@ pub trait Sink: Sync + Send {
fn get_controller(&self) -> &SinkController; fn get_controller(&self) -> &SinkController;
// Called from any thread at any time // Called from any thread at any time
fn set_uri(&self, uri: Option<Url>) -> Result<(), (UriError, String)>; fn set_uri(&self, uri: Option<Url>) -> Result<(), UriError>;
fn get_uri(&self) -> Option<Url>; fn get_uri(&self) -> Option<Url>;
// Called from the streaming thread only // Called from the streaming thread only
@ -70,8 +70,8 @@ pub unsafe extern "C" fn sink_set_uri(ptr: *mut Box<Sink>,
let sink: &mut Box<Sink> = &mut *ptr; let sink: &mut Box<Sink> = &mut *ptr;
if uri_ptr.is_null() { if uri_ptr.is_null() {
if let Err((code, msg)) = sink.set_uri(None) { if let Err(err) = sink.set_uri(None) {
code.into_gerror(cerr, Some(&msg)); err.into_gerror(cerr);
GBoolean::False GBoolean::False
} else { } else {
GBoolean::True GBoolean::True
@ -81,8 +81,8 @@ pub unsafe extern "C" fn sink_set_uri(ptr: *mut Box<Sink>,
match Url::parse(uri_str) { match Url::parse(uri_str) {
Ok(uri) => { Ok(uri) => {
if let Err((code, msg)) = sink.set_uri(Some(uri)) { if let Err(err) = sink.set_uri(Some(uri)) {
code.into_gerror(cerr, Some(&msg)); err.into_gerror(cerr);
GBoolean::False GBoolean::False
} else { } else {
GBoolean::True GBoolean::True
@ -90,10 +90,9 @@ pub unsafe extern "C" fn sink_set_uri(ptr: *mut Box<Sink>,
} }
Err(err) => { Err(err) => {
let _ = sink.set_uri(None); let _ = sink.set_uri(None);
UriError::BadUri.into_gerror(cerr, UriError::new(UriErrorKind::BadUri,
Some(&format!("Failed to parse URI '{}': {}", Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
uri_str, .into_gerror(cerr);
err)));
GBoolean::False GBoolean::False
} }
} }

View file

@ -40,7 +40,7 @@ pub trait Source: Sync + Send {
fn get_controller(&self) -> &SourceController; fn get_controller(&self) -> &SourceController;
// Called from any thread at any time // Called from any thread at any time
fn set_uri(&self, uri: Option<Url>) -> Result<(), (UriError, String)>; fn set_uri(&self, uri: Option<Url>) -> Result<(), UriError>;
fn get_uri(&self) -> Option<Url>; fn get_uri(&self) -> Option<Url>;
// Called from any thread between start/stop // Called from any thread between start/stop
@ -74,8 +74,8 @@ pub unsafe extern "C" fn source_set_uri(ptr: *mut Box<Source>,
let source: &mut Box<Source> = &mut *ptr; let source: &mut Box<Source> = &mut *ptr;
if uri_ptr.is_null() { if uri_ptr.is_null() {
if let Err((code, msg)) = source.set_uri(None) { if let Err(err) = source.set_uri(None) {
code.into_gerror(cerr, Some(&msg)); err.into_gerror(cerr);
GBoolean::False GBoolean::False
} else { } else {
GBoolean::True GBoolean::True
@ -85,8 +85,8 @@ pub unsafe extern "C" fn source_set_uri(ptr: *mut Box<Source>,
match Url::parse(uri_str) { match Url::parse(uri_str) {
Ok(uri) => { Ok(uri) => {
if let Err((code, msg)) = source.set_uri(Some(uri)) { if let Err(err) = source.set_uri(Some(uri)) {
code.into_gerror(cerr, Some(&msg)); err.into_gerror(cerr);
GBoolean::False GBoolean::False
} else { } else {
GBoolean::True GBoolean::True
@ -94,10 +94,9 @@ pub unsafe extern "C" fn source_set_uri(ptr: *mut Box<Source>,
} }
Err(err) => { Err(err) => {
let _ = source.set_uri(None); let _ = source.set_uri(None);
UriError::BadUri.into_gerror(cerr, UriError::new(UriErrorKind::BadUri,
Some(&format!("Failed to parse URI '{}': {}", Some(format!("Failed to parse URI '{}': {}", uri_str, err)))
uri_str, .into_gerror(cerr);
err)));
GBoolean::False GBoolean::False
} }
} }

View file

@ -20,6 +20,9 @@ use libc::c_char;
use std::os::raw::c_void; use std::os::raw::c_void;
use std::ffi::CString; use std::ffi::CString;
use std::ptr; use std::ptr;
use std::error::Error;
use std::fmt::{Display, Formatter};
use std::fmt::Error as FmtError;
#[macro_export] #[macro_export]
macro_rules! println_err( macro_rules! println_err(
@ -57,26 +60,73 @@ pub unsafe extern "C" fn cstring_drop(ptr: *mut c_char) {
CString::from_raw(ptr); CString::from_raw(ptr);
} }
#[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum UriError { pub enum UriErrorKind {
UnsupportedProtocol = 0, UnsupportedProtocol = 0,
BadUri, BadUri,
BadState, BadState,
BadReference, BadReference,
} }
#[derive(Debug)]
pub struct UriError {
error_kind: UriErrorKind,
message: Option<String>,
}
extern "C" { extern "C" {
fn g_set_error_literal(err: *mut c_void, domain: u32, code: i32, message: *const c_char); fn g_set_error_literal(err: *mut c_void, domain: u32, code: i32, message: *const c_char);
fn gst_uri_error_quark() -> u32; fn gst_uri_error_quark() -> u32;
} }
impl UriError { impl UriError {
pub unsafe fn into_gerror(self, err: *mut c_void, message: Option<&String>) { pub fn new(error_kind: UriErrorKind, message: Option<String>) -> UriError {
if let Some(msg) = message { UriError {
error_kind: error_kind,
message: message,
}
}
pub fn message(&self) -> &Option<String> {
&self.message
}
pub fn kind(&self) -> UriErrorKind {
self.error_kind
}
pub unsafe fn into_gerror(self, err: *mut c_void) {
if let Some(msg) = self.message {
let cmsg = CString::new(msg.as_str()).unwrap(); let cmsg = CString::new(msg.as_str()).unwrap();
g_set_error_literal(err, gst_uri_error_quark(), self as i32, cmsg.as_ptr()); g_set_error_literal(err,
gst_uri_error_quark(),
self.error_kind as i32,
cmsg.as_ptr());
} else { } else {
g_set_error_literal(err, gst_uri_error_quark(), self as i32, ptr::null()); g_set_error_literal(err,
gst_uri_error_quark(),
self.error_kind as i32,
ptr::null());
}
}
}
impl Display for UriError {
fn fmt(&self, f: &mut Formatter) -> Result<(), FmtError> {
match self.message {
None => f.write_str(self.description()),
Some(ref message) => f.write_fmt(format_args!("{}: {}", self.description(), message)),
}
}
}
impl Error for UriError {
fn description(&self) -> &str {
match self.error_kind {
UriErrorKind::UnsupportedProtocol => "Unsupported protocol",
UriErrorKind::BadUri => "Bad URI",
UriErrorKind::BadState => "Bad State",
UriErrorKind::BadReference => "Bad Reference",
} }
} }
} }