Skip to content

Commit 2020b87

Browse files
committed
table form
1 parent 531d82f commit 2020b87

8 files changed

Lines changed: 361 additions & 196 deletions

File tree

prebindgen-ext/src/core/functions_converter.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use quote::{format_ident, quote, ToTokens};
3333

3434
use prebindgen::SourceLocation;
3535

36-
use crate::core::inline_fn::{InputFn, OutputFn};
36+
use crate::core::inline_fn::{InputFn, NO_INPUT, NO_OUTPUT, OutputFn};
3737
use crate::core::name_mangler::NameMangler;
3838
use crate::core::type_registry::TypeRegistry;
3939
use crate::util::is_unit;
@@ -159,7 +159,13 @@ impl FunctionsBuilder {
159159
rust_type: impl AsRef<str>,
160160
wire_type: impl AsRef<str>,
161161
) -> Self {
162-
self.types = self.types.type_pair(rust_type, wire_type).finish();
162+
let rust_type = rust_type.as_ref().to_owned();
163+
self.types = self.types.type_pair(
164+
&rust_type,
165+
wire_type,
166+
NO_INPUT,
167+
NO_OUTPUT,
168+
);
163169
self
164170
}
165171

prebindgen-ext/src/core/inline_fn.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,50 @@ use std::sync::Arc;
88
use proc_macro2::TokenStream;
99

1010
#[derive(Clone)]
11-
pub struct InputFn(Arc<dyn Fn(&syn::Ident) -> TokenStream + Send + Sync>);
11+
pub struct InputFn(Option<Arc<dyn Fn(&syn::Ident) -> TokenStream + Send + Sync>>);
1212

1313
impl InputFn {
1414
pub fn new<F>(f: F) -> Self
1515
where
1616
F: Fn(&syn::Ident) -> TokenStream + Send + Sync + 'static,
1717
{
18-
InputFn(Arc::new(f))
18+
InputFn(Some(Arc::new(f)))
19+
}
20+
21+
pub fn unimplemented(_message: impl Into<String>) -> Self {
22+
InputFn(None)
1923
}
2024

2125
pub(crate) fn call(&self, ident: &syn::Ident) -> TokenStream {
22-
(self.0)(ident)
26+
self.0.as_ref().expect("missing input conversion")(ident)
2327
}
2428
}
2529

30+
pub const NO_INPUT: InputFn = InputFn(None);
31+
2632
#[derive(Clone)]
27-
pub struct OutputFn(Arc<dyn Fn(Option<&syn::Ident>) -> TokenStream + Send + Sync>);
33+
pub struct OutputFn(Option<Arc<dyn Fn(Option<&syn::Ident>) -> TokenStream + Send + Sync>>);
2834

2935
impl OutputFn {
3036
pub fn new<F>(f: F) -> Self
3137
where
3238
F: Fn(Option<&syn::Ident>) -> TokenStream + Send + Sync + 'static,
3339
{
34-
OutputFn(Arc::new(f))
40+
OutputFn(Some(Arc::new(f)))
41+
}
42+
43+
pub fn unimplemented(_message: impl Into<String>) -> Self {
44+
OutputFn(None)
3545
}
3646

3747
pub(crate) fn call(&self, ident: Option<&syn::Ident>) -> TokenStream {
38-
(self.0)(ident)
48+
self.0.as_ref().expect("missing output conversion")(ident)
49+
}
50+
51+
pub(crate) fn is_implemented(&self) -> bool {
52+
self.0.is_some()
3953
}
4054
}
4155

56+
pub const NO_OUTPUT: OutputFn = OutputFn(None);
57+

