spicedb_embedded_sys/
memory.rs1use std::os::raw::{c_char, c_int, c_uchar, c_ulonglong};
7
8use prost::Message;
9use spicedb_grpc_tonic::v1::{
10 CheckBulkPermissionsRequest, CheckBulkPermissionsResponse, CheckPermissionRequest,
11 CheckPermissionResponse, DeleteRelationshipsRequest, DeleteRelationshipsResponse,
12 ExpandPermissionTreeRequest, ExpandPermissionTreeResponse, ReadSchemaRequest,
13 ReadSchemaResponse, WriteRelationshipsRequest, WriteRelationshipsResponse, WriteSchemaRequest,
14 WriteSchemaResponse,
15};
16
17#[derive(Debug, Clone)]
19pub struct RpcError(pub String);
20
21impl std::fmt::Display for RpcError {
22 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
23 write!(f, "{}", self.0)
24 }
25}
26
27impl std::error::Error for RpcError {}
28
29pub type RpcResult<T> = Result<T, RpcError>;
31
32fn raw_call(
34 handle: u64,
35 request_bytes: &[u8],
36 f: unsafe extern "C" fn(
37 c_ulonglong,
38 *const c_uchar,
39 c_int,
40 *mut *mut c_uchar,
41 *mut c_int,
42 *mut *mut c_char,
43 ),
44) -> RpcResult<Vec<u8>> {
45 let mut out_response_bytes: *mut c_uchar = std::ptr::null_mut();
46 let mut out_response_len: c_int = 0;
47 let mut out_error: *mut c_char = std::ptr::null_mut();
48
49 unsafe {
50 f(
51 handle as c_ulonglong,
52 request_bytes.as_ptr(),
53 request_bytes.len() as c_int,
54 &mut out_response_bytes,
55 &mut out_response_len,
56 &mut out_error,
57 );
58 }
59
60 if !out_error.is_null() {
61 let s = unsafe { std::ffi::CStr::from_ptr(out_error) }
62 .to_string_lossy()
63 .into_owned();
64 unsafe { crate::spicedb_free(out_error) };
65 return Err(RpcError(s));
66 }
67
68 let len = out_response_len as usize;
69 let bytes = if len == 0 {
70 vec![]
71 } else {
72 unsafe { std::slice::from_raw_parts(out_response_bytes, len).to_vec() }
73 };
74 if !out_response_bytes.is_null() {
75 unsafe { crate::spicedb_free_bytes(out_response_bytes as *mut std::ffi::c_void) };
76 }
77 Ok(bytes)
78}
79
80pub fn check_permission(
84 handle: u64,
85 request: &CheckPermissionRequest,
86) -> RpcResult<CheckPermissionResponse> {
87 let mut buf = Vec::new();
88 request
89 .encode(&mut buf)
90 .map_err(|e| RpcError(e.to_string()))?;
91 let bytes = raw_call(handle, &buf, crate::spicedb_permissions_check_permission)?;
92 CheckPermissionResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
93}
94
95pub fn write_relationships(
97 handle: u64,
98 request: &WriteRelationshipsRequest,
99) -> RpcResult<WriteRelationshipsResponse> {
100 let mut buf = Vec::new();
101 request
102 .encode(&mut buf)
103 .map_err(|e| RpcError(e.to_string()))?;
104 let bytes = raw_call(handle, &buf, crate::spicedb_permissions_write_relationships)?;
105 WriteRelationshipsResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
106}
107
108pub fn delete_relationships(
110 handle: u64,
111 request: &DeleteRelationshipsRequest,
112) -> RpcResult<DeleteRelationshipsResponse> {
113 let mut buf = Vec::new();
114 request
115 .encode(&mut buf)
116 .map_err(|e| RpcError(e.to_string()))?;
117 let bytes = raw_call(
118 handle,
119 &buf,
120 crate::spicedb_permissions_delete_relationships,
121 )?;
122 DeleteRelationshipsResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
123}
124
125pub fn check_bulk_permissions(
127 handle: u64,
128 request: &CheckBulkPermissionsRequest,
129) -> RpcResult<CheckBulkPermissionsResponse> {
130 let mut buf = Vec::new();
131 request
132 .encode(&mut buf)
133 .map_err(|e| RpcError(e.to_string()))?;
134 let bytes = raw_call(
135 handle,
136 &buf,
137 crate::spicedb_permissions_check_bulk_permissions,
138 )?;
139 CheckBulkPermissionsResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
140}
141
142pub fn expand_permission_tree(
144 handle: u64,
145 request: &ExpandPermissionTreeRequest,
146) -> RpcResult<ExpandPermissionTreeResponse> {
147 let mut buf = Vec::new();
148 request
149 .encode(&mut buf)
150 .map_err(|e| RpcError(e.to_string()))?;
151 let bytes = raw_call(
152 handle,
153 &buf,
154 crate::spicedb_permissions_expand_permission_tree,
155 )?;
156 ExpandPermissionTreeResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
157}
158
159pub fn read_schema(handle: u64, request: &ReadSchemaRequest) -> RpcResult<ReadSchemaResponse> {
163 let mut buf = Vec::new();
164 request
165 .encode(&mut buf)
166 .map_err(|e| RpcError(e.to_string()))?;
167 let bytes = raw_call(handle, &buf, crate::spicedb_schema_read_schema)?;
168 ReadSchemaResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
169}
170
171pub fn write_schema(handle: u64, request: &WriteSchemaRequest) -> RpcResult<WriteSchemaResponse> {
173 let mut buf = Vec::new();
174 request
175 .encode(&mut buf)
176 .map_err(|e| RpcError(e.to_string()))?;
177 let bytes = raw_call(handle, &buf, crate::spicedb_schema_write_schema)?;
178 WriteSchemaResponse::decode(&bytes[..]).map_err(|e| RpcError(e.to_string()))
179}