Skip to content

Commit

Permalink
code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ypopovych committed Nov 22, 2023
1 parent 2acf8f0 commit b12d689
Show file tree
Hide file tree
Showing 19 changed files with 191 additions and 95 deletions.
4 changes: 2 additions & 2 deletions Rust/transports/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ include = [
"ServiceTransport", "ServiceBoundTransport", "ServiceTransportProcessor", "CTesseractErrorCode",
]
exclude = [
"CFuture_CData", "CFuture_Nothing", "CFuture_Void", "SyncPtr_Void",
"CAnyDropPtr", "CString", "CStringRef", "CError", "CErrorCode",
"CFutureData", "CFutureNothing", "SyncPtr_Void",
"CAnyDropPtr", "CString", "CStringRef", "CError", "CErrorCode", "CDataRef",
"COptionResponseResult", "SwiftError"
]
17 changes: 8 additions & 9 deletions Rust/transports/src/client/connection.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::mem::ManuallyDrop;
use std::sync::Arc;
use crate::error::TesseractSwiftError;
use tesseract_swift_utils::data::CData;
use tesseract_swift_utils::future::CFuture;
use tesseract_swift_utils::data::CDataRef;
use tesseract_swift_utils::future_impls::{CFutureNothing, CFutureData};
use tesseract_swift_utils::ptr::CAnyDropPtr;
use tesseract_swift_utils::Nothing;
use tesseract_swift_utils::traits::AsCRef;

use async_trait::async_trait;
use errorcon::convertible::ErrorContext;
Expand All @@ -16,18 +16,17 @@ use tesseract::Result;
pub struct ClientConnection {
ptr: CAnyDropPtr,
send: unsafe extern "C" fn(
connection: &ClientConnection,
data: *const u8,
len: usize,
) -> ManuallyDrop<CFuture<Nothing>>,
receive: unsafe extern "C" fn(connection: &ClientConnection) -> ManuallyDrop<CFuture<CData>>,
this: &ClientConnection,
data: CDataRef
) -> ManuallyDrop<CFutureNothing>,
receive: unsafe extern "C" fn(this: &ClientConnection) -> ManuallyDrop<CFutureData>,
}

#[async_trait]
impl Connection for ClientConnection {
async fn send(self: Arc<Self>, request: Vec<u8>) -> Result<()> {
let future = unsafe {
ManuallyDrop::into_inner((self.as_ref().send)(self.as_ref(), request.as_ptr(), request.len()))
ManuallyDrop::into_inner((self.as_ref().send)(self.as_ref(), request.as_cref()))
};

TesseractSwiftError::context_async(async || {
Expand Down
6 changes: 3 additions & 3 deletions Rust/transports/src/client/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ use tesseract::Protocol;
#[repr(C)]
pub struct ClientTransport {
ptr: CAnyDropPtr,
id: unsafe extern "C" fn(transport: &ClientTransport) -> ManuallyDrop<CString>,
id: unsafe extern "C" fn(this: &ClientTransport) -> ManuallyDrop<CString>,
status: unsafe extern "C" fn(
transport: &ClientTransport,
this: &ClientTransport,
protocol: CStringRef,
) -> ManuallyDrop<CFuture<ClientStatus>>,
connect: unsafe extern "C" fn(
transport: &ClientTransport,
this: &ClientTransport,
protocol: CStringRef,
) -> ManuallyDrop<ClientConnection>,
}
Expand Down
22 changes: 12 additions & 10 deletions Rust/transports/src/service/processor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::mem::ManuallyDrop;
use std::sync::Arc;
use tesseract_swift_utils::data::CData;
use tesseract_swift_utils::future::CFuture;
use tesseract_swift_utils::data::CDataRef;
use tesseract_swift_utils::future_impls::CFutureData;
use tesseract_swift_utils::ptr::SyncPtr;
use tesseract_swift_utils::Void;

Expand All @@ -24,24 +24,26 @@ impl ServiceTransportProcessor {
Self(SyncPtr::new(processor).as_void())
}

pub unsafe fn as_ref(&self) -> &Arc<dyn TransportProcessor + Send + Sync> {
unsafe fn as_ref(&self) -> &Arc<dyn TransportProcessor + Send + Sync> {
self.0.as_typed_ref().unwrap()
}

pub(super) unsafe fn take(mut self) -> Arc<dyn TransportProcessor + Send + Sync> {
self.0.take_typed()
}
}

#[no_mangle]
pub unsafe extern "C" fn tesseract_service_transport_processor_process(
processor: ManuallyDrop<ServiceTransportProcessor>,
data: *const u8,
len: usize,
) -> CFuture<ManuallyDrop<CData>> {
data: CDataRef
) -> ManuallyDrop<CFutureData> {
let arc = Arc::clone(processor.as_ref());
let slice = std::slice::from_raw_parts(data, len);
let vec = data.cloned();
let future = async move {
let response = arc.process(slice).await;
Ok(ManuallyDrop::new(CData::from(response)))
Ok(arc.process(vec?.as_ref()).await.into())
};
future.into()
ManuallyDrop::new(future.into())
}

#[no_mangle]
Expand Down
26 changes: 25 additions & 1 deletion Rust/transports/src/service/transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,32 @@ use tesseract::service::{BoundTransport, Transport, TransportProcessor};
#[repr(transparent)]
pub struct ServiceBoundTransport(CAnyDropPtr);

impl ServiceBoundTransport {
pub fn new(transport: Box<dyn BoundTransport + Send>) -> Self {
Self(CAnyDropPtr::new(transport))
}
}

impl BoundTransport for ServiceBoundTransport {}

#[repr(C)]
pub struct ServiceTransport {
ptr: CAnyDropPtr,
bind: unsafe extern "C" fn(
transport: ManuallyDrop<ServiceTransport>,
this: ManuallyDrop<ServiceTransport>,
processor: ManuallyDrop<ServiceTransportProcessor>,
) -> ManuallyDrop<ServiceBoundTransport>,
}

impl ServiceTransport {
pub fn new<T: Transport + 'static>(transport: T) -> Self {
Self {
ptr: CAnyDropPtr::new(transport),
bind: transport_bind::<T>
}
}
}

impl Transport for ServiceTransport {
fn bind(
self,
Expand All @@ -31,3 +46,12 @@ impl Transport for ServiceTransport {
}
}
}

unsafe extern "C" fn transport_bind<T: Transport + 'static>(
this: ManuallyDrop<ServiceTransport>,
processor: ManuallyDrop<ServiceTransportProcessor>,
) -> ManuallyDrop<ServiceBoundTransport> {
let transport = ManuallyDrop::into_inner(this).ptr.take::<T>().unwrap();
let bound = transport.bind(ManuallyDrop::into_inner(processor).take());
ManuallyDrop::new(ServiceBoundTransport::new(bound))
}
12 changes: 12 additions & 0 deletions Rust/utils/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ impl<'a, V> AsCRef<CArrayRef<'a, V>> for CArray<V> {
}
}

impl<'a, V> AsCRef<CArrayRef<'a, V>> for Vec<V> {
fn as_cref(&self) -> CArrayRef<'a, V> {
CArrayRef { ptr: self.as_ptr().into(), len: self.len(), _lifecycle: std::marker::PhantomData }
}
}

