4343//! .throw_exception("crate::throw_exception")
4444//! .string_decoder("crate::utils::decode_string")
4545//! .byte_array_decoder("crate::utils::decode_byte_array")
46- //! .struct_decoder(
47- //! "KeyExpr",
48- //! "crate::key_expr::decode_jni_key_expr",
49- //! "JNIKeyExpr",
46+ //! .type_binding(
47+ //! TypeBinding::new("KeyExpr").kotlin("JNIKeyExpr").consume(
48+ //! JniForm::new(
49+ //! "jni::objects::JObject",
50+ //! "JObject",
51+ //! ArgDecode::env_ref_mut("crate::key_expr::decode_jni_key_expr"),
52+ //! ),
53+ //! ),
5054//! )
5155//! .build();
5256//! source
@@ -111,6 +115,36 @@ pub enum ArgDecode {
111115 ConsumeArc ,
112116}
113117
118+ impl ArgDecode {
119+ /// `ArgDecode::Pure` from a path string (parsed lazily).
120+ pub fn pure ( path : impl AsRef < str > ) -> Self {
121+ ArgDecode :: Pure ( syn:: parse_str ( path. as_ref ( ) ) . expect ( "invalid ArgDecode::pure path" ) )
122+ }
123+
124+ /// `ArgDecode::EnvRefMut` from a path string.
125+ pub fn env_ref_mut ( path : impl AsRef < str > ) -> Self {
126+ ArgDecode :: EnvRefMut (
127+ syn:: parse_str ( path. as_ref ( ) ) . expect ( "invalid ArgDecode::env_ref_mut path" ) ,
128+ )
129+ }
130+
131+ /// `ArgDecode::EnvByVal` from a path string.
132+ pub fn env_by_val ( path : impl AsRef < str > ) -> Self {
133+ ArgDecode :: EnvByVal (
134+ syn:: parse_str ( path. as_ref ( ) ) . expect ( "invalid ArgDecode::env_by_val path" ) ,
135+ )
136+ }
137+ }
138+
139+ impl ReturnEncode {
140+ /// `ReturnEncode::Wrapper` from a path string.
141+ pub fn wrapper ( path : impl AsRef < str > ) -> Self {
142+ ReturnEncode :: Wrapper (
143+ syn:: parse_str ( path. as_ref ( ) ) . expect ( "invalid ReturnEncode::wrapper path" ) ,
144+ )
145+ }
146+ }
147+
114148/// Clonable closure that produces a TokenStream from the JNI input ident.
115149#[ derive( Clone ) ]
116150pub struct InlineFn ( Arc < dyn Fn ( & syn:: Ident ) -> TokenStream + Send + Sync > ) ;
@@ -444,62 +478,13 @@ impl Builder {
444478 self
445479 }
446480
447- /// Register a decoder for an enum type. Equivalent to:
448- /// ```ignore
449- /// .type_binding(TypeBinding::new(name)
450- /// .consume(JniForm::new("jni::sys::jint", "Int", ArgDecode::Pure(<path>))))
451- /// ```
452- pub fn enum_decoder (
453- mut self ,
454- type_name : impl Into < String > ,
455- decoder : impl AsRef < str > ,
456- ) -> Self {
457- let name = type_name. into ( ) ;
458- let p: syn:: Path =
459- syn:: parse_str ( decoder. as_ref ( ) ) . expect ( "invalid enum_decoder path" ) ;
460- let binding = self
461- . types
462- . entry ( name. clone ( ) )
463- . or_insert_with ( || TypeBinding :: new ( name) ) ;
464- binding. consume = Some ( JniForm :: new (
465- "jni::sys::jint" ,
466- "Int" ,
467- ArgDecode :: Pure ( p) ,
468- ) ) ;
469- self
470- }
471-
472- /// Register a decoder for a struct parameter passed across JNI as a plain
473- /// `JObject` (typically a Kotlin data class). The decoder must have
474- /// signature `fn(&mut JNIEnv, &JObject) -> ZResult<T>`. `kotlin_type` is
475- /// the Kotlin type name (FQN if out-of-package, bare otherwise).
476- pub fn struct_decoder (
477- mut self ,
478- type_name : impl Into < String > ,
479- decoder : impl AsRef < str > ,
480- kotlin_type : impl Into < String > ,
481- ) -> Self {
482- let name = type_name. into ( ) ;
483- let kt = kotlin_type. into ( ) ;
484- let p: syn:: Path =
485- syn:: parse_str ( decoder. as_ref ( ) ) . expect ( "invalid struct_decoder path" ) ;
486- let binding = self
487- . types
488- . entry ( name. clone ( ) )
489- . or_insert_with ( || TypeBinding :: new ( name) ) ;
490- binding. kotlin_type = Some ( kt) ;
491- binding. consume = Some ( JniForm :: new (
492- "jni::objects::JObject" ,
493- "JObject" ,
494- ArgDecode :: EnvRefMut ( p) ,
495- ) ) ;
496- self
497- }
498-
499481 /// Register a decoder for an `impl Fn(T) + Send + Sync + 'static` callback
500482 /// parameter. `element_type_name` is the last path segment of `T`
501483 /// (e.g. `"Sample"`, `"Query"`, `"Reply"`). The decoder must have
502484 /// signature `fn(&mut JNIEnv, JObject) -> ZResult<impl Fn(T) + Send + Sync + 'static>`.
485+ /// Callbacks have a fundamentally different shape (a closure-builder, not
486+ /// a value decoder) so they are registered separately from
487+ /// [`Builder::type_binding`].
503488 pub fn callback_decoder (
504489 mut self ,
505490 element_type_name : impl Into < String > ,
@@ -515,56 +500,6 @@ impl Builder {
515500 self
516501 }
517502
518- /// Register a return-type wrapper for `ZResult<T>` where `T`'s
519- /// last-segment name equals `type_name`. `wrap_fn` must have signature
520- /// `fn(&mut JNIEnv, T) -> ZResult<jni_type>`. `default_expr` is the value
521- /// returned on error (before the exception is thrown on the JVM side).
522- pub fn return_wrapper (
523- mut self ,
524- type_name : impl Into < String > ,
525- jni_type : impl AsRef < str > ,
526- wrap_fn : impl AsRef < str > ,
527- default_expr : impl AsRef < str > ,
528- kotlin_type : impl Into < String > ,
529- ) -> Self {
530- let name = type_name. into ( ) ;
531- let kt = kotlin_type. into ( ) ;
532- let wrap: syn:: Path =
533- syn:: parse_str ( wrap_fn. as_ref ( ) ) . expect ( "invalid return_wrapper wrap_fn path" ) ;
534- let mut form = ReturnForm :: new ( jni_type, ReturnEncode :: Wrapper ( wrap) , default_expr) ;
535- form. kotlin_jni_type = Some ( kt) ;
536- let binding = self
537- . types
538- . entry ( name. clone ( ) )
539- . or_insert_with ( || TypeBinding :: new ( name) ) ;
540- binding. returns = Some ( form) ;
541- self
542- }
543-
544- /// Like [`Builder::return_wrapper`] but applies when `T` is `Vec<E>`
545- /// with `E`'s last-segment name equal to `element_type_name`.
546- pub fn return_wrapper_vec (
547- mut self ,
548- element_type_name : impl Into < String > ,
549- jni_type : impl AsRef < str > ,
550- wrap_fn : impl AsRef < str > ,
551- default_expr : impl AsRef < str > ,
552- kotlin_type : impl Into < String > ,
553- ) -> Self {
554- let name = element_type_name. into ( ) ;
555- let kt = kotlin_type. into ( ) ;
556- let wrap: syn:: Path =
557- syn:: parse_str ( wrap_fn. as_ref ( ) ) . expect ( "invalid return_wrapper_vec wrap_fn path" ) ;
558- let mut form = ReturnForm :: new ( jni_type, ReturnEncode :: Wrapper ( wrap) , default_expr) ;
559- form. kotlin_jni_type = Some ( kt) ;
560- let binding = self
561- . types
562- . entry ( name. clone ( ) )
563- . or_insert_with ( || TypeBinding :: new ( name) ) ;
564- binding. returns_vec = Some ( form) ;
565- self
566- }
567-
568503 /// Enable Kotlin-side prototype generation. `path` is where the `.kt`
569504 /// file will be written when [`JniConverter::write_kotlin`] is called.
570505 pub fn kotlin_output ( mut self , path : impl Into < PathBuf > ) -> Self {
0 commit comments