From 2c92c6180ad0d14f3b7bbd6a3a82b7b93dbcd279 Mon Sep 17 00:00:00 2001 From: Raphael Taylor-Davies Date: Wed, 8 Jun 2022 11:34:42 +0100 Subject: [PATCH 1/2] Seal ArrowNativeType (#1028) --- arrow/src/datatypes/native.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arrow/src/datatypes/native.rs b/arrow/src/datatypes/native.rs index 2a8c99f0f89..b6abda3c9d8 100644 --- a/arrow/src/datatypes/native.rs +++ b/arrow/src/datatypes/native.rs @@ -19,6 +19,10 @@ use super::DataType; use half::f16; use serde_json::{Number, Value}; +mod private { + pub trait Sealed {} +} + /// Trait declaring any type that is serializable to JSON. This includes all primitive types (bool, i32, etc.). pub trait JsonSerializable: 'static { fn into_json_value(self) -> Option; @@ -37,6 +41,7 @@ pub trait ArrowNativeType: + std::str::FromStr + Default + JsonSerializable + + private::Sealed { /// Convert native type from usize. #[inline] @@ -109,6 +114,7 @@ impl JsonSerializable for i8 { } } +impl private::Sealed for i8 {} impl ArrowNativeType for i8 { #[inline] fn from_usize(v: usize) -> Option { @@ -132,6 +138,7 @@ impl JsonSerializable for i16 { } } +impl private::Sealed for i16 {} impl ArrowNativeType for i16 { #[inline] fn from_usize(v: usize) -> Option { @@ -155,6 +162,7 @@ impl JsonSerializable for i32 { } } +impl private::Sealed for i32 {} impl ArrowNativeType for i32 { #[inline] fn from_usize(v: usize) -> Option { @@ -184,6 +192,7 @@ impl JsonSerializable for i64 { } } +impl private::Sealed for i64 {} impl ArrowNativeType for i64 { #[inline] fn from_usize(v: usize) -> Option { @@ -217,6 +226,7 @@ impl JsonSerializable for i128 { } } +impl private::Sealed for i128 {} impl ArrowNativeType for i128 { #[inline] fn from_usize(v: usize) -> Option { @@ -246,6 +256,7 @@ impl JsonSerializable for u8 { } } +impl private::Sealed for u8 {} impl ArrowNativeType for u8 { #[inline] fn from_usize(v: usize) -> Option { @@ -269,6 +280,7 @@ impl JsonSerializable for u16 { } } +impl private::Sealed for u16 {} impl ArrowNativeType for u16 { #[inline] fn from_usize(v: usize) -> Option { @@ -292,6 +304,7 @@ impl JsonSerializable for u32 { } } +impl private::Sealed for u32 {} impl ArrowNativeType for u32 { #[inline] fn from_usize(v: usize) -> Option { @@ -315,6 +328,7 @@ impl JsonSerializable for u64 { } } +impl private::Sealed for u64 {} impl ArrowNativeType for u64 { #[inline] fn from_usize(v: usize) -> Option { @@ -351,8 +365,11 @@ impl JsonSerializable for f64 { } impl ArrowNativeType for f16 {} +impl private::Sealed for f16 {} impl ArrowNativeType for f32 {} +impl private::Sealed for f32 {} impl ArrowNativeType for f64 {} +impl private::Sealed for f64 {} /// Allows conversion from supported Arrow types to a byte slice. pub trait ToByteSlice { From a64575e5bb642035ff3c3a17d3e003af7416269c Mon Sep 17 00:00:00 2001 From: Raphael Taylor-Davies Date: Wed, 8 Jun 2022 15:59:45 +0100 Subject: [PATCH 2/2] Add docs --- arrow/src/datatypes/native.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arrow/src/datatypes/native.rs b/arrow/src/datatypes/native.rs index b6abda3c9d8..efb1d3e6b2d 100644 --- a/arrow/src/datatypes/native.rs +++ b/arrow/src/datatypes/native.rs @@ -30,8 +30,25 @@ pub trait JsonSerializable: 'static { /// Trait expressing a Rust type that has the same in-memory representation /// as Arrow. This includes `i16`, `f32`, but excludes `bool` (which in arrow is represented in bits). +/// /// In little endian machines, types that implement [`ArrowNativeType`] can be memcopied to arrow buffers /// as is. +/// +/// # Transmute Safety +/// +/// A type T implementing this trait means that any arbitrary slice of bytes of length and +/// alignment `size_of::()` can be safely interpreted as a value of that type without +/// being unsound, i.e. potentially resulting in undefined behaviour. +/// +/// Note: in the case of floating point numbers this transmutation can result in a signalling +/// NaN, which, whilst sound, can be unwieldy. In general, whilst it is perfectly sound to +/// reinterpret bytes as different types using this trait, it is likely unwise +/// +/// Note: `bool` is restricted to `0` or `1`, and so `bool: !ArrowNativeType` +/// +/// # Sealed +/// +/// Due to the above restrictions, this trait is sealed to prevent accidental misuse pub trait ArrowNativeType: std::fmt::Debug + Send