runmat_runtime/context/
capability.rs1use crate::{build_runtime_error, RuntimeError};
2use serde::{Deserialize, Serialize};
3use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum RuntimeCapability {
9 Builtin,
10 Call,
11 Workspace,
12 Object,
13 Host,
14 Error,
15 Cancellation,
16 Acceleration,
17 Placement,
18 Native,
19 Foreign,
20 Parallel,
21}
22
23impl RuntimeCapability {
24 pub const fn as_str(self) -> &'static str {
25 match self {
26 Self::Builtin => "builtin",
27 Self::Call => "call",
28 Self::Workspace => "workspace",
29 Self::Object => "object",
30 Self::Host => "host",
31 Self::Error => "error",
32 Self::Cancellation => "cancellation",
33 Self::Acceleration => "acceleration",
34 Self::Placement => "placement",
35 Self::Native => "native",
36 Self::Foreign => "foreign",
37 Self::Parallel => "parallel",
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
46#[serde(deny_unknown_fields)]
47pub struct RuntimeCapabilityError {
48 pub capability: RuntimeCapability,
49 pub operation: String,
50}
51
52impl RuntimeCapabilityError {
53 pub const IDENTIFIER: &'static str = "RunMat:RuntimeContext:CapabilityUnavailable";
54
55 pub fn new(capability: RuntimeCapability, operation: impl Into<String>) -> Self {
56 Self {
57 capability,
58 operation: operation.into(),
59 }
60 }
61
62 pub fn into_runtime_error(self) -> RuntimeError {
63 build_runtime_error(self.to_string())
64 .with_identifier(Self::IDENTIFIER)
65 .build()
66 }
67}
68
69impl fmt::Display for RuntimeCapabilityError {
70 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(
72 formatter,
73 "runtime capability '{}' is unavailable for {}",
74 self.capability.as_str(),
75 self.operation
76 )
77 }
78}
79
80impl std::error::Error for RuntimeCapabilityError {}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn capability_failure_has_stable_identifier_and_payload() {
88 let error = RuntimeCapabilityError::new(RuntimeCapability::Foreign, "invoke JNI callback");
89 let json = serde_json::to_string(&error).expect("serialize capability error");
90 assert_eq!(
91 json,
92 r#"{"capability":"foreign","operation":"invoke JNI callback"}"#
93 );
94 let runtime = error.into_runtime_error();
95 assert_eq!(
96 runtime.identifier(),
97 Some(RuntimeCapabilityError::IDENTIFIER)
98 );
99 assert!(runtime.to_string().contains("foreign"));
100 }
101}