Skip to content

Commit c93af61

Browse files
authored
Refactor the endpoint module (#31)
Refactor the endpoint module
2 parents d172456 + 0d5b902 commit c93af61

File tree

12 files changed

+1090
-719
lines changed

12 files changed

+1090
-719
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ license-file = "LICENSE-MIT"
1111
name = "xrl"
1212
readme = "README.md"
1313
repository = "https://github.com/xi-frontend/xrl"
14-
version = "0.0.6"
14+
version = "0.0.7"
1515
edition = "2018"
1616

1717
[dependencies]

examples/it_works.rs

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
#![allow(unused_variables)]
21
extern crate futures;
32
extern crate tokio;
43
extern crate xrl;
54

65
use futures::{future, Future, Stream};
7-
use xrl::{spawn, Client, Frontend, FrontendBuilder, MeasureWidth, ServerResult, XiNotification};
6+
use xrl::*;
87

9-
// Type that represent our client
8+
// Type that represent a `xi-core` peer. It implements `Frontend`,
9+
// which means it can handle notifications and requests from
10+
// `xi-core`.
11+
#[allow(dead_code)]
1012
struct MyFrontend {
11-
#[allow(dead_code)]
13+
// This is not actually used in this example, but if we wanted to
14+
// our frontend could use a `Client` so that it could send
15+
// requests and notifications to `xi-core`, instead of just
16+
// handling incoming messages.
1217
client: Client,
1318
}
1419

15-
// Implement how our client handles notifications and requests from the core.
20+
// Implement how our client handles notifications & requests from the core.
1621
impl Frontend for MyFrontend {
17-
fn handle_notification(&mut self, notification: XiNotification) -> ServerResult<()> {
22+
type NotificationResult = Result<(), ()>;
23+
fn handle_notification(&mut self, notification: XiNotification) -> Self::NotificationResult {
1824
use XiNotification::*;
19-
2025
match notification {
2126
Update(update) => println!("received `update` from Xi core:\n{:?}", update),
2227
ScrollTo(scroll) => println!("received `scroll_to` from Xi core:\n{:?}", scroll),
@@ -50,44 +55,63 @@ impl Frontend for MyFrontend {
5055
println!("received `language_changed` from Xi core:\n{:?}", lang)
5156
}
5257
}
53-
Box::new(future::ok(()))
58+
Ok(())
5459
}
5560

56-
fn handle_measure_width(&mut self, request: MeasureWidth) -> ServerResult<Vec<Vec<f32>>> {
57-
Box::new(future::ok(Vec::new()))
61+
type MeasureWidthResult = Result<Vec<Vec<f32>>, ()>;
62+
// we don't actually use the `request` argument in this example,
63+
// hence the attribute.
64+
#[allow(unused_variables)]
65+
fn handle_measure_width(&mut self, request: MeasureWidth) -> Self::MeasureWidthResult {
66+
Ok(Vec::new())
5867
}
5968
}
6069

6170
struct MyFrontendBuilder;
6271

63-
impl FrontendBuilder<MyFrontend> for MyFrontendBuilder {
64-
fn build(self, client: Client) -> MyFrontend {
65-
MyFrontend { client: client }
72+
impl FrontendBuilder for MyFrontendBuilder {
73+
type Frontend = MyFrontend;
74+
fn build(self, client: Client) -> Self::Frontend {
75+
MyFrontend { client }
6676
}
6777
}
6878

6979
fn main() {
70-
// spawn Xi core
71-
let (client, core_stderr) = spawn("xi-core", MyFrontendBuilder {});
80+
tokio::run(future::lazy(move || {
81+
// spawn Xi core
82+
let (client, core_stderr) = spawn("xi-core", MyFrontendBuilder {});
83+
84+
// start logging Xi core's stderr
85+
tokio::spawn(
86+
core_stderr
87+
.for_each(|msg| {
88+
println!("xi-core stderr: {}", msg);
89+
Ok(())
90+
})
91+
.map_err(|_| ()),
92+
);
7293

73-
// All clients must send client_started notification first
74-
tokio::run(client.client_started(None, None).map_err(|_| ()));
75-
// start logging Xi core's stderr
76-
let log_core_errors = core_stderr
77-
.for_each(|msg| {
78-
println!("xi-core stderr: {}", msg);
79-
Ok(())
80-
})
81-
.map_err(|_| ());
82-
::std::thread::spawn(move || {
83-
tokio::run(log_core_errors);
84-
});
85-
// Send a request to open a new view, and print the result
86-
let open_new_view = client
87-
.new_view(None)
88-
.map(|view_name| println!("opened new view: {}", view_name))
89-
.map_err(|_| ());
90-
tokio::run(open_new_view);
91-
// sleep until xi-requests are received
92-
::std::thread::sleep(::std::time::Duration::new(5, 0));
94+
let client_clone = client.clone();
95+
client
96+
// Xi core expects the first notification to be
97+
// "client_started"
98+
.client_started(None, None)
99+
.map_err(|e| eprintln!("failed to send \"client_started\": {:?}", e))
100+
.and_then(move |_| {
101+
let client = client_clone.clone();
102+
client
103+
.new_view(None)
104+
.map(|view_name| println!("opened new view: {}", view_name))
105+
.map_err(|e| eprintln!("failed to open a new view: {:?}", e))
106+
.and_then(move |_| {
107+
// Forces to shut down the Xi-RPC
108+
// endoint. Otherwise, this example would keep
109+
// running until the xi-core process
110+
// terminates.
111+
println!("shutting down");
112+
client_clone.shutdown();
113+
Ok(())
114+
})
115+
})
116+
}));
93117
}

0 commit comments

Comments
 (0)