tauri_plugin_video/
error.rs1use serde::{ser::Serializer, Serialize};
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, thiserror::Error)]
6pub enum Error {
7 #[error(
8 "native video protocol mismatch: expected {expected}, received {actual:?} from @get-air/video-tauri version {package_version:?}"
9 )]
10 ProtocolMismatch {
11 expected: u32,
12 actual: Option<u32>,
13 package_version: Option<String>,
14 },
15 #[error("invalid request: {0}")]
16 InvalidRequest(String),
17 #[error("GStreamer is unavailable: {0}")]
18 RuntimeUnavailable(String),
19 #[error("media pipeline failed: {0}")]
20 Pipeline(String),
21 #[cfg(mobile)]
22 #[error(transparent)]
23 PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
24}
25
26impl Error {
27 pub fn code(&self) -> &'static str {
28 match self {
29 Self::ProtocolMismatch { .. } => "PROTOCOL_MISMATCH",
30 Self::InvalidRequest(_) => "INVALID_REQUEST",
31 Self::RuntimeUnavailable(_) => "RUNTIME_UNAVAILABLE",
32 Self::Pipeline(_) => "PIPELINE_FAILED",
33 #[cfg(mobile)]
34 Self::PluginInvoke(_) => "MOBILE_PLUGIN_ERROR",
35 }
36 }
37
38 fn recoverable(&self) -> bool {
39 matches!(self, Self::Pipeline(_))
40 }
41}
42
43impl Serialize for Error {
44 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
45 where
46 S: Serializer,
47 {
48 #[derive(Serialize)]
49 #[serde(rename_all = "camelCase")]
50 struct WireError<'a> {
51 code: &'static str,
52 message: String,
53 recoverable: bool,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 stage: Option<&'a str>,
56 }
57
58 WireError {
59 code: self.code(),
60 message: self.to_string(),
61 recoverable: self.recoverable(),
62 stage: match self {
63 Self::ProtocolMismatch { .. } => Some("protocol"),
64 Self::Pipeline(_) => Some("pipeline"),
65 _ => None,
66 },
67 }
68 .serialize(serializer)
69 }
70}