Skip to content

Commit 1fc11d5

Browse files
Merge pull request #50 from bearcove/no-string-comp
Don't compare string, use const type_id
2 parents ef4d5cb + ff217b5 commit 1fc11d5

File tree

15 files changed

+140
-88
lines changed

15 files changed

+140
-88
lines changed

Cargo.lock

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

shapely-core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ keywords = ["reflection", "introspection", "serialization", "deserialization"]
1313
categories = ["development-tools", "encoding"]
1414

1515
[dependencies]
16+
typeid = "1.0.3"

shapely-core/src/impls/bytes_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::hash::Hash as _;
22

3-
use crate::{Bytes, Def, HasherProxy, Shape, Shapely, ValueVTable};
3+
use crate::{Bytes, Def, HasherProxy, ScalarDef, Shape, Shapely, ValueVTable};
44

55
impl Shapely for Bytes {
66
const SHAPE: &'static Shape = &Shape {
77
layout: std::alloc::Layout::new::<Self>(),
8-
def: Def::Scalar,
8+
def: Def::Scalar(ScalarDef::of::<Self>()),
99
vtable: &ValueVTable {
1010
type_name: |f, _opts| write!(f, "Bytes"),
1111
display: None,

shapely-core/src/impls/scalar_impls.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ impl Shapely for () {
66
const SHAPE: &'static Shape = &const {
77
Shape {
88
layout: Layout::new::<Self>(),
9-
def: Def::Scalar,
9+
def: Def::Scalar(ScalarDef::of::<Self>()),
1010
vtable: &ValueVTable {
1111
type_name: |f, _opts| write!(f, "()"),
1212
display: Some(|_value, mut f| write!(f, "()")),
@@ -32,7 +32,7 @@ impl Shapely for () {
3232
impl Shapely for String {
3333
const SHAPE: &'static Shape = &Shape {
3434
layout: Layout::new::<Self>(),
35-
def: Def::Scalar,
35+
def: Def::Scalar(ScalarDef::of::<Self>()),
3636
vtable: &ValueVTable {
3737
type_name: |f, _opts| write!(f, "String"),
3838
display: Some(|value, mut f| {
@@ -64,7 +64,7 @@ impl Shapely for String {
6464
impl Shapely for bool {
6565
const SHAPE: &'static Shape = &Shape {
6666
layout: Layout::new::<Self>(),
67-
def: Def::Scalar,
67+
def: Def::Scalar(ScalarDef::of::<Self>()),
6868
vtable: &ValueVTable {
6969
type_name: |f, _opts| write!(f, "bool"),
7070
display: Some(|value, mut f| {
@@ -100,7 +100,7 @@ macro_rules! impl_shapely_for_integer {
100100
impl Shapely for $type {
101101
const SHAPE: &'static Shape = &Shape {
102102
layout: Layout::new::<Self>(),
103-
def: Def::Scalar,
103+
def: Def::Scalar(ScalarDef::of::<Self>()),
104104
vtable: &ValueVTable {
105105
type_name: |f, _opts| write!(f, stringify!($type)),
106106
display: Some(|value, mut f| {
@@ -153,7 +153,7 @@ macro_rules! impl_shapely_for_float {
153153
impl Shapely for $type {
154154
const SHAPE: &'static Shape = &Shape {
155155
layout: Layout::new::<Self>(),
156-
def: Def::Scalar,
156+
def: Def::Scalar(ScalarDef::of::<Self>()),
157157
vtable: &ValueVTable {
158158
type_name: |f, _opts| write!(f, stringify!($type)),
159159
display: Some(|value, mut f| {

shapely-core/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ pub trait Shapely: Sized {
3434
/// Returns the shape function of this type
3535
const SHAPE: &'static Shape;
3636

37-
/// Heap-allocate a value of this shape
38-
fn allocate() -> OpaqueUninit<'static> {
39-
OpaqueUninit::new(unsafe { std::alloc::alloc(Self::SHAPE.layout) })
37+
/// Returns true if the type of `self` is equal to the type of `other`
38+
fn type_eq<Other: Shapely>() -> bool {
39+
Self::SHAPE == Other::SHAPE
4040
}
4141
}
4242

shapely-core/src/peek/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'mem> Peek<'mem> {
4444
super::Def::Tuple { .. } => todo!(),
4545
super::Def::Map { .. } => todo!(),
4646
super::Def::List { .. } => todo!(),
47-
super::Def::Scalar => Peek::Scalar(PeekValue { data, shape }),
47+
super::Def::Scalar { .. } => Peek::Scalar(PeekValue { data, shape }),
4848
super::Def::Enum { .. } => todo!(),
4949
}
5050
}

shapely-core/src/poke/enum_.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{EnumDef, FieldError, OpaqueUninit, Shape, Shapely, trace};
1+
use crate::{EnumDef, FieldError, OpaqueUninit, Shape, ShapeDebug, Shapely, trace};
22
use std::ptr::NonNull;
33

44
use super::{ISet, Poke};
@@ -232,7 +232,9 @@ impl<'mem> PokeEnum<'mem> {
232232
if !self.iset.has(field_index) {
233233
panic!(
234234
"Field '{}' of variant '{}' was not initialized. Complete schema:\n{:?}",
235-
field.name, variant.name, self.shape
235+
field.name,
236+
variant.name,
237+
ShapeDebug(self.shape)
236238
);
237239
}
238240
}
@@ -241,13 +243,11 @@ impl<'mem> PokeEnum<'mem> {
241243
}
242244

243245
fn assert_matching_shape<T: Shapely>(&self) {
244-
if self.shape != T::SHAPE {
245-
let current_shape = self.shape;
246-
let target_shape = T::SHAPE;
247-
246+
if !self.shape.is_type::<T>() {
248247
panic!(
249248
"This is a partial \x1b[1;34m{}\x1b[0m, you can't build a \x1b[1;32m{}\x1b[0m out of it",
250-
current_shape, target_shape,
249+
self.shape,
250+
T::SHAPE,
251251
);
252252
}
253253
}

shapely-core/src/poke/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl Drop for Guard {
5454
impl<'mem> Poke<'mem> {
5555
/// Allocates a new poke of a type that implements shapely
5656
pub fn alloc<S: Shapely>() -> (Self, Guard) {
57-
let data = S::allocate();
57+
let data = S::SHAPE.allocate();
5858
let layout = Layout::new::<S>();
5959
let guard = Guard {
6060
ptr: data.as_mut_ptr(),
@@ -92,7 +92,7 @@ impl<'mem> Poke<'mem> {
9292
let plu = unsafe { PokeListUninit::new(data, shape, list_def) };
9393
Poke::List(plu)
9494
}
95-
Def::Scalar => Poke::Scalar(unsafe { PokeValue::new(data, shape) }),
95+
Def::Scalar { .. } => Poke::Scalar(unsafe { PokeValue::new(data, shape) }),
9696
Def::Enum(enum_def) => {
9797
Poke::Enum(unsafe { PokeEnumNoVariant::new(data, shape, enum_def) })
9898
}

shapely-core/src/poke/struct_.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{FieldError, OpaqueUninit, Shape, StructDef};
1+
use crate::{FieldError, OpaqueUninit, Shape, ShapeDebug, StructDef};
22
use std::ptr::NonNull;
33

44
use super::{Guard, ISet};
@@ -33,7 +33,8 @@ impl<'mem> PokeStruct<'mem> {
3333
if !self.iset.has(i) {
3434
panic!(
3535
"Field '{}' was not initialized. Complete schema:\n{:?}",
36-
field.name, self.shape
36+
field.name,
37+
ShapeDebug(self.shape)
3738
);
3839
}
3940
}
@@ -65,9 +66,9 @@ impl<'mem> PokeStruct<'mem> {
6566
/// - The generic type parameter T does not match the shape that this PokeStruct is building.
6667
pub fn build<T: crate::Shapely>(self, guard: Option<Guard>) -> T {
6768
self.assert_all_fields_initialized();
68-
assert_eq!(self.shape, T::SHAPE, "Shape mismatch");
69+
self.shape.assert_type::<T>();
6970
if let Some(guard) = &guard {
70-
assert_eq!(guard.shape, self.shape, "Shape mismatch");
71+
guard.shape.assert_type::<T>();
7172
}
7273

7374
let result = unsafe {
@@ -88,7 +89,7 @@ impl<'mem> PokeStruct<'mem> {
8889
/// - The generic type parameter T does not match the shape that this PokeStruct is building.
8990
pub fn build_boxed<T: crate::Shapely>(self) -> Box<T> {
9091
self.assert_all_fields_initialized();
91-
assert_eq!(self.shape, T::SHAPE, "Shape mismatch");
92+
self.shape.assert_type::<T>();
9293

9394
let boxed = unsafe { Box::from_raw(self.data.as_mut_ptr() as *mut T) };
9495
std::mem::forget(self);
@@ -106,7 +107,7 @@ impl<'mem> PokeStruct<'mem> {
106107
pub unsafe fn move_into(self, target: NonNull<u8>, guard: Option<Guard>) {
107108
self.assert_all_fields_initialized();
108109
if let Some(guard) = &guard {
109-
assert_eq!(guard.shape, self.shape, "Shape mismatch");
110+
guard.shape.assert_shape(self.shape);
110111
}
111112

112113
unsafe {

shapely-core/src/poke/value.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{Opaque, OpaqueConst, OpaqueUninit, Peek, Shape, ValueVTable};
1+
use crate::{Opaque, OpaqueConst, OpaqueUninit, Peek, Shape, ShapeDebug, ValueVTable};
22

33
/// Lets you write to a value (implements write-only [`ValueVTable`] proxies)
44
pub struct PokeValue<'mem> {
@@ -10,7 +10,7 @@ pub struct PokeValue<'mem> {
1010
impl std::fmt::Debug for PokeValue<'_> {
1111
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1212
f.debug_struct("PokeValue")
13-
.field("shape", &self.shape)
13+
.field("shape", &ShapeDebug(self.shape))
1414
.finish_non_exhaustive()
1515
}
1616
}

0 commit comments

Comments
 (0)