JavaScript is disabled, refresh for a better experience. ambee/giterated

ambee/giterated

Git repository hosting, collaboration, and discovery for the Fediverse.

Spinning

Amber - ⁨1⁩ year ago

parent: tbd commit: ⁨1788060

Showing ⁨⁨32⁩ changed files⁩ with ⁨⁨146⁩ insertions⁩ and ⁨⁨79⁩ deletions⁩

Cargo.lock

View file
@@ -694,6 +694,7 @@ name = "giterated-abi"
694 694 version = "0.1.0"
695 695 dependencies = [
696 696 "anyhow",
697 "async-trait",
697 698 "dlopen2",
698 699 "giterated-models",
699 700 ]
@@ -744,6 +745,7 @@ dependencies = [
744 745 "giterated-models",
745 746 "giterated-plugin",
746 747 "giterated-protocol",
748 "giterated-runtime",
747 749 "jsonwebtoken",
748 750 "log",
749 751 "rand",
@@ -857,6 +859,7 @@ name = "giterated-runtime"
857 859 version = "0.1.0"
858 860 dependencies = [
859 861 "anyhow",
862 "async-trait",
860 863 "dlopen2",
861 864 "giterated-abi",
862 865 "giterated-core",

giterated-core/giterated-models/src/settings/mod.rs

View file
@@ -1,7 +1,5 @@
1 1 mod operations;
2 2
3 use std::{any::Any, sync::Arc};
4
5 3 pub use operations::*;
6 4 use serde::{de::DeserializeOwned, Serialize};
7 5

giterated-core/giterated-models/src/value.rs

View file
@@ -1,7 +1,6 @@
1 1 use std::{fmt::Debug, marker::PhantomData};
2 2
3 3 use serde::{de::DeserializeOwned, Deserialize, Serialize};
4 use serde_json::Value;
5 4
6 5 use crate::{error::GetValueError, object::GiteratedObject, operation::GiteratedOperation};
7 6

giterated-core/src/lib.rs

View file
@@ -7,7 +7,6 @@ use giterated_models::{
7 7 };
8 8 use std::fmt::Debug;
9 9
10 pub mod operation;
11 10 pub mod types;
12 11
13 12 #[derive(Clone)]

giterated-daemon/Cargo.toml

View file
@@ -16,6 +16,7 @@ keywords = ["giterated"]
16 16 giterated-models = { path = "../giterated-core/giterated-models" }
17 17 giterated-plugin = { path = "../giterated-plugin" }
18 18 giterated-protocol = { path = "../plugins/giterated-protocol" }
19 giterated-runtime = { path = "../giterated-runtime" }
19 20
20 21 tokio-tungstenite = "0.20"
21 22 tokio = { version = "1.32", features = [ "full" ] }

giterated-daemon/src/client.rs

View file
@@ -1,5 +1,3 @@
1 use std::sync::Arc;
2
3 1 use futures_util::{SinkExt, StreamExt};
4 2 use giterated_models::{
5 3 error::{IntoInternalError, OperationError},
@@ -7,18 +5,18 @@ use giterated_models::{
7 5 object_backend::ObjectBackend,
8 6 operation::OperationState,
9 7 };
10 use giterated_plugin::new_stack::{handle::RuntimeHandle, Runtime};
11 8 use giterated_protocol::{
12 9 handlers::{NetworkedObject, NetworkedOperation},
13 10 AuthenticatedPayload,
14 11 };
12 use giterated_runtime::RuntimeHandle;
15 13 use tokio::net::TcpStream;
16 14 use tokio_tungstenite::{tungstenite::Message, WebSocketStream};
17 15
18 16 pub async fn client_wrapper(
19 17 _our_instance: Instance,
20 18 mut socket: WebSocketStream<TcpStream>,
21 _runtime: Arc<Box<Runtime>>,
19 _runtime: RuntimeHandle,
22 20 ) {
23 21 loop {
24 22 let message = socket.next().await;

giterated-daemon/src/main.rs

View file
@@ -3,7 +3,7 @@ use giterated_daemon::{authentication::AuthenticationTokenGranter, client::clien
3 3
4 4 use giterated_models::instance::Instance;
5 5
6 use giterated_plugin::new_stack::Runtime;
6 use giterated_runtime::{Runtime, RuntimeHandle, StaticRuntimeExt};
7 7 use sqlx::{postgres::PgConnectOptions, ConnectOptions, PgPool};
8 8 use std::{net::SocketAddr, str::FromStr, sync::Arc};
9 9 use tokio::{
@@ -86,9 +86,10 @@ async fn main() -> Result<(), Error> {
86 86
87 87 let our_instance =
88 88 Instance::from_str(config["giterated"]["instance"].as_str().unwrap()).unwrap();
89 let runtime = runtime.clone();
90 89
91 pool.spawn_pinned(move || client_wrapper(our_instance, connection, runtime));
90 pool.spawn_pinned(move || {
91 client_wrapper(our_instance, connection, RuntimeHandle::from_static())
92 });
92 93 }
93 94 }
94 95

giterated-plugin/giterated-macros/src/lib.rs

View file
@@ -1,6 +1,6 @@
1 1 use proc_macro::TokenStream;
2 2 use quote::quote;
3 use syn::{parse_macro_input, Abi, Attribute, ItemFn};
3 use syn::{parse_macro_input, ItemFn};
4 4
5 5 extern crate proc_macro;
6 6

giterated-plugin/src/future.rs

View file
@@ -7,7 +7,6 @@ use giterated_abi::{
7 7 use std::{
8 8 cell::UnsafeCell,
9 9 future::Future,
10 marker::PhantomData,
11 10 mem::transmute,
12 11 ops::Deref,
13 12 task::{Context, RawWaker, RawWakerVTable, Waker},
@@ -69,7 +68,7 @@ impl RuntimeFuturesExt for State {
69 68
70 69 unsafe extern "C" fn poll_local(
71 70 _future: FfiValueMut<FfiFuture<()>>,
72 mut future_state: FfiValueMut<()>,
71 future_state: FfiValueMut<()>,
73 72 ) -> RuntimeFuturePoll {
74 73 let mut future_state: FfiValueMut<BoxFuture<'static, FfiValue<()>>> = transmute(future_state);
75 74

giterated-plugin/src/lib.rs

View file
@@ -7,9 +7,9 @@ pub mod local;
7 7 pub use giterated_abi as abi;
8 8 pub use giterated_abi::vtable::{operation::Operation, Object, Setting, Value};
9 9
10 pub use giterated_abi::operation::*;
10 11 pub use giterated_abi::state::StateExtractor;
11 12 pub use giterated_abi::state::{FromState, StateUUID};
12 pub use giterated_core::operation::{Failure, Success};
13 13 pub use giterated_core::RuntimeState;
14 14
15 15 #[macro_use]

giterated-plugin/src/local.rs

View file
@@ -6,13 +6,11 @@ use giterated_abi::{
6 6 Callback, CallbackPtr,
7 7 },
8 8 result::FfiError,
9 state::{FromState, State, StateUUID},
9 state::{State, StateUUID},
10 10 value_ex::FfiValueUntyped,
11 11 vtable::{
12 operation::{IntoOperationVTable, OperationVTable},
13 plugin_initialization::InitializationVTable,
14 IntoObjectVTable, IntoSettingVTable, IntoValueVTable, Object, ObjectVTable, SettingVTable,
15 VTable, ValueVTable,
12 operation::IntoOperationVTable, plugin_initialization::InitializationVTable,
13 IntoObjectVTable, IntoSettingVTable, IntoValueVTable, Object, VTable,
16 14 },
17 15 FfiValueMut, FfiValueRef,
18 16 };
@@ -28,6 +26,12 @@ pub struct PluginStackBuilder {
28 26 vtable: &'static VTable<InitializationVTable>,
29 27 }
30 28
29 impl Default for PluginStackBuilder {
30 fn default() -> Self {
31 Self::new()
32 }
33 }
34
31 35 impl PluginStackBuilder {
32 36 pub fn new(// state: FfiValueUntyped,
33 37 // vtable: &'static VTable<InitializationVTable>,

giterated-runtime/Cargo.toml

View file
@@ -12,4 +12,5 @@ giterated-core = { path = "../giterated-core" }
12 12
13 13 tracing = "0.1"
14 14 dlopen2 = "0.6"
15 anyhow = "1"
15 \ No newline at end of file
15 anyhow = "1"
16 async-trait = "0.1"
16 \ No newline at end of file

giterated-runtime/giterated-abi/Cargo.toml

View file
@@ -10,3 +10,4 @@ giterated-models = { path = "../../giterated-core/giterated-models"}
10 10
11 11 anyhow = "1"
12 12 dlopen2 = "0.6"
13 async-trait = "0.1"
13 \ No newline at end of file

giterated-runtime/giterated-abi/src/callback/setting.rs

View file
@@ -44,7 +44,7 @@ where
44 44 unsafe extern "C" fn get_setting(
45 45 callback: CallbackPtr<SettingGetterCallback>,
46 46 state: FfiValueMut<State>,
47 mut object: FfiValueRef<Object>,
47 object: FfiValueRef<Object>,
48 48 ) -> FfiFuture<Result<Setting, ()>> {
49 49 // let _guard = trace_span!(
50 50 // "get_setting handler",
@@ -89,7 +89,7 @@ where
89 89 unsafe extern "C" fn get_setting(
90 90 callback: CallbackPtr<SettingGetterCallback>,
91 91 state: FfiValueMut<State>,
92 mut object: FfiValueRef<Object>,
92 object: FfiValueRef<Object>,
93 93 ) -> FfiFuture<Result<Setting, ()>> {
94 94 todo!()
95 95 }
@@ -119,7 +119,7 @@ where
119 119 unsafe extern "C" fn set_setting(
120 120 callback: CallbackPtr<SettingGetterCallback>,
121 121 state: FfiValueMut<State>,
122 mut object: FfiValueRef<Object>,
122 object: FfiValueRef<Object>,
123 123 _setting: Setting,
124 124 ) -> FfiFuture<Result<(), ()>> {
125 125 // let _guard = trace_span!(
@@ -157,7 +157,7 @@ where
157 157 unsafe extern "C" fn set_setting(
158 158 callback: CallbackPtr<SettingGetterCallback>,
159 159 state: FfiValueMut<State>,
160 mut object: FfiValueRef<Object>,
160 object: FfiValueRef<Object>,
161 161 _setting: Setting,
162 162 ) -> FfiFuture<Result<(), ()>> {
163 163 todo!()

giterated-runtime/giterated-abi/src/callback/value.rs

View file
@@ -44,7 +44,7 @@ where
44 44 unsafe extern "C" fn get_value(
45 45 callback: CallbackPtr<SettingGetterCallback>,
46 46 state: FfiValueMut<State>,
47 mut object: FfiValueRef<Object>,
47 object: FfiValueRef<Object>,
48 48 ) -> FfiFuture<FfiResult<Value, FfiError>> {
49 49 // let _guard = trace_span!(
50 50 // "get_value handler",
@@ -94,7 +94,7 @@ where
94 94 unsafe extern "C" fn get_value(
95 95 callback: CallbackPtr<SettingGetterCallback>,
96 96 state: FfiValueMut<State>,
97 mut object: FfiValueRef<Object>,
97 object: FfiValueRef<Object>,
98 98 ) -> FfiFuture<FfiResult<Value, FfiError>> {
99 99 // let _guard = trace_span!(
100 100 // "get_value handler",

giterated-runtime/giterated-abi/src/heap.rs

View file
@@ -1,4 +1,4 @@
1 use std::{mem::MaybeUninit, ptr::drop_in_place};
1 use std::mem::MaybeUninit;
2 2
3 3 use crate::{abi_backing::HeapValueBacking, FfiValue};
4 4

giterated-runtime/giterated-abi/src/lib.rs

View file
@@ -85,6 +85,7 @@ pub mod callback;
85 85 mod future;
86 86 pub mod heap;
87 87 pub mod model_impl;
88 pub mod operation;
88 89 pub mod plugin;
89 90 pub mod result;
90 91 pub mod state;

giterated-runtime/giterated-abi/src/operation.rs

View file
@@ -0,0 +1,5 @@
1 use crate::prelude::FfiValueUntyped;
2
3 pub struct Success(FfiValueUntyped);
4
5 pub struct Failure(FfiValueUntyped);

giterated-runtime/giterated-abi/src/plugin.rs

View file
@@ -1,10 +1,6 @@
1 1 use dlopen2::wrapper::WrapperApi;
2 2
3 use crate::vtable::{
4 plugin::{Plugin, PluginVTable},
5 runtime::{RuntimeHandle, RuntimeVTable},
6 VTable,
7 };
3 use crate::vtable::{plugin::Plugin, runtime::RuntimeHandle, VTable};
8 4
9 5 #[derive(WrapperApi)]
10 6 pub struct GiteratedPluginAbi {

giterated-runtime/giterated-abi/src/result.rs

View file
@@ -1,3 +1,5 @@
1 use giterated_models::error::OperationError;
2
1 3 use crate::FfiSlice;
2 4
3 5 #[repr(C)]
@@ -10,3 +12,9 @@ pub enum FfiResult<T, E> {
10 12 pub struct FfiError {
11 13 last_error: FfiSlice<str>,
12 14 }
15
16 impl FfiError {
17 pub fn into_internal<T>(self) -> OperationError<T> {
18 todo!()
19 }
20 }

giterated-runtime/giterated-abi/src/state.rs

View file
@@ -20,10 +20,7 @@ use giterated_models::error::OperationError;
20 20
21 21 use crate::{
22 22 value_ex::FfiValueUntyped,
23 vtable::{
24 runtime::{RuntimeHandle, RuntimeVTable},
25 ObjectABI, VTable,
26 },
23 vtable::{runtime::RuntimeHandle, VTable},
27 24 };
28 25
29 26 #[repr(transparent)]

giterated-runtime/giterated-abi/src/vtable/operation.rs

View file
@@ -1,9 +1,10 @@
1 1 use std::ffi::CStr;
2 2
3 3 use crate::{
4 operation::{Failure, Success},
4 5 result::{FfiError, FfiResult},
5 6 value_ex::{FfiValueRefUntyped, FfiValueUntyped},
6 FfiSlice, FfiSliceRef, FfiValue, FfiValueRef,
7 FfiSlice, FfiSliceRef, FfiValueRef,
7 8 };
8 9
9 10 use super::{ObjectABI, VTable};
@@ -26,6 +27,10 @@ impl Operation {
26 27 pub fn deserialize_from<O, T: IntoOperationVTable<O>>(buffer: &[u8]) -> Result<Self, FfiError> {
27 28 todo!()
28 29 }
30
31 pub fn vtable(&self) -> &'static VTable<Self> {
32 self.vtable
33 }
29 34 }
30 35
31 36 impl ObjectABI for Operation {
@@ -65,7 +70,7 @@ impl OperationVTable {
65 70 todo!()
66 71 }
67 72
68 pub fn deserialize_success(&self, buffer: &[u8]) -> Result<FfiValueUntyped, FfiError> {
73 pub fn deserialize_success(&self, buffer: &[u8]) -> Result<Success, FfiError> {
69 74 todo!()
70 75 }
71 76
@@ -73,7 +78,7 @@ impl OperationVTable {
73 78 todo!()
74 79 }
75 80
76 pub fn deserialize_failure(&self, buffer: &[u8]) -> Result<FfiValueUntyped, FfiError> {
81 pub fn deserialize_failure(&self, buffer: &[u8]) -> Result<Failure, FfiError> {
77 82 todo!()
78 83 }
79 84 }

giterated-runtime/giterated-abi/src/vtable/plugin.rs

View file
@@ -1,4 +1,4 @@
1 use crate::{value_ex::FfiValueRefUntyped, FfiSliceRef, FfiValueRef};
1 use crate::{value_ex::FfiValueRefUntyped, FfiSliceRef};
2 2
3 3 use super::ObjectABI;
4 4

giterated-runtime/giterated-abi/src/vtable/runtime.rs

View file
@@ -1,4 +1,9 @@
1 use giterated_models::{error::OperationError, object::ObjectRequestError};
1 use giterated_models::{
2 error::OperationError,
3 object::{GiteratedObject, ObjectRequestError},
4 object_backend::ObjectBackend,
5 operation::{GiteratedOperation, OperationState},
6 };
2 7
3 8 use crate::{
4 9 result::{FfiError, FfiResult},
@@ -7,14 +12,47 @@ use crate::{
7 12 FfiFuture, FfiSliceRef, FfiValueMut,
8 13 };
9 14
15 use core::fmt::Debug;
16
10 17 use super::{Object, ObjectABI};
11 18
19 #[derive(Clone)]
12 20 pub struct RuntimeHandle;
13 21
14 22 impl ObjectABI for RuntimeHandle {
15 23 type VTable = RuntimeVTable;
16 24 }
17 25
26 impl RuntimeHandle {
27 pub async fn handle_serialized(
28 &self,
29 object: &str,
30 operation_type: &str,
31 operation_payload: &[u8],
32 ) -> Result<Vec<u8>, OperationError<Vec<u8>>> {
33 todo!()
34 }
35
36 pub async fn handle_typed<O, D>(
37 &self,
38 object: O,
39 operation: D,
40 ) -> Result<D::Success, OperationError<D::Failure>>
41 where
42 O: GiteratedObject,
43 D: GiteratedOperation<O>,
44 {
45 todo!()
46 }
47
48 pub async fn inner_get_object(
49 &self,
50 object_str: &str,
51 ) -> Result<Object, OperationError<ObjectRequestError>> {
52 todo!()
53 }
54 }
55
18 56 #[derive(Clone, Copy)]
19 57 pub struct RuntimeVTable {
20 58 pub(crate) handle_fn: unsafe extern "C" fn(
@@ -50,3 +88,30 @@ pub trait IntoRuntimeVtable {
50 88 operation_state: FfiValueMut<State>,
51 89 ) -> FfiResult<Object, OperationError<ObjectRequestError>>;
52 90 }
91
92 #[async_trait::async_trait(?Send)]
93 impl ObjectBackend for RuntimeHandle {
94 async fn object_operation<O, D>(
95 &self,
96 object: O,
97 operation: &str,
98 payload: D,
99 operation_state: &OperationState,
100 ) -> Result<D::Success, OperationError<D::Failure>>
101 where
102 O: GiteratedObject + Debug + 'static,
103 D: GiteratedOperation<O> + Debug + 'static,
104 D::Success: Clone,
105 D::Failure: Clone,
106 {
107 todo!()
108 }
109
110 async fn get_object<O: GiteratedObject + Debug + 'static>(
111 &self,
112 object_str: &str,
113 operation_state: &OperationState,
114 ) -> Result<giterated_models::object::Object<O, Self>, OperationError<ObjectRequestError>> {
115 todo!()
116 }
117 }

giterated-runtime/src/lib.rs

View file
@@ -1,11 +1,7 @@
1 1 mod operation_walker;
2 2 pub mod plugin;
3 3
4 use std::{
5 collections::HashMap,
6 path::{Path, PathBuf},
7 sync::Arc,
8 };
4 use std::{collections::HashMap, sync::Arc};
9 5
10 6 use anyhow::Error;
11 7 use dlopen2::wrapper::Container;
@@ -17,16 +13,12 @@ use giterated_abi::{
17 13 CallbackPtr,
18 14 },
19 15 plugin::GiteratedPluginAbi,
20 vtable::{
21 operation::Operation, plugin::Plugin, runtime::RuntimeHandle, Object, Setting, VTable,
22 Value,
23 },
16 vtable::{operation::Operation, plugin::Plugin, Object, Setting, VTable, Value},
24 17 };
25 18 use giterated_core::types::TypeMetadata;
26 19 use giterated_models::{
27 20 error::OperationError,
28 21 object::{GiteratedObject, ObjectOperationPair},
29 object_backend::ObjectBackend,
30 22 operation::GiteratedOperation,
31 23 settings::ObjectSettingPair,
32 24 value::ObjectValuePair,
@@ -35,7 +27,7 @@ use operation_walker::OperationHandlerRules;
35 27 use plugin::initialization::PluginInitializationState;
36 28 use tracing::{debug, debug_span, trace, trace_span, warn};
37 29
38 pub use giterated_core::RuntimeState;
30 pub use giterated_abi::vtable::runtime::RuntimeHandle;
39 31
40 32 pub struct Runtime {
41 33 plugins: Vec<RuntimePlugin>,
@@ -93,7 +85,7 @@ impl Runtime {
93 85
94 86 pub fn insert_plugin(
95 87 &mut self,
96 mut plugin: RuntimePlugin,
88 plugin: RuntimePlugin,
97 89 mut initialization: PluginInitializationState,
98 90 ) {
99 91 let _guard = debug_span!("inserting plugin", meta = debug(&plugin.name())).entered();

giterated-runtime/src/operation_walker.rs

View file
@@ -4,7 +4,7 @@ use giterated_models::{
4 4 settings::GetSetting, value::GetValue,
5 5 };
6 6
7 use tracing::{debug_span, trace, trace_span};
7 use tracing::{trace, trace_span};
8 8
9 9 use super::{ObjectSettingPair, ObjectValuePair, RuntimeHandlers};
10 10

plugins/example-plugin/src/lib.rs

View file
@@ -5,11 +5,7 @@ use giterated_models::{
5 5 object::{ObjectRequest, ObjectRequestError, ObjectResponse},
6 6 user::{DisplayName, User},
7 7 };
8 use giterated_plugin::{
9 abi::state::{StateExtractor, StateUUID},
10 local::PluginStackBuilder,
11 plugin,
12 };
8 use giterated_plugin::{abi::state::StateUUID, local::PluginStackBuilder, plugin};
13 9
14 10 plugin!(
15 11 name: "Example Plugin",

plugins/example-plugin/src/main.rs

View file
@@ -5,7 +5,6 @@ use giterated_models::{
5 5 operation::OperationState,
6 6 user::{DisplayName, User},
7 7 };
8 use giterated_plugin::abi::state::RuntimeState;
9 8 use giterated_plugin::abi::vtable::runtime::RuntimeHandle;
10 9 use giterated_runtime::{Runtime, StaticRuntimeExt};
11 10 use tracing::{info, Level};

plugins/giterated-issues/src/lib.rs

View file
@@ -1,4 +1,4 @@
1 use std::{fmt::Display, str::FromStr, sync::OnceLock};
1 use std::{fmt::Display, str::FromStr};
2 2
3 3 use anyhow::Error;
4 4 use giterated_models::{object::GiteratedObject, repository::Repository};

plugins/giterated-issues/src/main.rs

View file
@@ -28,10 +28,13 @@ pub async fn main() -> Result<(), anyhow::Error> {
28 28 author: User::from_str("amber:giterated.dev").unwrap(),
29 29 };
30 30
31 match runtime.handle_typed(
32 Repository::from_str("barson:giterated.dev/[email protected]").unwrap(),
33 operation,
34 ) {
31 match runtime
32 .handle_typed(
33 Repository::from_str("barson:giterated.dev/[email protected]").unwrap(),
34 operation,
35 )
36 .await
37 {
35 38 Ok(success) => {
36 39 println!("Success in create issue: {:?}", success)
37 40 }

plugins/giterated-protocol/src/handlers.rs

View file
@@ -100,7 +100,7 @@ pub async fn try_handle_with_remote(
100 100 // TODO:
101 101 // Ideally we support pass-through on object types that aren't used locally.
102 102 // For now, we aren't worrying about that.
103 let object_meta = object.vtable();
103 // let object_meta = object.vtable();
104 104
105 105 let operation_meta = operation.vtable();
106 106
@@ -110,10 +110,10 @@ pub async fn try_handle_with_remote(
110 110 // operation.kind().operation_name
111 111 // );
112 112
113 let object_home_uri = unsafe { (object_meta.home_uri)(&object) };
113 let object_home_uri = object.home_uri();
114 114
115 115 if let Some(home_uri) = state.home_uri {
116 if &home_uri == object_home_uri.as_ref() {
116 if home_uri == object_home_uri {
117 117 // This isn't a remote request, requests aren't supposed to hit this layer
118 118 // if they're not remote.
119 119 // warn!("Try handling object operation {}::{}, resolved object home uri as local home uri. This is a bug.", object.kind(),
@@ -133,10 +133,9 @@ pub async fn try_handle_with_remote(
133 133
134 134 let object = todo!();
135 135
136 let payload = unsafe { (operation_meta.serialize)(&operation) }.unwrap();
137 let payload = Vec::from(payload.as_ref());
136 let payload = operation.serialize();
138 137
139 let operation = NetworkedOperation::new(operation_meta.kind().to_string(), payload);
138 let operation = NetworkedOperation::new(operation.operation_kind().to_string(), payload);
140 139
141 140 // let authenticated = Authenticated::new(object, operation);
142 141
@@ -162,13 +161,15 @@ pub async fn try_handle_with_remote(
162 161
163 162 match result {
164 163 Ok(success) => {
165 let success = unsafe { (operation_meta.deserialize_success)(&success) }.unwrap();
164 let success = unsafe { operation_meta.deserialize_success(&success) }
165 .map_err(|e| e.into_internal())?;
166 166
167 167 Ok(success)
168 168 }
169 169 Err(err) => Err(match err {
170 170 OperationError::Operation(failure) => {
171 let failure = unsafe { (operation_meta.deserialize_failure)(&failure) }.unwrap();
171 let failure = unsafe { operation_meta.deserialize_failure(&failure) }
172 .map_err(|e| e.into_internal())?;
172 173
173 174 OperationError::Operation(failure)
174 175 }