Skip to content

Commit 7839b51

Browse files
Junha Yangjunha1
Junha Yang
authored andcommitted
Update README.md
1 parent e118e04 commit 7839b51

File tree

2 files changed

+88
-9
lines changed

2 files changed

+88
-9
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ https://docs.rs/remote-trait-object)
1111

1212
A simple and powerful Rust remote method invocation library based on Rust trait objects.
1313

14+
See the [documentation](https://docs.rs/remote-trait-object).
15+
1416
## License
1517

1618
Licensed under either of

remote-trait-object/README.md

Lines changed: 86 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,92 @@ https://crates.io/crates/remote-trait-object)
99
https://docs.rs/remote-trait-object)
1010
[![chat](https://img.shields.io/discord/569610676205781012.svg?logo=discord)](https://discord.gg/xhpdXm7)
1111

12-
This library provides a simple and powerful remote method invocation support based on Rust's trait objects.
13-
It sets up an connection between two contexts of `remote-trait-object` that may exist over different thread, different processes, or even different machines.
14-
User can freely export a _service object_, and the user of the other side will import such service as a _proxy object_.
15-
Both service object and proxy object are expressed in Rust trait objects, which exposes only **methods** that can be remotely served and called.
12+
`remote-trait-object` is a general, powerful, and simple [remote method invocation](https://en.wikipedia.org/wiki/Distributed_object_communication) library
13+
based on trait objects.
1614

17-
The actual communciation upon which such connection is constructed, is abstracted with `TransportRecv` and `TransportSend`.
18-
The implementation of the transport must be supplied by the user, and this library itself provides nothing about the communication.
19-
It can be a plain in-process communication, an Ipc, or even a networking, as you implement.
15+
It is...
2016

21-
## Flow
17+
1. Based on _services_ that can be exported and imported **as trait objects** -
18+
You register a service object, which is a trait object, and export it. On the other side, you import it into a proxy object, which is also a trait object.
19+
1. Based on a point-to-point connection - All operations are conducted upon a single connection, which has **two ends**.
20+
1. Easy to export and import services - During a remote method call in some service, you **can export and import another service as an argument or a return value** of the method.
21+
1. Independent from the transport model - The transport model is abstracted and **users must provide a concrete implementation of it**.
22+
1. Concurrent - you can both **call and handle remote calls concurrently**.
2223

23-
![alt text](./flow.png "Call Flow")
24+
See the [documentation](https://docs.rs/remote-trait-object).
25+
26+
## Example
27+
28+
[This example code](https://github.com/CodeChain-io/remote-trait-object/blob/master/remote-trait-object-tests/src/simple.rs)
29+
briefly shows how you can use `remote-trait-object`.
30+
31+
Note that `crate::transport::create()` is for creating the transport ends that are provided to `remote-trait-object ` contexts, which is just in-process communication for the test.
32+
You have to implement your own transport implementation if you're going to actually use this crate./
33+
34+
```rust
35+
use remote_trait_object::*;
36+
37+
#[service]
38+
pub trait CreditCard: Service {
39+
fn pay(&mut self, ammount: u64) -> Result<(), ()>;
40+
}
41+
struct SomeCreditCard {
42+
money: u64,
43+
}
44+
impl Service for SomeCreditCard {}
45+
impl CreditCard for SomeCreditCard {
46+
fn pay(&mut self, ammount: u64) -> Result<(), ()> {
47+
if ammount <= self.money {
48+
self.money -= ammount;
49+
Ok(())
50+
} else {
51+
Err(())
52+
}
53+
}
54+
}
55+
56+
#[service]
57+
pub trait PizzaStore: Service {
58+
fn order_pizza(&self, credit_card: ServiceRef<dyn CreditCard>) -> Result<String, ()>;
59+
}
60+
struct SomePizzaStore;
61+
impl Service for SomePizzaStore {}
62+
impl PizzaStore for SomePizzaStore {
63+
fn order_pizza(&self, credit_card: ServiceRef<dyn CreditCard>) -> Result<String, ()> {
64+
let mut credit_card_proxy: Box<dyn CreditCard> = credit_card.unwrap_import().into_proxy();
65+
credit_card_proxy.pay(10)?;
66+
Ok("Tasty Pizza".to_owned())
67+
}
68+
}
69+
70+
#[test]
71+
fn test() {
72+
let crate::transport::TransportEnds {
73+
recv1,
74+
send1,
75+
recv2,
76+
send2,
77+
} = crate::transport::create();
78+
79+
let _context_pizza_town = Context::with_initial_service_export(
80+
Config::default_setup(),
81+
send1,
82+
recv1,
83+
ServiceToExport::new(Box::new(SomePizzaStore) as Box<dyn PizzaStore>),
84+
);
85+
86+
let (_context_customer, pizza_store): (_, ServiceToImport<dyn PizzaStore>) =
87+
Context::with_initial_service_import(Config::default_setup(), send2, recv2);
88+
let pizza_store_proxy: Box<dyn PizzaStore> = pizza_store.into_proxy();
89+
90+
let my_credit_card = Box::new(SomeCreditCard {
91+
money: 11,
92+
}) as Box<dyn CreditCard>;
93+
assert_eq!(pizza_store_proxy.order_pizza(ServiceRef::create_export(my_credit_card)).unwrap(), "Tasty Pizza");
94+
95+
let my_credit_card = Box::new(SomeCreditCard {
96+
money: 9,
97+
}) as Box<dyn CreditCard>;
98+
assert!(pizza_store_proxy.order_pizza(ServiceRef::create_export(my_credit_card)).is_err());
99+
}
100+
```

0 commit comments

Comments
 (0)