@@ -13,50 +13,106 @@ use crate::{Event, Info, TrustedPeer, Warning};
1313use super :: { error:: ClientError , messages:: ClientMessage } ;
1414use super :: { error:: FetchBlockError , IndexedBlock } ;
1515
16- /// A [`Client`] allows for communication with a running node.
16+ /// Client state when idle.
17+ pub struct Idle ;
18+ /// Client state when active.
19+ pub struct Active ;
20+
21+ mod sealed {
22+ pub trait Sealed { }
23+ }
24+
25+ impl sealed:: Sealed for Idle { }
26+ impl sealed:: Sealed for Active { }
27+
28+ /// State of the client
29+ pub trait State : sealed:: Sealed { }
30+
31+ impl State for Idle { }
32+ impl State for Active { }
33+
34+ /// Wrapper type for the channels that will receive events.
1735#[ derive( Debug ) ]
18- pub struct Client {
19- /// Send events to a node, such as broadcasting a transaction.
20- pub requester : Requester ,
36+ pub struct EventListeners {
2137 /// Receive informational messages from the node.
2238 pub info_rx : mpsc:: Receiver < Info > ,
2339 /// Receive warning messages from a node.
2440 pub warn_rx : mpsc:: UnboundedReceiver < Warning > ,
2541 /// Receive [`Event`] from a node to act on.
2642 pub event_rx : mpsc:: UnboundedReceiver < Event > ,
27- /// Internal node structure.
28- node : Option < Node > ,
2943}
3044
31- impl Client {
32- pub ( crate ) fn new (
45+ impl EventListeners {
46+ fn new (
3347 info_rx : mpsc:: Receiver < Info > ,
3448 warn_rx : mpsc:: UnboundedReceiver < Warning > ,
3549 event_rx : mpsc:: UnboundedReceiver < Event > ,
36- ntx : UnboundedSender < ClientMessage > ,
37- node : Node ,
3850 ) -> Self {
3951 Self {
40- requester : Requester :: new ( ntx) ,
4152 info_rx,
4253 warn_rx,
4354 event_rx,
44- node : Some ( node) ,
4555 }
4656 }
57+ }
58+
59+ /// A [`Client`] allows for communication with a running node.
60+ #[ derive( Debug ) ]
61+ pub struct Client < S : State > {
62+ /// Send events to a node, such as broadcasting a transaction.
63+ ntx : UnboundedSender < ClientMessage > ,
64+ /// Receive informational messages from the node.
65+ events : Option < EventListeners > ,
66+ /// Internal node structure.
67+ node : Option < Node > ,
68+ /// Marker for state.
69+ _marker : core:: marker:: PhantomData < S > ,
70+ }
4771
72+ impl Client < Idle > {
73+ pub ( crate ) fn new (
74+ info_rx : mpsc:: Receiver < Info > ,
75+ warn_rx : mpsc:: UnboundedReceiver < Warning > ,
76+ event_rx : mpsc:: UnboundedReceiver < Event > ,
77+ ntx : UnboundedSender < ClientMessage > ,
78+ node : Node ,
79+ ) -> Client < Idle > {
80+ Client {
81+ ntx,
82+ events : Some ( EventListeners :: new ( info_rx, warn_rx, event_rx) ) ,
83+ node : Some ( node) ,
84+ _marker : core:: marker:: PhantomData ,
85+ }
86+ }
4887 /// Start the underlying node on a [`tokio::task`]. This assumes there is a runtime present to
4988 /// execute the task.
50- pub fn run ( mut self ) -> ( Self , JoinHandle < Result < ( ) , crate :: error:: NodeError > > ) {
89+ pub fn run (
90+ mut self ,
91+ ) -> (
92+ Client < Active > ,
93+ EventListeners ,
94+ JoinHandle < Result < ( ) , crate :: error:: NodeError > > ,
95+ ) {
96+ let events = core:: mem:: take ( & mut self . events ) . expect ( "cannot call run twice." ) ;
5197 let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
52- ( self , tokio:: task:: spawn ( async move { node. run ( ) . await } ) )
98+ (
99+ Client {
100+ ntx : self . ntx ,
101+ events : None ,
102+ node : None ,
103+ _marker : core:: marker:: PhantomData ,
104+ } ,
105+ events,
106+ tokio:: task:: spawn ( async move { node. run ( ) . await } ) ,
107+ )
53108 }
54109
55110 /// Run on a detached operating system thread. This method is useful in the case where the
56111 /// majority of your application code is blocking, and you do not have a
57112 /// [`tokio::runtime::Runtime`] available. This method will implicitly create a runtime which
58113 /// runs the data fetching process.
59- pub fn run_detached ( mut self ) -> ( Self , std:: thread:: JoinHandle < ( ) > ) {
114+ pub fn run_detached ( mut self ) -> ( Client < Active > , EventListeners , std:: thread:: JoinHandle < ( ) > ) {
115+ let events = core:: mem:: take ( & mut self . events ) . expect ( "cannot call run twice." ) ;
60116 let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
61117 let handle = std:: thread:: spawn ( || {
62118 tokio:: runtime:: Builder :: new_multi_thread ( )
@@ -67,27 +123,38 @@ impl Client {
67123 let _ = node. run ( ) . await ;
68124 } )
69125 } ) ;
70- ( self , handle)
126+ let client = Client {
127+ ntx : self . ntx ,
128+ events : None ,
129+ node : None ,
130+ _marker : core:: marker:: PhantomData ,
131+ } ;
132+ ( client, events, handle)
71133 }
72134
73135 /// Run the node with an existing [`tokio::runtime::Runtime`].
74- pub fn run_with_runtime ( mut self , rt : tokio:: runtime:: Runtime ) -> ( Self , JoinHandle < Result < ( ) , crate :: error:: NodeError > > ) {
136+ pub fn run_with_runtime (
137+ mut self ,
138+ rt : impl AsRef < tokio:: runtime:: Runtime > ,
139+ ) -> (
140+ Client < Active > ,
141+ EventListeners ,
142+ JoinHandle < Result < ( ) , crate :: error:: NodeError > > ,
143+ ) {
144+ let rt = rt. as_ref ( ) ;
145+ let events = core:: mem:: take ( & mut self . events ) . expect ( "cannot call run twice." ) ;
75146 let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
76- ( self , rt. spawn ( async move { node. run ( ) . await } ) )
147+ let client = Client {
148+ ntx : self . ntx ,
149+ events : None ,
150+ node : None ,
151+ _marker : core:: marker:: PhantomData ,
152+ } ;
153+ ( client, events, rt. spawn ( async move { node. run ( ) . await } ) )
77154 }
78155}
79156
80- /// Send messages to a node that is running so the node may complete a task.
81- #[ derive( Debug , Clone ) ]
82- pub struct Requester {
83- ntx : UnboundedSender < ClientMessage > ,
84- }
85-
86- impl Requester {
87- fn new ( ntx : UnboundedSender < ClientMessage > ) -> Self {
88- Self { ntx }
89- }
90-
157+ impl Client < Active > {
91158 /// Tell the node to shut down.
92159 ///
93160 /// # Errors
0 commit comments