Skip to content

Commit 3e139b7

Browse files
committed
feat: Refactored int primitives with BigInt support and bounds checking
1 parent 050fda4 commit 3e139b7

File tree

2 files changed

+57
-198
lines changed

2 files changed

+57
-198
lines changed

src/gen/primitives/macros.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ macro_rules! impl_renderable_for_primitive {
6868
}
6969
}
7070
};
71+
// Variant without bounds checking (for floats, etc.)
7172
($T:ty, $class_name:literal, $canonical_name:literal, $allocation_size:literal) => {
7273
impl Renderable for $T {
7374
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
@@ -111,4 +112,45 @@ macro_rules! impl_renderable_for_primitive {
111112
}
112113
}
113114
};
115+
// Variant with bounds checking (for integers)
116+
($T:ty, $class_name:literal, $canonical_name:literal, $allocation_size:literal, $min_value:literal, $max_value:literal, $type_name:literal) => {
117+
impl Renderable for $T {
118+
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
119+
let cl_name = &self.ffi_converter_name();
120+
let type_signature = &self.type_label();
121+
let conversion_name = &$canonical_name
122+
.replace("UInt", "Uint")
123+
.replace("Double", "Float");
124+
125+
// Pre-compute the error message to avoid string interpolation conflicts
126+
let error_message = format!("\"Value out of range for {}: \" + value.toString()", $type_name);
127+
128+
quote! {
129+
class $cl_name {
130+
static $type_signature lift($type_signature value) => value;
131+
132+
static LiftRetVal<$type_signature> read(Uint8List buf) {
133+
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).get$conversion_name(0), $allocation_size);
134+
}
135+
136+
static $type_signature lower($type_signature value) {
137+
if (value < $min_value || value > $max_value) {
138+
throw ArgumentError($error_message);
139+
}
140+
return value;
141+
}
142+
143+
static int allocationSize([$type_signature value = 0]) {
144+
return $allocation_size;
145+
}
146+
147+
static int write($type_signature value, Uint8List buf) {
148+
buf.buffer.asByteData(buf.offsetInBytes).set$conversion_name(0, lower(value));
149+
return $allocation_size;
150+
}
151+
}
152+
}
153+
}
154+
}
155+
};
114156
}

src/gen/primitives/mod.rs

Lines changed: 15 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -157,201 +157,18 @@ impl Renderable for UInt64CodeType {
157157
}
158158
}
159159

