|
18 | 18 | use std::fmt::Debug; |
19 | 19 |
|
20 | 20 | use allocative::Allocative; |
| 21 | +use starlark_derive::type_matcher; |
21 | 22 |
|
| 23 | +use crate as starlark; |
22 | 24 | use crate::typing::custom::TyCustom; |
23 | 25 | use crate::values::Value; |
24 | 26 | use crate::values::typing::type_compiled::alloc::TypeMatcherAlloc; |
25 | 27 | use crate::values::typing::type_compiled::type_matcher_factory::TypeMatcherFactory; |
26 | 28 |
|
| 29 | +/// Marker trait for type matchers which are registered. |
| 30 | +/// |
| 31 | +/// This trait is automatically implemented by the `#[type_matcher]` proc macro. |
| 32 | +/// |
| 33 | +/// # Safety |
| 34 | +/// |
| 35 | +/// This trait must only be implemented by the `#[type_matcher]` proc macro, |
| 36 | +/// which ensures the type is properly registered in the vtable registry. |
| 37 | +/// Manual implementations may break deserialization. |
| 38 | +#[cfg_attr(not(feature = "pagable"), allow(dead_code))] |
| 39 | +pub unsafe trait TypeMatcherRegistered {} |
| 40 | + |
| 41 | +/// Base trait for type matchers |
| 42 | +/// |
| 43 | +/// When `pagable` is enabled, matchers must also implement `TypeMatcherRegistered` |
| 44 | +/// to ensure they are registered. |
| 45 | +#[cfg(feature = "pagable")] |
| 46 | +pub trait TypeMatcherBase: |
| 47 | + TypeMatcherRegistered + Allocative + Debug + Clone + Sized + Send + Sync + 'static |
| 48 | +{ |
| 49 | +} |
| 50 | + |
| 51 | +#[cfg(feature = "pagable")] |
| 52 | +impl<T> TypeMatcherBase for T where |
| 53 | + T: TypeMatcherRegistered + Allocative + Debug + Clone + Sized + Send + Sync + 'static |
| 54 | +{ |
| 55 | +} |
| 56 | + |
| 57 | +/// Base trait for type matchers |
| 58 | +#[cfg(not(feature = "pagable"))] |
| 59 | +pub trait TypeMatcherBase: Allocative + Debug + Clone + Sized + Send + Sync + 'static {} |
| 60 | + |
| 61 | +#[cfg(not(feature = "pagable"))] |
| 62 | +impl<T> TypeMatcherBase for T where T: Allocative + Debug + Clone + Sized + Send + Sync + 'static {} |
| 63 | + |
27 | 64 | /// Runtime type matcher. E.g. when `isinstance(1, int)` is called, |
28 | 65 | /// implementation of `TypeMatcher` for `int` is used. |
29 | | -pub trait TypeMatcher: Allocative + Debug + Clone + Sized + Send + Sync + 'static { |
| 66 | +pub trait TypeMatcher: TypeMatcherBase { |
30 | 67 | /// Check if the value matches the type. |
31 | 68 | fn matches(&self, value: Value) -> bool; |
32 | 69 | /// True if this matcher matches any value. |
@@ -71,6 +108,7 @@ impl Clone for TypeMatcherBox { |
71 | 108 | } |
72 | 109 | } |
73 | 110 |
|
| 111 | +#[type_matcher] |
74 | 112 | impl TypeMatcher for TypeMatcherBox { |
75 | 113 | fn matches(&self, value: Value) -> bool { |
76 | 114 | self.0.matches_dyn(value) |
|
0 commit comments