prebindgen-ext/src/core/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ pub mod types_converter;
3030
pub use functions_converter::{
3131
BodyContext, BodyStrategy, FunctionsBuilder, FunctionsConverter, PassThroughBody,
3232
};
33-
pub use inline_fn::{InputFn, OutputFn};
33+
pub use inline_fn::{InputFn, NO_INPUT, NO_OUTPUT, OutputFn};
3434
pub use name_mangler::NameMangler;
35-
pub use type_registry::{primitive_builtins, TypePairBuilder, TypeRegistry};
35+
pub use type_registry::{primitive_builtins, TypeRegistry};
3636
pub use types_converter::{StructStrategy, TypesBuilder, TypesConverter};

prebindgen-ext/src/core/type_registry.rs

Lines changed: 41 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -6,69 +6,33 @@ use std::collections::HashMap;
66
use proc_macro2::TokenStream;
77
use quote::quote;
88

9-
use crate::core::inline_fn::{InputFn, OutputFn};
9+
use crate::core::inline_fn::{InputFn, NO_OUTPUT, OutputFn};
1010
use crate::core::type_binding::{canon_type, TypeBinding};
1111

1212
#[derive(Default, Clone)]
1313
pub struct TypeRegistry {
1414
pub(crate) types: HashMap<String, TypeBinding>,
1515
}
1616

