Skip to content

Commit 286c9ea

Browse files
committed
Readd serde separation
This reverts commit 30a545a.
1 parent 8bcbed2 commit 286c9ea

File tree

6 files changed

+79
-25
lines changed

6 files changed

+79
-25
lines changed

example/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2021"
55

66
[features]
77
axum = ["dep:axum", "dep:tokio", "dep:thiserror"]
8+
serde = ["dep:serde", "cel-interpreter/serde"]
89
json = ["dep:serde_json", "cel-interpreter/json"]
910
chrono = ["dep:chrono", "cel-interpreter/chrono"]
1011

@@ -13,7 +14,7 @@ cel-interpreter = { path = "../interpreter", default-features = false }
1314

1415
chrono = { version = "0.4", optional = true }
1516

16-
serde = { version = "1.0", features = ["derive"] }
17+
serde = { version = "1.0", features = ["derive"], optional = true }
1718
serde_json = { version = "1.0", optional = true }
1819

1920
axum = { version = "0.7.5", default-features = false, features = [
@@ -48,6 +49,7 @@ path = "src/threads.rs"
4849
[[bin]]
4950
name = "example-serde"
5051
path = "src/serde.rs"
52+
required-features = ["serde"]
5153

5254
[[bin]]
5355
name = "example-axum"

interpreter/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ nom = "7.1.3"
1515

1616
chrono = { version = "0.4", default-features = false, features = ["alloc"], optional = true }
1717
regex = { version = "1.10.5", optional = true }
18-
serde = "1.0"
18+
serde = { version = "1.0", optional = true }
1919
serde_json = { version = "1.0", optional = true }
2020
base64 = { version = "0.22.1", optional = true }
2121

@@ -31,7 +31,8 @@ name = "runtime"
3131
harness = false
3232

3333
[features]
34-
default = ["regex", "chrono"]
35-
json = ["dep:serde_json", "dep:base64"]
34+
default = ["regex", "chrono", "serde"]
35+
json = ["serde", "dep:serde_json", "dep:base64"]
36+
serde = ["dep:serde"]
3637
regex = ["dep:regex"]
3738
chrono = ["dep:chrono"]

interpreter/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ mod resolvers;
2121
#[cfg(feature = "chrono")]
2222
mod duration;
2323

24+
#[cfg(feature = "serde")]
2425
mod ser;
26+
#[cfg(feature = "serde")]
2527
pub use ser::to_value;
2628

2729
#[cfg(feature = "json")]
@@ -45,6 +47,14 @@ pub enum ExecutionError {
4547
/// but the type of the value was not supported as a key.
4648
#[error("Unable to use value '{0:?}' as a key")]
4749
UnsupportedKeyType(Value),
50+
#[error(
51+
"Casting number '{value:.2}' ({source_ty}) to {target_ty} type would cause an overflow"
52+
)]
53+
CastOverflow {
54+
value: f64,
55+
source_ty: &'static str,
56+
target_ty: &'static str,
57+
},
4858
#[error("Unexpected type: got '{got}', want '{want}'")]
4959
UnexpectedType { got: String, want: String },
5060
/// Indicates that the script attempted to reference a key on a type that

interpreter/src/macros.rs

+34-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
#[macro_export]
22
macro_rules! impl_conversions {
33
// Capture pairs separated by commas, where each pair is separated by =>
4-
($($target_type:ty => $value_variant:path),* $(,)?) => {
4+
($($target_type:ty $(as $cast:ty)? => $value_variant:path),* $(,)?) => {
55
$(
66
impl FromValue for $target_type {
77
fn from_value(expr: &Value) -> Result<Self, ExecutionError> {
88
if let $value_variant(v) = expr {
9-
Ok(v.clone())
9+
$(if <$target_type>::MAX as $cast < *v {
10+
return Err(ExecutionError::CastOverflow {
11+
value: *v as f64,
12+
source_ty: std::any::type_name::<$cast>(),
13+
target_ty: std::any::type_name::<$target_type>(),
14+
})
15+
} else if <$target_type>::MIN as $cast > *v {
16+
return Err(ExecutionError::CastOverflow {
17+
value: *v as f64,
18+
source_ty: std::any::type_name::<$cast>(),
19+
target_ty: std::any::type_name::<$target_type>(),
20+
})
21+
})?
22+
Ok(v.clone() $(as $cast as $target_type)?)
1023
} else {
1124
Err(ExecutionError::UnexpectedType {
1225
got: format!("{:?}", expr),
@@ -20,7 +33,22 @@ macro_rules! impl_conversions {
2033
fn from_value(expr: &Value) -> Result<Self, ExecutionError> {
2134
match expr {
2235
Value::Null => Ok(None),
23-
$value_variant(v) => Ok(Some(v.clone())),
36+
$value_variant(v) => {
37+
$(if <$target_type>::MAX as $cast < *v {
38+
return Err(ExecutionError::CastOverflow {
39+
value: *v as f64,
40+
source_ty: std::any::type_name::<$cast>(),
41+
target_ty: std::any::type_name::<$target_type>(),
42+
})
43+
} else if <$target_type>::MIN as $cast > *v {
44+
return Err(ExecutionError::CastOverflow {
45+
value: *v as f64,
46+
source_ty: std::any::type_name::<$cast>(),
47+
target_ty: std::any::type_name::<$target_type>(),
48+
})
49+
})?
50+
Ok(Some(v.clone() $(as $cast as $target_type)?))
51+
},
2452
_ => Err(ExecutionError::UnexpectedType {
2553
got: format!("{:?}", expr),
2654
want: stringify!($target_type).to_string(),
@@ -31,19 +59,19 @@ macro_rules! impl_conversions {
3159

3260
impl From<$target_type> for Value {
3361
fn from(value: $target_type) -> Self {
34-
$value_variant(value)
62+
$value_variant(value $(as $cast)?)
3563
}
3664
}
3765

3866
impl $crate::magic::IntoResolveResult for $target_type {
3967
fn into_resolve_result(self) -> ResolveResult {
40-
Ok($value_variant(self))
68+
Ok($value_variant(self $(as $cast)?))
4169
}
4270
}
4371

4472
impl $crate::magic::IntoResolveResult for Result<$target_type, ExecutionError> {
4573
fn into_resolve_result(self) -> ResolveResult {
46-
self.map($value_variant)
74+
self.map(|it| $value_variant(it $(as $cast)?))
4775
}
4876
}
4977

interpreter/src/magic.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,15 @@ use std::marker::PhantomData;
77
use std::sync::Arc;
88

99
impl_conversions!(
10+
i8 as i64 => Value::Int,
11+
i16 as i64 => Value::Int,
12+
i32 as i64 => Value::Int,
1013
i64 => Value::Int,
14+
u8 as u64 => Value::UInt,
15+
u16 as u64 => Value::UInt,
16+
u32 as u64 => Value::UInt,
1117
u64 => Value::UInt,
18+
f32 as f64 => Value::Float,
1219
f64 => Value::Float,
1320
Arc<String> => Value::String,
1421
Arc<Vec<u8>> => Value::Bytes,
@@ -22,12 +29,6 @@ impl_conversions!(
2229
chrono::DateTime<chrono::FixedOffset> => Value::Timestamp,
2330
);
2431

25-
impl From<i32> for Value {
26-
fn from(value: i32) -> Self {
27-
Value::Int(value as i64)
28-
}
29-
}
30-
3132
/// Describes any type that can be converted from a [`Value`] into itself.
3233
/// This is commonly used to convert from [`Value`] into primitive types,
3334
/// e.g. from `Value::Bool(true) -> true`. This trait is auto-implemented

interpreter/src/objects.rs

+21-9
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ impl From<u64> for Key {
8585
}
8686
}
8787

88+
#[cfg(feature = "serde")]
8889
impl serde::Serialize for Key {
8990
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
9091
where
@@ -144,18 +145,28 @@ pub trait TryIntoValue {
144145
fn try_into_value(self) -> Result<Value, Self::Error>;
145146
}
146147

148+
#[cfg(feature = "serde")]
147149
impl<T: serde::Serialize> TryIntoValue for T {
148150
type Error = crate::ser::SerializationError;
149151
fn try_into_value(self) -> Result<Value, Self::Error> {
150152
crate::ser::to_value(self)
151153
}
152154
}
155+
#[cfg(feature = "serde")]
153156
impl TryIntoValue for Value {
154157
type Error = Infallible;
155158
fn try_into_value(self) -> Result<Value, Self::Error> {
156159
Ok(self)
157160
}
158161
}
162+
#[cfg(not(feature = "serde"))]
163+
impl<T: Into<Value>> TryIntoValue for T {
164+
type Error = Infallible;
165+
166+
fn try_into_value(self) -> Result<Value, Self::Error> {
167+
Ok(self.into())
168+
}
169+
}
159170

160171
#[derive(Debug, Clone)]
161172
pub enum Value {
@@ -351,16 +362,17 @@ impl From<&Key> for Key {
351362
}
352363

353364
// Convert Vec<T> to Value
354-
impl<T: Into<Value>> From<Vec<T>> for Value {
365+
impl<T: Into<Value> + 'static> From<Vec<T>> for Value {
355366
fn from(v: Vec<T>) -> Self {
356-
Value::List(v.into_iter().map(|v| v.into()).collect::<Vec<_>>().into())
357-
}
358-
}
359-
360-
// Convert Vec<u8> to Value
361-
impl From<Vec<u8>> for Value {
362-
fn from(v: Vec<u8>) -> Self {
363-
Value::Bytes(v.into())
367+
if std::any::TypeId::of::<Vec<T>>() == std::any::TypeId::of::<Vec<u8>>() {
368+
Value::Bytes(Arc::new(unsafe {
369+
// SAFETY: Checked Vec<T> is Vec<u8>, so they're the same type,
370+
// just the compiler can't tell without specialization.
371+
std::mem::transmute::<Vec<T>, Vec<u8>>(v)
372+
}))
373+
} else {
374+
Value::List(v.into_iter().map(|v| v.into()).collect::<Vec<_>>().into())
375+
}
364376
}
365377
}
366378

0 commit comments

Comments
 (0)