1- use std:: { ops:: ControlFlow , rc :: Rc } ;
1+ use std:: ops:: ControlFlow ;
22
3- use uuid :: Uuid ;
3+ use lu :: Methods ;
44
5- use crate :: shared:: { ApiCheck , Casing , NetworkSide , NumberKind , Options , Range } ;
5+ use crate :: {
6+ options,
7+ shared:: { ApiCheck , Casing , NetworkSide , NumberKind , Range , Remote } ,
8+ } ;
69
710#[ derive( Default ) ]
811struct Config ;
@@ -22,9 +25,13 @@ pub fn exec(source: &[u8]) -> Result<Table, String> {
2225
2326 let mut state = lu:: State :: new ( ( ) , lu:: DefaultAllocator ) ;
2427 state. open_std ( ) ;
25- state. open_userdata :: < Type > ( ) ;
26- state. open_userdata :: < Event > ( ) ;
27- state. open_userdata :: < Options > ( ) ;
28+ state. open_userdata :: < Type > ( Methods :: default ( ) ) ;
29+ state. open_userdata :: < Event > ( Methods :: default ( ) ) ;
30+ state. open_userdata :: < OptionUserdata > ( Methods :: default ( ) ) ;
31+ state. open_userdata :: < RemoteUserdata > ( Methods :: default ( ) . with_method (
32+ "event" ,
33+ lu:: Function :: norm ( "RemoteUserdata::event" , RemoteUserdata :: event) ,
34+ ) ) ;
2835 state. open_library ( "zap" , library ( ) ) ;
2936 state. sandbox ( ) ;
3037
@@ -52,7 +59,7 @@ pub fn exec(source: &[u8]) -> Result<Table, String> {
5259 Err ( format ! ( "yielded: {trace}" ) )
5360 } ,
5461
55- _ => table ( stack, Rc :: new ( Options :: default ( ) ) ) ,
62+ _ => table ( stack) ,
5663 }
5764}
5865
@@ -62,14 +69,14 @@ pub enum Item {
6269 Event ( Event ) ,
6370}
6471
65- fn table ( stack : & lu:: Stack < Config > , parent : Rc < Options > ) -> Result < Table , String > {
66- let mut options = Rc :: new ( Options :: default ( ) . with_parent ( parent ) ) ;
72+ fn table ( stack : & lu:: Stack < Config > ) -> Result < Table , String > {
73+ let mut options = options :: Node :: from ( options :: Partial :: default ( ) ) ;
6774 let mut items = Vec :: new ( ) ;
6875
6976 let result = stack. iter ( -1 , || {
7077 if stack. to_number ( -2 ) . is_some_and ( |n| n == 1.0 ) {
71- options = match stack. to_userdata :: < Options > ( -1 ) {
72- Some ( options) => Rc :: new ( options. borrow ( ) . clone ( ) ) ,
78+ options = match stack. to_userdata :: < OptionUserdata > ( -1 ) {
79+ Some ( options) => options. borrow ( ) . 0 . clone ( ) ,
7380 None => return ControlFlow :: Break ( "index 1 may only contain options" . to_string ( ) ) ,
7481 } ;
7582 } else {
@@ -79,11 +86,12 @@ fn table(stack: &lu::Stack<Config>, parent: Rc<Options>) -> Result<Table, String
7986
8087 match stack. type_of ( -1 ) {
8188 lu:: Type :: Table => {
82- let table = match table ( stack, options . clone ( ) ) {
89+ let table = match table ( stack) {
8390 Ok ( table) => table,
8491 Err ( err) => return ControlFlow :: Break ( err) ,
8592 } ;
8693
94+ table. opts . set_parent ( options. clone ( ) ) ;
8795 items. push ( ( name. to_owned ( ) , Item :: Table ( table) ) ) ;
8896 }
8997
@@ -107,7 +115,10 @@ fn table(stack: &lu::Stack<Config>, parent: Rc<Options>) -> Result<Table, String
107115 if let Some ( err) = result {
108116 Err ( err)
109117 } else {
110- Ok ( Table { options, items } )
118+ Ok ( Table {
119+ opts : options,
120+ items,
121+ } )
111122 }
112123}
113124
@@ -118,7 +129,7 @@ fn library() -> lu::Library<Config> {
118129
119130 lu:: Library :: default ( )
120131 . with_function_norm ( "options" , options)
121- . with_function_norm ( "event " , event )
132+ . with_function_norm ( "remote " , remote )
122133 . with_function_norm ( "boolean" , boolean)
123134 . with_function_norm ( "u8" , u8)
124135 . with_function_norm ( "u16" , u16)
@@ -143,12 +154,15 @@ fn library() -> lu::Library<Config> {
143154
144155#[ derive( Clone ) ]
145156pub struct Table {
146- pub options : Rc < Options > ,
157+ pub opts : options :: Node ,
147158 pub items : Vec < ( String , Item ) > ,
148159}
149160
161+ #[ derive( lu:: Userdata ) ]
162+ pub struct OptionUserdata ( options:: Node ) ;
163+
150164extern "C-unwind" fn options ( ctx : Context ) -> lu:: FnReturn {
151- let mut options = Options :: default ( ) ;
165+ let mut options = options :: Partial :: default ( ) ;
152166 ctx. arg_table ( 1 ) ;
153167
154168 ctx. iter ( 1 , || {
@@ -162,7 +176,7 @@ extern "C-unwind" fn options(ctx: Context) -> lu::FnReturn {
162176 _ => ctx. error_msg ( "apicheck must be 'none', 'some', or 'full'" ) ,
163177 } ;
164178
165- options = options . clone ( ) . with_apicheck ( value) ;
179+ options. apicheck = Some ( value)
166180 }
167181
168182 Some ( "casing" ) => {
@@ -175,7 +189,7 @@ extern "C-unwind" fn options(ctx: Context) -> lu::FnReturn {
175189 _ => ctx. error_msg ( "casing must be 'lower', 'snake', 'camel', or 'pascal'" ) ,
176190 } ;
177191
178- options = options . clone ( ) . with_casing ( value) ;
192+ options. casing = Some ( value) ;
179193 }
180194
181195 Some ( str) => ctx. error_msg ( format ! ( "unknown option: {str}" ) ) ,
@@ -185,45 +199,57 @@ extern "C-unwind" fn options(ctx: Context) -> lu::FnReturn {
185199 ControlFlow :: < ( ) > :: Continue ( ( ) )
186200 } ) ;
187201
188- ctx. push_userdata ( options) ;
202+ ctx. push_userdata ( OptionUserdata ( options:: Node :: from ( options ) ) ) ;
189203 ctx. ret_with ( 1 )
190204}
191205
192206#[ derive( lu:: Userdata , Clone ) ]
193207pub struct Event {
194- pub uuid : Uuid ,
208+ pub thru : Remote ,
195209 pub from : NetworkSide ,
196210 pub data : Vec < Type > ,
197211}
198212
199- extern "C-unwind" fn event ( ctx : Context ) -> lu:: FnReturn {
200- let from = ctx. arg_string_str ( 1 ) ;
201- ctx. arg_table ( 2 ) ;
213+ #[ derive( lu:: Userdata ) ]
214+ pub struct RemoteUserdata ( Remote ) ;
202215
203- let uuid = Uuid :: new_v4 ( ) ;
204- let from = match from {
205- "server" => NetworkSide :: Server ,
206- "client" => NetworkSide :: Client ,
216+ impl RemoteUserdata {
217+ extern "C-unwind" fn event ( ctx : Context ) -> lu:: FnReturn {
218+ let remote = ctx. arg_userdata :: < RemoteUserdata > ( 1 ) ;
219+ let from = ctx. arg_string_str ( 2 ) ;
220+ ctx. arg_table ( 3 ) ;
207221
208- _ => ctx. arg_error ( 1 , c"must be 'server' or 'client'" ) ,
209- } ;
222+ let thru = remote. borrow ( ) . 0 . clone ( ) ;
210223
211- let mut data = Vec :: new ( ) ;
212- ctx. iter ( 2 , || {
213- if !ctx. is_number ( -2 ) {
214- ctx. error_msg ( "event data must be an array" )
215- }
224+ let from = match from {
225+ "server" => NetworkSide :: Server ,
226+ "client" => NetworkSide :: Client ,
216227
217- if let Some ( item) = ctx. to_userdata :: < Type > ( -1 ) {
218- data. push ( item. borrow ( ) . clone ( ) ) ;
219- } else {
220- ctx. error_msg ( "event data must be a type" ) ;
221- }
228+ _ => ctx. arg_error ( 2 , c"must be 'server' or 'client'" ) ,
229+ } ;
222230
223- ControlFlow :: < ( ) > :: Continue ( ( ) )
224- } ) ;
231+ let mut data = Vec :: new ( ) ;
232+ ctx. iter ( 3 , || {
233+ if !ctx. is_number ( -2 ) {
234+ ctx. error_msg ( "event data must be an array" )
235+ }
236+
237+ if let Some ( item) = ctx. to_userdata :: < Type > ( -1 ) {
238+ data. push ( item. borrow ( ) . clone ( ) ) ;
239+ } else {
240+ ctx. error_msg ( "event data must be a type" ) ;
241+ }
242+
243+ ControlFlow :: < ( ) > :: Continue ( ( ) )
244+ } ) ;
245+
246+ ctx. push_userdata ( Event { thru, from, data } ) ;
247+ ctx. ret_with ( 1 )
248+ }
249+ }
225250
226- ctx. push_userdata ( Event { uuid, from, data } ) ;
251+ extern "C-unwind" fn remote ( ctx : Context ) -> lu:: FnReturn {
252+ ctx. push_userdata ( RemoteUserdata ( Remote :: default ( ) ) ) ;
227253 ctx. ret_with ( 1 )
228254}
229255
0 commit comments