17-
pub struct TypePairBuilder {
18-
registry: TypeRegistry,
19-
rust_type: String,
20-
}
21-
22-
impl TypePairBuilder {
23-
/// Add or replace the input conversion function for the current
24-
/// Rust type pair.
25-
pub fn input(mut self, decode: InputFn) -> Self {
26-
self.registry
27-
.add_input_conversion_function_mut(&self.rust_type, decode);
28-
self
29-
}
30-
31-
/// Add or replace the output conversion function for the current
32-
/// Rust type pair.
33-
pub fn output(mut self, encode: OutputFn) -> Self {
34-
self.registry
35-
.add_output_conversion_function_mut(&self.rust_type, encode);
36-
self
37-
}
38-
39-
/// Add or replace a new Rust/Wire type pair and continue chaining
40-
/// conversions against that new pair.
41-
pub fn type_pair(
42-
self,
43-
rust_type: impl AsRef<str>,
44-
wire_type: impl AsRef<str>,
45-
) -> TypePairBuilder {
46-
self.finish().type_pair(rust_type, wire_type)
47-
}
48-
49-
/// Return to the owning [`TypeRegistry`].
50-
pub fn finish(self) -> TypeRegistry {
51-
self.registry
52-
}
53-
}
54-
5517
impl TypeRegistry {
5618
pub fn new() -> Self {
5719
Self::default()
5820
}
5921

60-
/// Add or replace a Rust/Wire type pair.
22+
/// Add or replace a Rust/Wire type pair together with conversion
23+
/// functions used for wire-to-Rust (`input`) and Rust-to-wire (`output`).
6124
pub fn type_pair(
6225
mut self,
6326
rust_type: impl AsRef<str>,
6427
wire_type: impl AsRef<str>,
65-
) -> TypePairBuilder {
66-
let rust_type = rust_type.as_ref().to_owned();
67-
self.add_type_pair_mut(&rust_type, wire_type);
68-
TypePairBuilder {
69-
registry: self,
70-
rust_type,
71-
}
28+
input: InputFn,
29+
output: OutputFn,
30+
) -> Self {
31+
let rust_type = rust_type.as_ref();
32+
self.add_type_pair_mut(rust_type, wire_type);
33+
self.add_input_conversion_function_mut(rust_type, input);
34+
self.add_output_conversion_function_mut(rust_type, output);
35+
self
7236
}
7337

7438
/// Add or replace the input conversion function for an already
@@ -165,30 +129,39 @@ impl TypeRegistry {
165129
/// Kept here as a free function so the universal core has no opinion
166130
/// about which primitives are pre-registered.
167131
pub fn primitive_builtins() -> TypeRegistry {
132+
let bool_input = InputFn::new(|input: &syn::Ident| -> TokenStream {
133+
quote! { #input != 0 }
134+
});
135+
let id_input = InputFn::new(|input: &syn::Ident| -> TokenStream {
136+
quote! { #input }
137+
});
138+
let duration_input = InputFn::new(|input: &syn::Ident| -> TokenStream {
139+
quote! { std::time::Duration::from_millis(#input as u64) }
140+
});
141+
168142
TypeRegistry::new()
169-
.type_pair("bool", "jni::sys::jboolean")
170-
.input(
171-
InputFn::new(|input: &syn::Ident| -> TokenStream {
172-
quote! { #input != 0 }
173-
}),
143+
.type_pair(
144+
"bool",
145+
"jni::sys::jboolean",
146+
bool_input,
147+
NO_OUTPUT,
174148
)
175-
.type_pair("i64", "jni::sys::jlong")
176-
.input(
177-
InputFn::new(|input: &syn::Ident| -> TokenStream {
178-
quote! { #input }
179-
}),
149+
.type_pair(
150+
"i64",
151+
"jni::sys::jlong",
152+
id_input.clone(),
153+
NO_OUTPUT,
180154
)
181-
.type_pair("f64", "jni::sys::jdouble")
182-
.input(
183-
InputFn::new(|input: &syn::Ident| -> TokenStream {
184-
quote! { #input }
185-
}),
155+
.type_pair(
156+
"f64",
157+
"jni::sys::jdouble",
158+
id_input,
159+
NO_OUTPUT,
186160
)
187-
.type_pair("Duration", "jni::sys::jlong")
188-
.input(
189-
InputFn::new(|input: &syn::Ident| -> TokenStream {
190-
quote! { std::time::Duration::from_millis(#input as u64) }
191-
}),
161+
.type_pair(
162+
"Duration",
163+
"jni::sys::jlong",
164+
duration_input,
165+
NO_OUTPUT,
192166
)
193-
.finish()
194167
}

prebindgen-ext/src/core/types_converter.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use quote::ToTokens;
1212

1313
use prebindgen::SourceLocation;
1414

15-
use crate::core::inline_fn::{InputFn, OutputFn};
15+
use crate::core::inline_fn::{InputFn, NO_INPUT, NO_OUTPUT, OutputFn};
1616
use crate::core::type_registry::TypeRegistry;
1717

1818
/// Strategy for translating one `#[prebindgen]` struct into output items.
@@ -50,7 +50,13 @@ impl TypesBuilder {
5050
rust_type: impl AsRef<str>,
5151
wire_type: impl AsRef<str>,
5252
) -> Self {
53-
self.types = self.types.type_pair(rust_type, wire_type).finish();
53+
let rust_type = rust_type.as_ref().to_owned();
54+
self.types = self.types.type_pair(
55+
&rust_type,
56+
wire_type,
57+
NO_INPUT,
58+
NO_OUTPUT,
59+
);
5460
self
5561
}
5662

prebindgen-ext/src/jni/struct_strategy.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ impl StructStrategy for JniDecoderStruct {
156156
field_init.push(quote! { #fname_ident });
157157

158158
// Check if encoder is available for this field
159-
if let Some(encode) = binding.encode() {
159+
if let Some(encode) = binding.encode().filter(|encode| encode.is_implemented()) {
160160
let field_ref_ident = format_ident!("__{}_value", fname_ident);
161161
let encoded_ident = format_ident!("__{}_encoded", fname_ident);
162162
let encode_expr = encode.call(Some(&field_ref_ident));

prebindgen-ext/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ mod util;
1313

1414
pub use core::{
1515
BodyContext, BodyStrategy, FunctionsBuilder, FunctionsConverter, NameMangler,
16-
PassThroughBody, StructStrategy, TypePairBuilder, TypeRegistry, TypesBuilder, TypesConverter,
16+
PassThroughBody, StructStrategy, TypeRegistry, TypesBuilder, TypesConverter,
1717
};
1818
pub use jni::{JniDecoderStruct, JniTryClosureBody};
1919
pub use kotlin::{KotlinInterfaceBuilder, KotlinInterfaceGenerator, KotlinTypeMap};

0 commit comments

Comments
 (0)