@@ -12,58 +12,129 @@ use crate::{Event, Info, TrustedPeer, Warning};
1212use super :: { error:: ClientError , messages:: ClientMessage } ;
1313use super :: { error:: FetchBlockError , IndexedBlock } ;
1414
15- /// A [`Client`] allows for communication with a running node.
15+ /// Client state when idle.
16+ pub struct Idle ;
17+ /// Client state when subscribed to events.
18+ pub struct Subscribed ;
19+ /// Client state when active.
20+ pub struct Active ;
21+
22+ mod sealed {
23+ pub trait Sealed { }
24+ }
25+
26+ impl sealed:: Sealed for Idle { }
27+ impl sealed:: Sealed for Subscribed { }
28+ impl sealed:: Sealed for Active { }
29+
30+ /// State of the client
31+ pub trait State : sealed:: Sealed { }
32+
33+ impl State for Idle { }
34+ impl State for Subscribed { }
35+ impl State for Active { }
36+
37+ /// Wrapper type for the channels that will receive events.
1638#[ derive( Debug ) ]
17- pub struct Client {
18- /// Send events to a node, such as broadcasting a transaction.
19- pub requester : Requester ,
39+ pub struct EventListeners {
2040 /// Receive informational messages from the node.
2141 pub info_rx : mpsc:: Receiver < Info > ,
2242 /// Receive warning messages from a node.
2343 pub warn_rx : mpsc:: UnboundedReceiver < Warning > ,
2444 /// Receive [`Event`] from a node to act on.
2545 pub event_rx : mpsc:: UnboundedReceiver < Event > ,
26- /// Internal node structure.
27- node : Option < Node > ,
2846}
2947
30- impl Client {
31- pub ( crate ) fn new (
48+ impl EventListeners {
49+ fn new (
3250 info_rx : mpsc:: Receiver < Info > ,
3351 warn_rx : mpsc:: UnboundedReceiver < Warning > ,
3452 event_rx : mpsc:: UnboundedReceiver < Event > ,
35- ntx : UnboundedSender < ClientMessage > ,
36- node : Node ,
3753 ) -> Self {
3854 Self {
39- requester : Requester :: new ( ntx) ,
4055 info_rx,
4156 warn_rx,
4257 event_rx,
58+ }
59+ }
60+ }
61+
62+ /// A [`Client`] allows for communication with a running node.
63+ #[ derive( Debug ) ]
64+ pub struct Client < S : State > {
65+ /// Send events to a node, such as broadcasting a transaction.
66+ ntx : UnboundedSender < ClientMessage > ,
67+ /// Receive informational messages from the node.
68+ events : Option < EventListeners > ,
69+ /// Internal node structure.
70+ node : Option < Node > ,
71+ /// Marker for state.
72+ _marker : core:: marker:: PhantomData < S > ,
73+ }
74+
75+ impl Client < Idle > {
76+ pub ( crate ) fn new (
77+ info_rx : mpsc:: Receiver < Info > ,
78+ warn_rx : mpsc:: UnboundedReceiver < Warning > ,
79+ event_rx : mpsc:: UnboundedReceiver < Event > ,
80+ ntx : UnboundedSender < ClientMessage > ,
81+ node : Node ,
82+ ) -> Client < Idle > {
83+ Client {
84+ ntx,
85+ events : Some ( EventListeners :: new ( info_rx, warn_rx, event_rx) ) ,
4386 node : Some ( node) ,
87+ _marker : core:: marker:: PhantomData ,
4488 }
4589 }
4690
47- /// Start the underlying node on a [`tokio::task`]. This assumes there is a runtime present to
48- /// execute the task.
49- pub fn run ( mut self ) -> Self {
50- let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
51- tokio:: task:: spawn ( async move { node. run ( ) . await } ) ;
52- self
91+ /// Subscribe to the events published by the light client. Applications may perform arbitrary behavior
92+ /// when receiving these events, such as logging or applying the effect of a block to a wallet.
93+ /// The client is not yet running after this step.
94+ pub fn subscribe ( mut self ) -> ( Client < Subscribed > , EventListeners ) {
95+ let events = core:: mem:: take ( & mut self . events ) . expect ( "cannot call run twice." ) ;
96+ (
97+ Client {
98+ ntx : self . ntx ,
99+ events : None ,
100+ node : self . node ,
101+ _marker : core:: marker:: PhantomData ,
102+ } ,
103+ events,
104+ )
53105 }
54106}
55107
56- /// Send messages to a node that is running so the node may complete a task.
57- #[ derive( Debug , Clone ) ]
58- pub struct Requester {
59- ntx : UnboundedSender < ClientMessage > ,
60- }
108+ impl Client < Subscribed > {
109+ /// Start the client, which will begin publishing events to subscribers. This will implicitly
110+ /// spawn a [`tokio::task`] to fetch data for the client.
111+ pub fn start ( mut self ) -> Client < Active > {
112+ let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
113+ tokio:: task:: spawn ( async move { node. run ( ) . await } ) ;
114+ Client {
115+ ntx : self . ntx ,
116+ events : None ,
117+ node : None ,
118+ _marker : core:: marker:: PhantomData ,
119+ }
120+ }
61121
62- impl Requester {
63- fn new ( ntx : UnboundedSender < ClientMessage > ) -> Self {
64- Self { ntx }
122+ /// Receive a [`Node`] to run on a dedicated resource, likely with a custom [`tokio::runtime::Runtime`].
123+ pub fn start_managed ( mut self ) -> ( Client < Active > , Node ) {
124+ let node = core:: mem:: take ( & mut self . node ) . expect ( "cannot call run twice." ) ;
125+ (
126+ Client {
127+ ntx : self . ntx ,
128+ events : None ,
129+ node : None ,
130+ _marker : core:: marker:: PhantomData ,
131+ } ,
132+ node,
133+ )
65134 }
135+ }
66136
137+ impl Client < Active > {
67138 /// Tell the node to shut down.
68139 ///
69140 /// # Errors
0 commit comments