impl<'a, V> AsCRef<CArrayRef<'a, V>> for &'a[V] {
fn as_cref(&self) -> CArrayRef<'a, V> {
CArrayRef { ptr: self.as_ptr().into(), len: self.len(), _lifecycle: std::marker::PhantomData }
}
}

impl<Value> TryAsRef<[Value]> for CArray<Value> {
type Error = CError;

Expand Down
1 change: 0 additions & 1 deletion Rust/utils/src/future/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ mod from;
mod into;

pub use cfuture::*;
pub use into::*;
11 changes: 11 additions & 0 deletions Rust/utils/src/ptr/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ impl CAnyDropPtr {
})
}

pub fn take<T: Any>(mut self) -> Result<T> {
if self.ptr.is_null() {
return Err(CError::null::<Self>());
}
let val = unsafe { self.ptr.take_typed::<Box<dyn Any>>() };
std::mem::forget(self);
val.downcast::<T>()
.map_err(|_| CError::cast::<Self, T>())
.map(|boxed| *boxed)
}

pub fn ptr(&self) -> &SyncPtr<Void> {
&self.ptr
}
Expand Down
19 changes: 8 additions & 11 deletions Sources/CTesseractShared/include/tesseract-swift-transports.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,15 @@ typedef struct CFuture_ClientStatus {

typedef struct ClientConnection {
CAnyDropPtr ptr;
CFuture_Nothing (*send)(const struct ClientConnection *connection,
const uint8_t *data,
uintptr_t len);
CFuture_CData (*receive)(const struct ClientConnection *connection);
CFutureNothing (*send)(const struct ClientConnection *this, CDataRef data);
CFutureData (*receive)(const struct ClientConnection *this);
} ClientConnection;

typedef struct ClientTransport {
CAnyDropPtr ptr;
CString (*id)(const struct ClientTransport *transport);
struct CFuture_ClientStatus (*status)(const struct ClientTransport *transport, CStringRef protocol);
struct ClientConnection (*connect)(const struct ClientTransport *transport, CStringRef protocol);
CString (*id)(const struct ClientTransport *this);
struct CFuture_ClientStatus (*status)(const struct ClientTransport *this, CStringRef protocol);
struct ClientConnection (*connect)(const struct ClientTransport *this, CStringRef protocol);
} ClientTransport;

typedef struct CFuture_ClientStatus CFutureClientStatus;
Expand All @@ -84,7 +82,7 @@ typedef CAnyDropPtr ServiceBoundTransport;

typedef struct ServiceTransport {
CAnyDropPtr ptr;
ServiceBoundTransport (*bind)(struct ServiceTransport transport,
ServiceBoundTransport (*bind)(struct ServiceTransport this,
struct ServiceTransportProcessor processor);
} ServiceTransport;

Expand All @@ -94,9 +92,8 @@ extern "C" {

CString tesseract_error_get_description(const CError *err);

CFuture_CData tesseract_service_transport_processor_process(struct ServiceTransportProcessor processor,
const uint8_t *data,
uintptr_t len);
CFutureData tesseract_service_transport_processor_process(struct ServiceTransportProcessor processor,
CDataRef data);

void tesseract_service_transport_processor_free(struct ServiceTransportProcessor *processor);

Expand Down
16 changes: 9 additions & 7 deletions Sources/TesseractClient/Protocols/SubstrateService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ import Foundation
import CTesseract
import TesseractShared

public final class SubstrateService: Service, TesseractShared.SubstrateService {
public private(set) var service: CTesseract.SubstrateService

public init(tesseract: UnsafePointer<ClientTesseract>) {
service = tesseract_client_get_substrate_service(tesseract)
}

public final class SubstrateService: ServiceBase<CTesseract.SubstrateService>,
TesseractShared.SubstrateService
{
public func getAccount(
type: TesseractShared.SubstrateAccountType
) async throws -> TesseractShared.SubstrateGetAccountResponse {
Expand All @@ -39,3 +35,9 @@ public final class SubstrateService: Service, TesseractShared.SubstrateService {
}.result.castError(TesseractError.self).get()
}
}

extension CTesseract.SubstrateService: CoreService {
public static func get(from tesseract: UnsafePointer<ClientTesseract>) -> Self {
tesseract_client_get_substrate_service(tesseract)
}
}
18 changes: 8 additions & 10 deletions Sources/TesseractClient/Protocols/TestService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@ import Foundation
import CTesseract
import TesseractShared

public final class TestService: Service, TesseractShared.TestService {
public private(set) var service: CTesseract.TestService

public init(tesseract: UnsafePointer<ClientTesseract>) {
service = tesseract_client_get_test_service(tesseract)
}

public final class TestService: ServiceBase<CTesseract.TestService>,
TesseractShared.TestService
{
public func signTransaction(req: String) async throws -> String {
try await withUnsafePointer(to: &service) {
$0.pointee.sign_transaction($0, req)
}.result.castError(TesseractError.self).get()
}

deinit {
try! service.free().get()
}

extension CTesseract.TestService: CoreService {
public static func get(from tesseract: UnsafePointer<ClientTesseract>) -> Self {
tesseract_client_get_test_service(tesseract)
}
}
30 changes: 30 additions & 0 deletions Sources/TesseractClient/Service.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// Service.swift
//
//
// Created by Yehor Popovych on 22/11/2023.
//

import Foundation
import CTesseract
import TesseractShared

public protocol Service: AnyObject {
init(tesseract: UnsafePointer<ClientTesseract>)
}

public protocol CoreService: CSwiftAnyDropPtr {
static func get(from tesseract: UnsafePointer<ClientTesseract>) -> Self
}

open class ServiceBase<S: CoreService>: Service {
public var service: S

public required init(tesseract: UnsafePointer<ClientTesseract>) {
service = S.get(from: tesseract)
}

deinit {
try! service.free().get()
}
}
4 changes: 0 additions & 4 deletions Sources/TesseractClient/Tesseract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import CTesseract
#endif
@_exported import TesseractShared

public protocol Service: AnyObject {
init(tesseract: UnsafePointer<ClientTesseract>)
}

// Class is not thread safe.
// Use mutex if you need multithreaded setup (but why?)
// Services and transports are thread safe
Expand Down
2 changes: 1 addition & 1 deletion Sources/TesseractService/Protocols/TestService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public protocol TestServiceResult: TesseractShared.TestServiceResult, Service

public protocol TestService: TestServiceResult, TesseractShared.TestService {}

public extension TestService {
public extension TestServiceResult {
func toCore() -> Core {
var value = Core(value: self)
value.sign_transaction = test_service_sign
Expand Down
5 changes: 2 additions & 3 deletions Sources/TesseractTransportsClient/CoreTransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ private func transport_connect(
}

private func connection_send(self: UnsafePointer<ClientConnection>!,
data: UnsafePointer<UInt8>!,
len: UInt) -> CFutureNothing
data: CDataRef) -> CFutureNothing
{
let data = Data(bytes: UnsafeRawPointer(data), count: Int(len))
let data = data.copied()
return CFutureNothing {
await self.unowned(Connection.self).castError().asyncFlatMap {
await $0.send(request: data)
Expand Down
Loading

0 comments on commit b12d689

Please sign in to comment.