160-
// Custom implementations for smaller integer types with bounds checking
161-
impl Renderable for Int8CodeType {
162-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
163-
let cl_name = &self.ffi_converter_name();
164-
let type_signature = &self.type_label();
165-
166-
quote! {
167-
class $cl_name {
168-
static $type_signature lift($type_signature value) => value;
169-
170-
static LiftRetVal<$type_signature> read(Uint8List buf) {
171-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getInt8(0), 1);
172-
}
173-
174-
static $type_signature lower($type_signature value) {
175-
if (value < -128 || value > 127) {
176-
throw ArgumentError("Value out of range for i8: " + value.toString());
177-
}
178-
return value;
179-
}
180-
181-
static int allocationSize([$type_signature value = 0]) {
182-
return 1;
183-
}
184-
185-
static int write($type_signature value, Uint8List buf) {
186-
buf.buffer.asByteData(buf.offsetInBytes).setInt8(0, lower(value));
187-
return 1;
188-
}
189-
}
190-
}
191-
}
192-
}
193-
194-
impl Renderable for Int16CodeType {
195-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
196-
let cl_name = &self.ffi_converter_name();
197-
let type_signature = &self.type_label();
198-
199-
quote! {
200-
class $cl_name {
201-
static $type_signature lift($type_signature value) => value;
202-
203-
static LiftRetVal<$type_signature> read(Uint8List buf) {
204-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getInt16(0), 2);
205-
}
206-
207-
static $type_signature lower($type_signature value) {
208-
if (value < -32768 || value > 32767) {
209-
throw ArgumentError("Value out of range for i16: " + value.toString());
210-
}
211-
return value;
212-
}
213-
214-
static int allocationSize([$type_signature value = 0]) {
215-
return 2;
216-
}
217-
218-
static int write($type_signature value, Uint8List buf) {
219-
buf.buffer.asByteData(buf.offsetInBytes).setInt16(0, lower(value));
220-
return 2;
221-
}
222-
}
223-
}
224-
}
225-
}
226-
227-
impl Renderable for Int32CodeType {
228-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
229-
let cl_name = &self.ffi_converter_name();
230-
let type_signature = &self.type_label();
231-
232-
quote! {
233-
class $cl_name {
234-
static $type_signature lift($type_signature value) => value;
235-
236-
static LiftRetVal<$type_signature> read(Uint8List buf) {
237-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getInt32(0), 4);
238-
}
239-
240-
static $type_signature lower($type_signature value) {
241-
if (value < -2147483648 || value > 2147483647) {
242-
throw ArgumentError("Value out of range for i32: " + value.toString());
243-
}
244-
return value;
245-
}
246-
247-
static int allocationSize([$type_signature value = 0]) {
248-
return 4;
249-
}
250-
251-
static int write($type_signature value, Uint8List buf) {
252-
buf.buffer.asByteData(buf.offsetInBytes).setInt32(0, lower(value));
253-
return 4;
254-
}
255-
}
256-
}
257-
}
258-
}
259-
260-
impl Renderable for UInt8CodeType {
261-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
262-
let cl_name = &self.ffi_converter_name();
263-
let type_signature = &self.type_label();
264-
265-
quote! {
266-
class $cl_name {
267-
static $type_signature lift($type_signature value) => value;
268-
269-
static LiftRetVal<$type_signature> read(Uint8List buf) {
270-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getUint8(0), 1);
271-
}
272-
273-
static $type_signature lower($type_signature value) {
274-
if (value < 0 || value > 255) {
275-
throw ArgumentError("Value out of range for u8: " + value.toString());
276-
}
277-
return value;
278-
}
279-
280-
static int allocationSize([$type_signature value = 0]) {
281-
return 1;
282-
}
283-
284-
static int write($type_signature value, Uint8List buf) {
285-
buf.buffer.asByteData(buf.offsetInBytes).setUint8(0, lower(value));
286-
return 1;
287-
}
288-
}
289-
}
290-
}
291-
}
292-
293-
impl Renderable for UInt16CodeType {
294-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
295-
let cl_name = &self.ffi_converter_name();
296-
let type_signature = &self.type_label();
297-
298-
quote! {
299-
class $cl_name {
300-
static $type_signature lift($type_signature value) => value;
301-
302-
static LiftRetVal<$type_signature> read(Uint8List buf) {
303-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getUint16(0), 2);
304-
}
305-
306-
static $type_signature lower($type_signature value) {
307-
if (value < 0 || value > 65535) {
308-
throw ArgumentError("Value out of range for u16: " + value.toString());
309-
}
310-
return value;
311-
}
312-
313-
static int allocationSize([$type_signature value = 0]) {
314-
return 2;
315-
}
316-
317-
static int write($type_signature value, Uint8List buf) {
318-
buf.buffer.asByteData(buf.offsetInBytes).setUint16(0, lower(value));
319-
return 2;
320-
}
321-
}
322-
}
323-
}
324-
}
325-
326-
impl Renderable for UInt32CodeType {
327-
fn render_type_helper(&self, _type_helper: &dyn TypeHelperRenderer) -> dart::Tokens {
328-
let cl_name = &self.ffi_converter_name();
329-
let type_signature = &self.type_label();
330-
331-
quote! {
332-
class $cl_name {
333-
static $type_signature lift($type_signature value) => value;
334-
335-
static LiftRetVal<$type_signature> read(Uint8List buf) {
336-
return LiftRetVal(buf.buffer.asByteData(buf.offsetInBytes).getUint32(0), 4);
337-
}
338-
339-
static $type_signature lower($type_signature value) {
340-
if (value < 0 || value > 4294967295) {
341-
throw ArgumentError("Value out of range for u32: " + value.toString());
342-
}
343-
return value;
344-
}
345-
346-
static int allocationSize([$type_signature value = 0]) {
347-
return 4;
348-
}
349-
350-
static int write($type_signature value, Uint8List buf) {
351-
buf.buffer.asByteData(buf.offsetInBytes).setUint32(0, lower(value));
352-
return 4;
353-
}
354-
}
355-
}
356-
}
357-
}
160+
// Use the unified macro with bounds checking for integer types
161+
impl_renderable_for_primitive!(Int8CodeType, "int", "Int8", 1, -128, 127, "i8");
162+
impl_renderable_for_primitive!(Int16CodeType, "int", "Int16", 2, -32768, 32767, "i16");
163+
impl_renderable_for_primitive!(
164+
Int32CodeType,
165+
"int",
166+
"Int32",
167+
4,
168+
-2147483648,
169+
2147483647,
170+
"i32"
171+
);
172+
impl_renderable_for_primitive!(UInt8CodeType, "int", "UInt8", 1, 0, 255, "u8");
173+
impl_renderable_for_primitive!(UInt16CodeType, "int", "UInt16", 2, 0, 65535, "u16");
174+
impl_renderable_for_primitive!(UInt32CodeType, "int", "UInt32", 4, 0, 4294967295, "u32");

0 commit comments

Comments
 (0)